close = function (){ settings.level = Number.MAX_VALUE; }
...
setLevel and close methods to dynamically change the log level.
these are global settings, affect all output that are created via tracer
```javascript
var tracer = require('tracer');
tracer.setLevel(2); //or tracer.setLevel('debug');
//... ...
tracer.close();
```
notice:
if you set level in initialize, you can't change more lower level than the initial level.
```javascript
...
colorConsole = function (conf) { return require('./console')({ filters : { //log : do nothing trace : colors.magenta, debug : colors.cyan, info : colors.green, warn : colors.yellow, error : colors.red.bold } }, conf); }
...
var logger = require('tracer').console();
```
Color Console
```javascript
var logger = require('tracer').colorConsole();
```
Set Output Level
```javascript
var logger = require('tracer').colorConsole({level:'warn'});
```
...
console = function () { // default config var _config = { format : "{{timestamp}} <{{title}}> {{file}}:{{line}} ({{method}}) {{message}}", dateformat : "isoDateTime", preprocess : function(data) { }, transport : function(data) { console.log(data.output); }, filters : [], level : 'log', methods : [ 'log', 'trace', 'debug', 'info', 'warn', 'error' ], stackIndex : 0, // get the specified index of stack as file information. It is userful for development package. inspectOpt : { showHidden : false, //if true then the object's non-enumerable properties will be shown too. Defaults to false depth : 2 //tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated objects. Defaults to 2. To make it recurse indefinitely pass null. } }; // union user's config and default _config = utils.union(_config, arguments); var _self = {}; _config.format = Array.isArray(_config.format) ? _config.format : [ _config.format ]; _config.filters = Array.isArray(_config.filters) ? _config.filters : [ _config.filters ]; _config.transport = Array.isArray(_config.transport) ? _config.transport : [_config.transport]; var fLen = _config.filters.length, lastFilter; if (fLen > 0) if (Object.prototype.toString.call(_config.filters[--fLen]) != '[object Function]') { lastFilter = _config.filters[fLen]; _config.filters = _config.filters.slice(0, fLen); } if (typeof (_config.level) == 'string') _config.level = _config.methods.indexOf(_config.level); _config.methods.forEach(function(title, i) { if (i < _config.level) _self[title] = noop; else { var format = _config.format[0]; if (_config.format.length === 2 && _config.format[1][title]) format = _config.format[1][title]; var needstack = /{{(method|path|line|pos|file)}}/i.test(format); var filters; if (lastFilter && lastFilter[title]) filters = Array.isArray(lastFilter[title]) ? lastFilter[title] : [ lastFilter[title] ]; else filters = _config.filters; // interface _self[title] = function() { return logMain(_config, i, title, format, filters, needstack, arguments); }; } }); return _self; }
...
Usage
-----
Add to your code:
Simple Console
```javascript
var logger = require('tracer').console();
```
Color Console
```javascript
var logger = require('tracer').colorConsole();
...
dailyfile = function (conf) { var _conf = { root: '.', logPathFormat: '{{root}}/{{prefix}}.{{date}}.log', splitFormat: 'yyyymmdd', allLogsFileName: false, maxLogFiles: 10 }; _conf = utils.union(_conf, [conf]); function LogFile(prefix, date) { this.date = date; this.path = tinytim.tim(_conf.logPathFormat, {root: _conf.root, prefix: prefix, date: date}); spawnSync('mkdir', ['-p', _conf.root]); this.stream = fs.createWriteStream(this.path, { flags: "a", encoding: "utf8", mode: parseInt('0644', 8) // When engines node >= 4.0.0, following notation will be better: //mode: 0o644 }); } LogFile.prototype.write = function (str) { this.stream.write(str + "\n"); }; LogFile.prototype.destroy = function () { if (this.stream) { this.stream.end(); this.stream.destroySoon(); this.stream = null; } }; var _logMap = {}; function _push2File(str, title) { var logFile = _logMap[title], now = dateFormat(new Date(), _conf.splitFormat); if (logFile && logFile.date != now) { logFile.destroy(); logFile = null; } if (!logFile) { logFile = _logMap[title] = new LogFile(title, now); spawn('find', [_conf.root, '-type', 'f', '-name', '*.log', '-mtime', '+' + _conf.maxLogFiles, '-exec', 'rm', '{}', '\;']); } logFile.write(str); if (_conf.allLogsFileName) { var allLogFile = _logMap.allLogFile, now = dateFormat(new Date(), _conf.splitFormat); if (allLogFile && allLogFile.date != now) { allLogFile.destroy(); allLogFile = null; } if (!allLogFile) { allLogFile = _logMap.allLogFile = new LogFile(_conf.allLogsFileName, now); spawn('find', ['./', '-type', 'f', '-name', '*.log', '-mtime', '+' + _conf.maxLogFiles, '-exec', 'rm', '{}', '\;']); } allLogFile.write(str); } } function dailyFileTransport(data) { _push2File(data.output, data.title); } if (conf.transport) { conf.transport = Array.isArray(conf.transport) ? conf.transport : [conf.transport]; conf.transport.push(dailyFileTransport) } else { conf.transport = [dailyFileTransport]; } return require('./console')(conf); }
...
logger.info('hello %s %d', 'world', 123, {foo:'bar'});
logger.warn('hello %s %d %j', 'world', 123, {foo:'bar'});
logger.error('hello %s %d %j', 'world', 123, {foo:'bar'}, [1, 2, 3, 4], Object);
```
### Daily Log
```javascript
var logger = require('tracer').dailyfile({root:'.', maxLogFiles:
10, allLogsFileName: 'myAppName'});
logger.log('hello');
logger.trace('hello', 'world');
logger.debug('hello %s', 'world', 123);
logger.info('hello %s %d', 'world', 123, {foo:'bar'});
logger.warn('hello %s %d %j', 'world', 123, {foo:'bar'});
logger.error('hello %s %d %j', 'world', 123, {foo:'bar'}, [1, 2, 3, 4], Object);
...
getLevel = function (){ return settings.level; }
n/a
setLevel = function (level){ settings.level = level; }
...
setLevel and close methods to dynamically change the log level.
these are global settings, affect all output that are created via tracer
```javascript
var tracer = require('tracer');
tracer.setLevel(2); //or tracer.setLevel('debug');
//... ...
tracer.close();
```
notice:
if you set level in initialize, you can't change more lower level than the initial level.
...
close = function (){ settings.level = Number.MAX_VALUE; }
...
setLevel and close methods to dynamically change the log level.
these are global settings, affect all output that are created via tracer
```javascript
var tracer = require('tracer');
tracer.setLevel(2); //or tracer.setLevel('debug');
//... ...
tracer.close();
```
notice:
if you set level in initialize, you can't change more lower level than the initial level.
```javascript
...
getLevel = function (){ return settings.level; }
n/a
setLevel = function (level){ settings.level = level; }
...
setLevel and close methods to dynamically change the log level.
these are global settings, affect all output that are created via tracer
```javascript
var tracer = require('tracer');
tracer.setLevel(2); //or tracer.setLevel('debug');
//... ...
tracer.close();
```
notice:
if you set level in initialize, you can't change more lower level than the initial level.
...
format = function (f) { var inspectOpt = this.inspectOpt; var args = arguments; var i = 0; if (typeof f !== 'string') { var objects = []; for (; i < args.length; i++) { objects.push(util.inspect(args[i], inspectOpt)); } return objects.join(' '); } i = 1; var str = String(f).replace(formatRegExp, function(x) { switch (x) { case '%s': return String(args[i++]); case '%d': return Number(args[i++]); case '%j': try { if (args[i] instanceof Error) { return JSON.stringify(args[i++], ['message', 'stack', 'type', 'name']); } else { return JSON.stringify(args[i++]); } } catch(e) { return '[Circular]'; } case '%t': return util.inspect(args[i++], inspectOpt); default: return x; } }); for ( var len = args.length, x = args[i]; i < len; x = args[++i]) { if (x === null || typeof x !== 'object') { str += ' ' + x; } else { str += ' ' + util.inspect(x, inspectOpt); } } return str; }
n/a
union = function (obj, args) { for (var i = 0, len = args.length; i < len; i += 1) { var source = args[i]; for ( var prop in source) { obj[prop] = source[prop]; } } return obj; }
...
inspectOpt : {
showHidden : false, //if true then the object's non-enumerable properties will be shown too. Defaults to false
depth : 2 //tells inspect how many times to recurse while formatting the object. This is useful for inspecting large complicated
objects. Defaults to 2. To make it recurse indefinitely pass null.
}
};
// union user's config and default
_config = utils.union(_config, arguments);
var _self = {};
_config.format = Array.isArray(_config.format) ? _config.format
: [ _config.format ];
_config.filters = Array.isArray(_config.filters) ? _config.filters
...