atma-logger
Version:
Logger | Formatter + Color
1,888 lines (1,491 loc) • 39.4 kB
JavaScript
(function(root, factory){
"use strict";
var __global = typeof window === 'undefined'
? global
: window
;
var Logger = factory(__global);
// if Global
__global.logger = Logger;
// endif
}(this, function(global){
"use strict";
// source ../src/vars.js
var _format;
// if NodeJS
_format = require('atma-formatter');
// endif
var level_TRACE = 100,
level_DEBUG = 75,
level_LOG = 50,
level_WARN = 25,
level_ERROR = 0,
level_EXCEPTION = -25
;
var _cfg = {
formatMessage: true,
logCaller: true,
logDate: false,
logMeta: null,
color: 'ascii',
handleExceptions: false
},
_level = level_LOG,
_levels = {}
;
// end:source ../src/vars.js
// source ../src/utils/obj.js
var obj_typeof,
obj_inherit,
obj_extend,
obj_dimissCircular,
obj_stringify
;
(function(){
obj_typeof = function(x) {
return Object
.prototype
.toString
.call(x)
.replace('[object ', '')
.replace(']', '');
};
obj_inherit = function(target /* source, ..*/ ) {
if (typeof target === 'function')
target = target.prototype;
var i = 1,
imax = arguments.length,
source, key;
for (; i < imax; i++) {
source = typeof arguments[i] === 'function'
? arguments[i].prototype
: arguments[i];
for (key in source) {
target[key] = source[key];
}
}
return target;
};
obj_extend = function(target, source) {
if (source == null)
return target;
for (var key in source)
target[key] = source[key];
return target;
};
obj_dimissCircular = (function() {
var cache;
function clone(mix) {
if (mix == null)
return mix;
var type = obj_typeof(mix),
cloned;
switch (type) {
case 'String':
case 'Number':
case 'Date':
case 'RegExp':
case 'Function':
case 'Error':
case 'Boolean':
return mix;
case 'Array':
case 'Arguments':
cloned = [];
for (var i = 0, imax = mix.length; i < imax; i++) {
cloned[i] = clone(mix[i]);
}
return cloned;
case 'Object':
case 'global':
if (cache.indexOf(mix) !== -1)
return '<circular>';
cache.push(mix);
cloned = {};
for (var key in mix) {
cloned[key] = clone(mix[key]);
}
return cloned;
default:
console.warn('obj_dimissCircular: Unknown type', type);
return mix;
}
}
return function(mix) {
if (typeof mix === 'object' && mix != null) {
cache = [];
mix = clone(mix);
cache = null;
}
return mix;
};
}());
obj_stringify = (function(){
function doIndent(count) {
var str = '',
i = 0;
for (; i < count; i++){
str += ' ';
}
return str;
}
return function stringify(obj, visitor, indent){
if (indent == null)
indent = 0;
var tuple = ['', 0];
if (typeof obj === 'undefined'){
tuple[1] = '<undefined>';
visitor(tuple, 'undefined');
return tuple[1];
}
if (obj == null) {
tuple[1] = '<null>';
visitor(tuple, 'null');
return tuple[1];
}
var type = obj_typeof(obj);
switch (type) {
case 'Array':
case 'Arguments':
var str = '[',
array = obj;
for (var i = 0, x, imax = array.length; i < imax; i++){
x = array[i];
if (str === '[')
str += '\n';
str += doIndent(indent + 1)
+ stringify(x, visitor, indent + 1)
+ (i < imax - 1 ? ',' : '')
+ '\n'
;
}
str += doIndent(indent) + ']';
return str;
case 'RegExp':
tuple[1] = obj.toString();
visitor(tuple, 'regexp');
return tuple[1];
case 'Date':
tuple[1] = obj.toISOString();
visitor(tuple, 'date');
return tuple[1];
case 'String':
case 'Number':
case 'Boolean':
tuple[1] = obj;
visitor(tuple, type.toLowerCase());
return tuple[1];
case 'Function':
tuple[1] = '<function>';
visitor(tuple, type.toLowerCase());
return tuple[1];
case 'Error':
return obj.toString().red;
case 'Object':
case 'global':
var str = '{',
keys = Object.keys(obj),
key;
i = 0;
imax = keys.length;
for (; i < imax; i++){
key = keys[i];
if (str === '{')
str += '\n';
tuple[0] = key;
tuple[1] = obj[key];
visitor(tuple);
str += doIndent(indent + 1)
+ tuple[0]
+ ': '
+ stringify(obj[key], visitor, indent + 1)
+ (i < imax - 1 ? ',' : '')
+ '\n'
;
}
str += doIndent(indent) + '}';
return str;
}
};
}());
}());
// end:source ../src/utils/obj.js
// source ../src/utils/function.js
function fn_doNothing() {
return this;
}
// end:source ../src/utils/function.js
// source ../src/utils/stack.js
var stack_formatCaller;
(function() {
var stackEntry = {
path: null,
file: null,
line: null
};
var currentFile;
function parseStackEntry(line) {
if (line[line.length - 1] === ')')
line = line.substr(
line.indexOf('(') + 1,
line.lastIndexOf(')') - 1);
var match = /^(.+):(\d+):(\d)/.exec(line);
if (match == null)
return null;
var path = stackEntry.path = match[1];
stackEntry.file = path.substring(path.search(/[\/\\][^\/\\]+$/) + 1);
stackEntry.line = match[2];
if (currentFile == null)
currentFile = stackEntry.file;
return stackEntry;
}
stack_formatCaller = function(format, entryIndex) {
var stack = new Error()
.stack
.split('\n')
.splice(1);
var imax = stack.length,
i = -1,
entry;
while (++i < imax) {
entry = parseStackEntry(stack[i]);
if (entry == null || currentFile == null)
continue;
if (entry.file !== currentFile)
break;
}
if (entry == null || i === imax)
return '';
return format
.replace('P', entry.path)
.replace('F', entry.file)
.replace('L', entry.line);
};
}());
// end:source ../src/utils/stack.js
// source ../src/utils/date.js
var date_formatForMessage
;
(function(){
date_formatForMessage = function(format){
if (typeof format !== 'string')
format = 'dd-MM hh:mm:ss';
return _format(new Date, format);
};
}());
// end:source ../src/utils/date.js
// source ../src/utils/message.js
var message_format,
message_prepair;
(function() {
message_prepair = function(args, instance) {
if (_cfg.formatMessage === false) {
if (_cfg.logMeta)
args.unshift(_cfg.logMeta(args));
return args;
}
var message = message_format(args);
if (instance._name != null) {
message = instance._name.color + ' ' + message;
}
if (_cfg.logCaller !== false)
message += stack_formatCaller(' (F:L)', 5);
if (typeof _cfg.logMeta === 'function')
message = _cfg.logMeta(args) + ' ' + message;
if (_cfg.logDate !== false) {
message = date_formatForMessage(_cfg.logDate)
+ ' '
+ message;
}
return message;
};
message_format = function(args) {
var str = '',
rgx_format = /%s|%d/,
item;
var format = args.length > 1
&& typeof args[0] === 'string'
&& rgx_format.test(args[0])
;
for (var i = 0, x, imax = args.length; i < imax; i++) {
x = args[i];
if (x instanceof String)
x = String(x);
item = typeof x === 'string'
? x
: Color.formatJSON(x)
;
if (i > 0 && format && rgx_format.test(str)) {
str = str.replace(rgx_format, item);
continue;
}
if (str !== '')
str += ' ';
str += item;
}
return str;
};
}());
// end:source ../src/utils/message.js
// source ../src/utils/process.js
var process_handleExceptions;
(function(){
process_handleExceptions = function(state){
// if NodeJS
process
.removeListener('uncaughtException', onException);
if (state !== false)
process.on('uncaughtException', onException);
// endif
};
// private
function onException(error) {
var Transport = Logger
.error(error)
.getTransport()
;
if (Transport != null) {
if (Transport.flush) {
Transport.flush(exit);
return;
}
if (Transport.flushAsync) {
Transport.flushAsync(exit);
return;
}
}
exit();
}
function exit() {
// if NodeJS
process.exit(1);
// endif
}
}());
// end:source ../src/utils/process.js
// source ../src/utils/cfg.js
var cfg_set;
(function(){
cfg_set = function(key, value) {
switch (key) {
case 'level':
_level = value;
break;
case 'levels':
for (var scope in value){
level_scope_Set(scope, value[scope]);
}
break;
case 'transport':
Transport.define(value);
break;
case 'handleExceptions':
process_handleExceptions(value);
break;
case 'color':
Color.define(value);
/*fall through*/
case 'logCaller':
case 'logDate':
case 'formatMessage':
case 'meta':
_cfg[key] = value;
break;
default:
console.error('Logger: unknown configuration', key);
break;
}
};
}());
// end:source ../src/utils/cfg.js
// source ../src/utils/level.js
var level_scope_Set,
level_scope_Get;
(function(){
level_scope_Set = function(scope, level){
insert(scope, level);
};
level_scope_Get = function(scope){
var level = _levels[scope];
if (level === _default)
return null;
if (level == null)
level = _levels[scope] = getParent(scope);
return level.level;
};
// private
var _levels = {},
_default = {
level: null
};
function getParent(scope){
var i = scope.lastIndexOf('.');
if (i === -1)
return _default;
scope = scope.substring(0, i);
if (_levels.hasOwnProperty(scope) && _levels[scope].strict !== true) {
return _levels[scope];
}
return getParent(scope);
}
function insert(scope, level) {
var any = /\.\*$/.test(scope);
if (any)
scope = scope.slice(0, -2);
_levels[scope] = {
level: level,
strict: any === false
};
if (any)
updateChildren(scope, level, any);
}
function updateChildren(scope, level) {
var length = scope.length,
key;
for(key in _levels){
if (key.length <= length + 1)
continue;
if (key.indexOf(scope + '.') !== 0 )
continue;
_levels[key] = {
level: level
};
}
}
}());
// end:source ../src/utils/level.js
// source ../src/color/color.js
var Color;
(function() {
Color = {
init: {
ascii: function() {
_colorize = initialize(ColorAscii);
},
html: function(){
_colorize = initialize(ColorHtml);
},
none: function(){
_colorize = initialize(ColorNone);
}
},
colorize: function(str){
return _colorize(str);
},
formatJSON: function(obj){
var json = obj;
if (json !== void 0 && typeof json === 'object') {
json = obj_dimissCircular(obj);
}
return obj_stringify(json, function(tuple, type){
if (type && JSONTheme[type]) {
tuple[1] = String(tuple[1])[JSONTheme[type]];
}
if (tuple[0]) {
tuple[0] = tuple[0].bold;
}
});
},
define: function(type){
if (Color.init[type])
return Color.init[type]();
console.error('Invalid Color Type ', type);
}
};
var _colorize;
// source data/none.js
var ColorNone = {
END : '',
value: {
red: '',
green: '',
yellow: '',
blue: '',
magenta: '',
cyan: '',
bold: '',
italic: '',
underline: '',
inverse: ''
},
start: function(key){
return '';
}
};
// end:source data/none.js
// source data/html.js
var ColorHtml;
(function(){
ColorHtml = {
END : '</span>',
value: {
red: 'color:red',
green: 'color:green',
yellow: 'color:yellow',
blue: 'color:blue',
magenta: 'color:magenta',
cyan: 'color:cyan',
bg_black: 'background-color:black',
bg_red: 'background-color:red',
bg_green: 'background-color:green',
bg_yellow: 'background-color:yellow',
bg_blue: 'background-color:blue',
bg_magenta: 'background-color:magenta',
bg_cyan: 'background-color:cyan',
bg_white: 'background-color:white',
bold: 'font-weight:bold',
italic: 'font-style:italic',
underline: 'text-decoration:underline',
inverse: 'color:black;background:white'
},
start: function(key){
var str = '<span style="'
+ this.value[key]
+ '">';
return str;
},
decorator: function(str){
return str_htmlEncode(str);
}
};
var str_htmlEncode;
(function() {
str_htmlEncode = function(html) {
return html.replace(/[&"'<>\/]/g, replaceEntity);
};
var map = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/'
};
function replaceEntity(chr) {
return map[chr];
}
}());
}());
// end:source data/html.js
// source data/ascii.js
var ColorAscii = {
type: 'ascii',
START : '\u001b[',
END : '\u001b[0m',
value: {
red: '31m',
green: '32m',
yellow: '33m',
blue: '34m',
magenta: '35m',
cyan: '36m',
white: '37m',
black: '30m',
bg_black: '40m',
bg_red: '41m',
bg_green: '42m',
bg_yellow: '43m',
bg_blue: '44m',
bg_magenta: '45m',
bg_cyan: '46m',
bg_white: '47m',
bold: '1m',
italic: '3m',
underline: '4m',
inverse: '7m'
},
start: function(key){
return this.START + this.value[key];
}
};
// end:source data/ascii.js
function initialize(ColorData) {
Object
.keys(ColorData.value)
.forEach(function(key) {
try {
Object.defineProperty(String.prototype, key, {
get: function() {
var txt = this,
decorator = ColorData.decorator;
if (decorator != null) {
if (txt.__wrapped !== true)
txt = decorator(txt);
}
var out = ColorData.start(key)
+ txt
+ ColorData.END;
if (decorator == null)
return out;
out = new String(out);
out.__wrapped = true;
return out;
},
enumerable: false,
configurable: true
});
} catch(e) {
// already exists ( with configurable: false )
}
});
Object.defineProperty(String.prototype, 'color', {
get: function() {
return painter(this, ColorData);
},
enumerable: false,
configurable: true
});
return function(str){
return painter(str, ColorData);
};
}
_colorize = initialize(ColorAscii);
var JSONTheme = {
'string': 'yellow',
'number': 'cyan',
'boolean': 'cyan',
'regexp': 'magenta',
'date': 'magenta',
'function': 'magenta',
'null': 'blue',
'undefined': 'blue'
};
var painter;
(function(){
painter = function(str, ColorData) {
prepairColor(ColorData);
ColorData.rgx_search.lastIndex = 0;
var match,
key,
end,
doRenew = ColorData.type === 'ascii',
stack = doRenew && [] || null,
txt
;
var out = '', last = 0;
while (1) {
match = ColorData.rgx_search.exec(str);
if (match == null)
break;
key = match[1];
if (ColorData.value[key] == null)
continue;
var index = match.index,
bound = index + match[0].length,
head, txt;
if (last !== index)
out += createRange(str, last, index, ColorData);
end = index_End(str, bound);
last = end + 1;
if (end === -1) {
out += createRange(str, index, end, ColorData);
continue;
}
head = ColorData.start(key);
txt = str.substring(bound, end);
txt = painter(txt, ColorData);
out += head
+ txt
+ ColorData.END
+ (doRenew ? stack_renew(stack, end, ColorData) : '')
;
if (doRenew)
stack.push({end: end, key: key});
ColorData.rgx_search.lastIndex = end + 1;
}
if (last < str.length) {
out += createRange(str, last, str.length, ColorData);
}
return out;
};
function createRange(str, start, end, ColorData) {
var txt = str.substring(start, end);
if (ColorData.decorator)
return ColorData.decorator(txt);
return txt;
}
function index_End(str, start) {
var count = 1,
imax = str.length,
i = start,
c;
for (; i < imax; i++){
c = str.charCodeAt(i);
if (c === 60 /* < */)
count++;
if (c === 62 /* > */)
count--;
if (count === 0)
return i;
}
return -1;
}
function stack_renew(stack, index, ColorData) {
var str = '',
imax = stack.length,
i = -1, x;
while ( ++i < imax ){
x = stack[i];
if (x.end < index)
continue;
str += ColorData.start(x.key);
}
return str;
}
function prepairColor(ColorData){
if (ColorData.rgx_search == null) {
var str = '(';
for (var key in ColorData.value) {
str += str === '(' ? key : '|' + key;
}
str += ')<';
ColorData.rgx_search = new RegExp(str, 'g');
}
return ColorData;
}
}());
}());
// end:source ../src/color/color.js
// source ../src/transport/Transport.js
var Transport = (function(){
var _transports = {},
_transport;
// source ./helper/Buffered.js
var Buffered;
(function(){
Buffered = {
flushAsync: function(writer, maxSize, write, cb){
if (writer.busy) {
if (cb != null)
writer.listeners.push(cb);
return;
}
var data = joinBuffer(writer);
if (data === '') {
if (cb)
cb();
return;
}
writer.busy = true;
write(writer, data, function(error){
writer.busy = false;
callAll(cb, writer.listeners);
if (writer.buffer.length > maxSize)
writer.flushAsync();
});
},
flush: function(writer, write, cb){
if (writer.busy) {
// performing Sync flush on Async writer: ensure transport is free
writer.listeners.push(function(){
flushBuffer(writer, write, cb);
});
return;
}
flushBuffer(writer, write);
if (cb)
cb();
}
};
function flushBuffer(writer, write){
var data = joinBuffer(writer);
if (data === '')
return;
write(writer, data);
}
function joinBuffer(writer) {
var buf = writer.buffer;
if (buf.length === 0)
return '';
var newLine = writer.newLine,
data = buf.join(newLine)+ newLine;
buf.length = 0;
return data;
}
function callAll(fn, fns, error) {
if (fn)
fn(error);
var imax = fns.length,
i = -1;
if (imax === 0)
return;
while ( ++i < imax )
fns[i](error);
fns.length = 0;
}
}());
// end:source ./helper/Buffered.js
// source ./http/transport.js
_transports.http = function(){
var BUFFER_SIZE = 0,
_url,
_method,
_headers,
_type;
// source ./http_send.js
var http_send;
(function(){
http_send = function(data, cb){
// if NodeJS
send_node(_url, _method || 'POST', _headers, data, cb);
// endif
};
// if NodeJS
var Https = require('https'),
Http = require('http'),
Url = require('url');
function send_node(url, method, headers, data, cb){
method = method.toUpperCase();
headers = headers || {};
if (!headers['Content-Type'])
headers['Content-Type'] = 'text/plain';
headers['Content-Length'] = Buffer.byteLength(data);
if (method === 'GET') {
data = encode(data);
if (data == null) {
if (cb) cb('Encode failed');
return;
}
url += data;
data = void 0;
}
var options = Url.parse(url);
options.headers = headers;
options.method = method;
var T = options.protocol === 'https:'
? Https
: Http;
var msg = '';
var req = T.request(options, function(res){
res.setEncoding('utf-8');
res
.on('data', function(chunk){
msg += String(chunk);
})
.on('end', function(){
if (cb) cb(msg, res);
});
});
if (data != null) {
req.write(data);
}
req.end();
}
// endif
function encode(str) {
try {
return encodeURIComponent(str);
} catch(error){
Logger.error('Logger encode error', error);
return null;
}
}
}());
// end:source ./http_send.js
// source ./HttpHandler.js
var HttpHandler;
(function(){
HttpHandler = {
newLine: '\n',
busy: false,
listeners: [],
buffer: [],
write: function(message){
message = message.replace(/\n/g, '\\n');
this.buffer.push(message);
if (this.buffer.length > BUFFER_SIZE)
this.flushAsync();
},
flushAsync: function(cb){
Buffered.flushAsync(this, BUFFER_SIZE, Http_writeAsync, cb);
},
};
function Http_writeAsync(handler, data, cb){
http_send(data, cb);
}
}());
// end:source ./HttpHandler.js
return {
write: function(message){
HttpHandler.write(message);
},
flushAsync: function(cb){
HttpHandler.flushAsync(cb);
},
/* { bufferSize, url, method, headers } */
cfg: function(cfg){
if (cfg.bufferSize != null)
BUFFER_SIZE = cfg.bufferSize;
_url = cfg.url || _url;
_method = cfg.method || _method;
_headers = cfg.headers || _headers;
}
};
};
// end:source ./http/transport.js
// if NodeJS
// source ./Std.js
_transports.std = (function(){
return {
write: function(message){
this.put('\n' + message);
},
put: function(data) {
process.stdout.write(data);
},
cfg: function(){},
std: true
};
}());
// end:source ./Std.js
// source ./Stream.js
_transports.stream = (function(){
var _stream;
return {
write: function(message){
_stream.write(message);
},
put: function(message){
_stream.write(message);
},
cfg: function(config){
var stream = config.stream;
if (stream == null)
throw Error('Transport Configuration: No `stream` property');
if (stream.write == null)
throw Error('Transport Configuration: Invalid stream object');
_stream = stream;
}
};
}());
// end:source ./Stream.js
// source ./fs/transport.js
_transports.fs = function(){
var Path = require('path'),
Fs = require('fs')
;
// source vars.js
var path_DIR = 'logs',
path_Ext = 'txt',
os_EndOfLine = require('os').EOL,
// Bytes
FILE_MAXSIZE = 500 * 1024,
FILE_MAXCOUNT = 10,
// Message Count
BUFFER_SIZE = 0,
use_SYNC = false,
// EOL or <br/>
newLine
;
// end:source vars.js
// source utils/file.js
var file_append,
file_appendAsync,
file_readSize,
file_removeAsync,
file_remove;
(function() {
var Fs = require('fs'),
Path = require('path');
file_readSize = function(path) {
try {
return Fs.lstatSync(path).size;
} catch (error) {
return 0;
}
};
file_removeAsync = function(path, callback) {
Fs.unlink(path, function(error) {
if (error)
exception_(error);
callback(error);
});
};
file_remove = function(path) {
try {
Fs.unlinkSync(path);
} catch (error) {
exception_(error);
}
};
file_appendAsync = function(path, str, callback) {
if (!str) {
callback();
return;
}
Fs.open(path, 'a', function(error, fd) {
if (error != null) {
exception_(error);
callback(error);
return;
}
var buffer = new Buffer(str, 'utf8');
Fs.write(fd, buffer, 0, buffer.length, 0, function(error) {
if (error)
exception_(error);
Fs.close(fd, callback);
});
});
};
file_append = function(path, str) {
if (!str)
return;
try {
var fd = Fs.openSync(path, 'a');
Fs.writeSync(fd, str);
Fs.closeSync(fd);
} catch (error) {
exception_(error);
}
};
}());
// end:source utils/file.js
// source utils/dir.js
var dir_read,
dir_ensure;
(function() {
dir_read = function(path) {
try {
return Fs
.readdirSync(path);
} catch (error) {
exception_(error);
return [];
}
};
dir_ensure = function(path) {
if (Fs.existsSync(path))
return;
dir_ensure(Path.dirname(path));
try {
Fs.mkdirSync(path);
} catch (error) {
exception_(error);
}
};
}());
// end:source utils/dir.js
// source utils/std.js
var std_intercept;
(function() {
var orig = {};
saveOriginals(process.stdout, 'stdout');
saveOriginals(process.stderr, 'stderr');
std_intercept = function(state){
var fn = state !== false
? intercept
: deintercept
;
fn(process.stdout, 'stdout');
fn(process.stderr, 'stderr');
};
function saveOriginals(stream, type) {
orig[type] = {
write: stream.write,
end: stream.end
};
}
function deintercept(stream, type) {
stream.write = orig[type].write;
stream.end = orig[type].end;
}
function intercept(stream, type) {
stream.write = stream.end = function(data, encoding) {
if (data == null)
return;
if (typeof data !== 'string')
data = data.toString();
if (type === 'stderr')
data = data.red;
FsTransport.write(data);
};
}
}());
// end:source utils/std.js
// source File.js
var File = function(name, shouldReadStats){
this.buffer = [];
this.path = Path.resolve(_directory, name)
+ '.'
+ _extension
;
this.size = shouldReadStats !== true
? 0
: file_readSize(this.path)
;
};
File.prototype = {
get newLine () {
return newLine;
},
busy: false,
errored: false,
listeners: [],
write: function(message){
this.size += message.length + newLine.length;
this.buffer.push(message);
if (this.buffer.length > BUFFER_SIZE) {
this[use_SYNC ? 'flush' : 'flushAsync']();
}
if (this.size >= FILE_MAXSIZE) {
flow_nextFile();
}
},
flushAsync: function(cb){
Buffered.flushAsync(this, BUFFER_SIZE, File_writeAsync, cb);
},
flush: function(cb){
Buffered.flush(this, File_write, cb);
},
getBuffer_: function(){
if (this.buffer.length === 0)
return '';
var data = this.buffer.join(newLine)+ newLine;
this.buffer.length = 0;
return data;
}
};
function File_writeAsync(self, data, cb){
file_appendAsync(self.path, data, cb);
}
function File_write(self, data){
file_append(self.path, data);
}
// end:source File.js
// source flow.js
var flow_initialize,
flow_nextFile
;
(function(){
flow_initialize = function(){
newLine = _cfg.color === 'html'
? '<br/>'
: os_EndOfLine
;
dir_ensure(_directory);
var files = dir_read(_directory).sort(),
filename,
i = files.length,
rgx = /^\d+_/g
;
while ( --i > -1 ) {
filename = files[i];
if (rgx.test(filename)) {
break;
}
}
_file = i > -1
? new File(filename.replace(/\.\w+$/, ''), true)
: flow_nextFile()
;
if (_file.size >= FILE_MAXSIZE)
flow_nextFile();
if (files.length >= FILE_MAXCOUNT) {
files
.slice(0, files.length - FILE_MAXCOUNT + 1)
.forEach(function(filename){
file_remove(Path.resolve(_directory, filename));
});
}
};
flow_nextFile = function(){
if (_file != null)
_file.flush();
var d = new Date();
_file = new File(d.getTime()
+ '_'
+ (switch_++)
+ '_'
+ _format(d, 'dd-MM_hh'));
return _file;
};
var switch_ = 0;
}());
// end:source flow.js
// source exception.js
function exception_(error) {
try {
Fs.appendFileSync(
Path.resolve(_directory, 'logger-exceptions.txt'),
message_format([error]) + os_EndOfLine
);
} catch(error_) {
if (error_.code === 'ENOENT') {
dir_ensure(_directory);
exception_(error);
}
}
}
// end:source exception.js
var _directory = path_DIR,
_extension = path_Ext,
_file
;
var FsTransport = {
write: function(message, level){
if (_file == null)
flow_initialize();
_file.write(message);
},
flush: function(cb){
_file.flush(cb);
},
flushAsync: function(cb){
_file.flushAsync(cb);
},
/*
* { extension, directory, filesCount, fileSize, bufferSize }
*/
cfg: function(cfg){
_extension = cfg.extension || path_Ext;
_directory = Path.resolve(
//process.mainModule.filename,
Path.dirname(module.parent.filename),
cfg.directory || path_DIR
);
if (cfg.bufferSize != null)
BUFFER_SIZE = cfg.bufferSize;
if (cfg.filesCount)
FILE_MAXCOUNT = cfg.filesCount;
if (cfg.fileSize)
FILE_MAXSIZE = cfg.fileSize;
if (cfg.sync != null)
use_SYNC = cfg.sync;
if (cfg.interceptStd)
std_intercept();
},
interceptStd: function(state){
std_intercept(state);
},
exception: exception_
};
return FsTransport;
};
// end:source ./fs/transport.js
_transport = _transports.std;
// endif
return {
define: function(transportCfg){
var type = transportCfg.type;
_transport = _transports[type];
if (_transport == null)
throw Error('Transport type is not supported `' + type + '`');
if (typeof _transport === 'function') {
// initialize
_transport = _transport();
}
_transport.cfg(transportCfg);
return this;
},
write: function(message){
_transport.write(message);
},
get: function(type){
if (type == null)
return _transport;
var t = _transport[type];
if (t == null) throw Error('No transport: ' + type);
return typeof t === 'function'
? t()
: t
;
}
};
}());
// end:source ../src/transport/Transport.js
// source ../src/logger/Logger.js
var Logger;
(function(){
// source utils.js
var logger_canWrite,
logger_fn;
(function(){
logger_canWrite = function(instance, level){
var logLevel = level,
globalLevel = _level;
if (instance == null || instance instanceof Logger === false)
instance = mockedInstance;
var scope = instance._scope;
if (scope != null) {
var scoped = level_scope_Get(scope);
if (scoped != null)
return scoped + (level - level_LOG) /* diff */ <= globalLevel;
}
if (instance._level != null)
logLevel = instance._level;
if (logLevel <= globalLevel)
return true;
return false;
};
logger_fn = function(expectLevel, decorator){
return function(){
if (logger_canWrite(this, expectLevel) === false)
return this;
var msg = message_prepair(arguments, this);
if (decorator && typeof msg === 'string')
msg = decorator(msg);
Transport.write(msg);
return this;
};
};
var mockedInstance = {
_parent: null,
_level: null,
_name: null,
_scope: null
};
}());
// end:source utils.js
// source Proto.js
var LoggerProto,
LoggerEmptyProto;
(function(){
LoggerProto = {
_parent: null,
_level: null,
_name: null,
cfg: function(mix){
if (arguments.length === 0)
return _cfg;
if (typeof mix === 'string'){
if (arguments.length === 1)
return _cfg[mix];
cfg_set(mix, arguments[1]);
return this;
}
for (var key in mix) {
cfg_set(key, mix[key]);
}
return this;
},
color: Color,
formatMessage: function(){
return message_format(arguments);
},
log: logger_fn(level_LOG),
warn: logger_fn(level_WARN, function(msg){return msg.yellow.bold;}),
debug: logger_fn(level_DEBUG),
trace: logger_fn(level_TRACE),
error: logger_fn(level_ERROR, function(msg){return msg.red.bold;}),
getTransport: function() {
return Transport.get();
},
create: function(name, level){
return new Logger_Scope(
this instanceof Logger && this || null
, name
, level
);
},
level_LOG: level_LOG,
level_WARN: level_WARN,
level_TRACE: level_TRACE,
level_DEBUG: level_DEBUG,
level_ERROR: level_ERROR,
level_EXCEPTION : level_EXCEPTION
};
LoggerEmptyProto = obj_extend({}, LoggerProto);
LoggerEmptyProto.log =
LoggerEmptyProto.warn =
LoggerEmptyProto.debug =
LoggerEmptyProto.trace =
LoggerEmptyProto.error = fn_doNothing;
}());
// end:source Proto.js
// source Logger_Empty.js
var Logger_Empty;
(function() {
Logger_Empty = function(){};
Logger_Empty.prototype = LoggerEmptyProto;
}());
// end:source Logger_Empty.js
// source Logger_Scope.js
var Logger_Scope;
(function() {
Logger_Scope = function(parent, name, level){
this._parent = parent;
this._name = name;
this._level = level;
if (parent != null && parent._name)
this._name = parent._name + '.' + name;
this._scope = this._name;
var self = this;
function log(){
return self.log.apply(self, arguments);
}
log.__proto__ = self;
return log;
};
Logger_Scope.prototype = LoggerProto;
obj_extend(Logger_Scope, LoggerProto);
}());
// end:source Logger_Scope.js
Logger = function(mix1, mix2) {
if (typeof mix1 === 'string') {
return new Logger_Scope(
this instanceof Logger && this || null
, mix1
, mix2
);
}
if (typeof mix1 === 'number') {
return logger_canWrite(null, mix1)
? LoggerProto
: LoggerEmptyProto;
}
if (typeof mix1 === 'boolean') {
return mix1 === true
? LoggerProto
: LoggerEmptyProto;
}
return LoggerEmptyProto;
};
Logger.prototype = LoggerProto;
obj_extend(Logger, LoggerProto);
}());
// end:source ../src/logger/Logger.js
// source ../src/configurate.js
(function(){
if (typeof process === 'undefined')
return;
var args = process.argv.slice(2),
imax = args.length,
i = -1,
x;
while ( ++i < imax ) {
x = args[i].replace(/^\-+/,'');
switch (x) {
case 'no-color':
Logger.cfg('color', 'none');
break;
case 'level':
var level = getLevel('level');
if (level == null)
break;
Logger.cfg('level', level);
break;
default:
if (x.indexOf('level.') === 0) {
var level = getLevel('level.SCOPE_NAME');
if (level == null)
break;
x = x.replace('level.', '');
var obj = {};
obj[x] = level;
Logger.cfg('levels', obj);
}
break;
}
}
function getLevel(key){
var level = parseInt(args[++i]);
if (isNaN(level)) {
Logger.error('<atma-logger> invalid cli command --' + key + ' NUMBER');
return null;
}
return level;
}
}());
// end:source ../src/configurate.js
return Logger;
}));