logger: add logger "contexts".
This commit is contained in:
parent
b104e664a7
commit
81b565fc85
@ -69,6 +69,21 @@ Logger.levelsByVal = [
|
||||
'spam'
|
||||
];
|
||||
|
||||
/**
|
||||
* Available log levels.
|
||||
* @const {String[]}
|
||||
* @default
|
||||
*/
|
||||
|
||||
Logger.prefixByVal = [
|
||||
'N',
|
||||
'E',
|
||||
'W',
|
||||
'I',
|
||||
'D',
|
||||
'S'
|
||||
];
|
||||
|
||||
/**
|
||||
* Default CSI colors.
|
||||
* @const {String[]}
|
||||
@ -122,6 +137,7 @@ Logger.prototype.init = function init(options) {
|
||||
|
||||
/**
|
||||
* Open the logger.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
Logger.prototype.open = co(function* open() {
|
||||
@ -137,6 +153,7 @@ Logger.prototype.open = co(function* open() {
|
||||
|
||||
/**
|
||||
* Destroy the write stream.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
Logger.prototype.close = co(function* close() {
|
||||
@ -233,7 +250,338 @@ Logger.prototype.error = function error(err) {
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this._error(err);
|
||||
return this.logError(Logger.levels.ERROR, null, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
this.log(Logger.levels.ERROR, null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the `warning` log level.
|
||||
* @param {String|Object} obj
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.warning = function warning(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.WARNING)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.WARNING, null, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
this.log(Logger.levels.WARNING, null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the `info` log level.
|
||||
* @param {String|Object} obj
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.info = function info(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.INFO)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.INFO, null, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
this.log(Logger.levels.INFO, null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the `debug` log level.
|
||||
* @param {String|Object} obj
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.debug = function debug(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.DEBUG)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.DEBUG, null, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
this.log(Logger.levels.DEBUG, null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the `spam` log level.
|
||||
* @param {String|Object} obj
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.spam = function spam(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.SPAM)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.SPAM, null, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
args[i] = arguments[i];
|
||||
|
||||
this.log(Logger.levels.SPAM, null, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the desired log level.
|
||||
* Note that this bypasses the level check.
|
||||
* @param {String} level
|
||||
* @param {String|null} module
|
||||
* @param {Object[]} args
|
||||
*/
|
||||
|
||||
Logger.prototype.log = function log(level, module, args) {
|
||||
if (this.closed)
|
||||
return;
|
||||
|
||||
if (this.level < level)
|
||||
return;
|
||||
|
||||
this.writeConsole(level, module, args);
|
||||
this.writeStream(level, module, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Create logger context.
|
||||
* @param {String} module
|
||||
* @returns {LoggerContext}
|
||||
*/
|
||||
|
||||
Logger.prototype.context = function context(module) {
|
||||
return new LoggerContext(this, module);
|
||||
};
|
||||
|
||||
/**
|
||||
* Write log to the console.
|
||||
* @param {String} level
|
||||
* @param {String|null} module
|
||||
* @param {Object[]} args
|
||||
*/
|
||||
|
||||
Logger.prototype.writeConsole = function writeConsole(level, module, args) {
|
||||
var name = Logger.prefixByVal[level];
|
||||
var msg = '';
|
||||
var fmt, color;
|
||||
|
||||
assert(name, 'Invalid log level.');
|
||||
|
||||
if (!this.console)
|
||||
return;
|
||||
|
||||
if (util.isBrowser) {
|
||||
fmt = args[0];
|
||||
msg += '[' + name + '] ';
|
||||
|
||||
if (module)
|
||||
msg += '(' + module + ') ';
|
||||
|
||||
if (typeof args[0] !== 'object')
|
||||
fmt = util.format(args, false);
|
||||
|
||||
msg += fmt;
|
||||
|
||||
return level === Logger.levels.ERROR
|
||||
? console.error(msg)
|
||||
: console.log(msg);
|
||||
}
|
||||
|
||||
if (this.colors) {
|
||||
color = Logger.colors[level];
|
||||
msg += '\x1b[' + color + 'm';
|
||||
msg += '[' + name + '] ';
|
||||
msg += '\x1b[m';
|
||||
}
|
||||
|
||||
if (module)
|
||||
msg += '(' + module + ') ';
|
||||
|
||||
msg += util.format(args, this.colors);
|
||||
|
||||
return level === Logger.levels.ERROR
|
||||
? process.stderr.write(msg + '\n')
|
||||
: process.stdout.write(msg + '\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Write a string to the output stream (usually a file).
|
||||
* @param {String} level
|
||||
* @param {String|null} module
|
||||
* @param {Object[]} args
|
||||
*/
|
||||
|
||||
Logger.prototype.writeStream = function writeStream(level, module, args) {
|
||||
var name = Logger.prefixByVal[level];
|
||||
var stream = this.stream;
|
||||
var msg = '';
|
||||
var prefix;
|
||||
|
||||
assert(name, 'Invalid log level.');
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
msg += '['
|
||||
msg += name;
|
||||
msg += ':' + util.date();
|
||||
msg += '] ';
|
||||
|
||||
if (module)
|
||||
msg += '(' + module + ') ';
|
||||
|
||||
msg += util.format(args, false);
|
||||
msg += '\n';
|
||||
|
||||
stream.write(msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to parse an error into a nicer
|
||||
* format. Call's `log` internally.
|
||||
* @private
|
||||
* @param {Number} level
|
||||
* @param {String|null} module
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
Logger.prototype.logError = function logError(level, module, err) {
|
||||
var msg;
|
||||
|
||||
if (this.closed)
|
||||
return;
|
||||
|
||||
if (util.isBrowser && this.console && level >= Logger.levels.DEBUG)
|
||||
console.error(err);
|
||||
|
||||
msg = (err.message + '').replace(/^ *Error: */, '');
|
||||
|
||||
this.log(level, module, [msg]);
|
||||
|
||||
if (this.level >= Logger.levels.DEBUG) {
|
||||
if (this.stream)
|
||||
this.stream.write(err.stack + '\n');
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Log the current memory usage.
|
||||
* @param {String|null} module
|
||||
*/
|
||||
|
||||
Logger.prototype.memory = function memory(module) {
|
||||
var mem;
|
||||
|
||||
if (!process.memoryUsage)
|
||||
return;
|
||||
|
||||
mem = process.memoryUsage();
|
||||
|
||||
this.log(Logger.levels.DEBUG, module,
|
||||
['Memory: rss=%dmb, js-heap=%d/%dmb native-heap=%dmb',
|
||||
util.mb(mem.rss),
|
||||
util.mb(mem.heapUsed),
|
||||
util.mb(mem.heapTotal),
|
||||
util.mb(mem.rss - mem.heapTotal)]);
|
||||
};
|
||||
|
||||
/**
|
||||
* Basic stdout and file logger.
|
||||
* @constructor
|
||||
* @ignore
|
||||
* @param {Logger} logger
|
||||
* @param {String} module
|
||||
*/
|
||||
|
||||
function LoggerContext(logger, module) {
|
||||
if (!(this instanceof LoggerContext))
|
||||
return new LoggerContext(logger, module);
|
||||
|
||||
assert(typeof module === 'string');
|
||||
|
||||
this.logger = logger;
|
||||
this.module = module;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open the logger.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.open = function open() {
|
||||
return this.logger.open();
|
||||
};
|
||||
|
||||
/**
|
||||
* Destroy the write stream.
|
||||
* @returns {Promise}
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.close = function close() {
|
||||
return this.logger.close();
|
||||
};
|
||||
|
||||
/**
|
||||
* Set the log file location.
|
||||
* @param {String} filename
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.setFile = function setFile(filename) {
|
||||
this.logger.setFile(filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Set or reset the log level.
|
||||
* @param {String} level
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.setLevel = function setLevel(name) {
|
||||
this.logger.setLevel(name);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Output a log to the `error` log level.
|
||||
* @param {String|Object|Error} err
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.error = function error(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.logger.level < Logger.levels.ERROR)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.ERROR, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
@ -243,18 +591,33 @@ Logger.prototype.error = function error(err) {
|
||||
this.log(Logger.levels.ERROR, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to parse an error into a nicer
|
||||
* format. Call's `log` internally.
|
||||
* @private
|
||||
* @param {Number} level
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
LoggerContext.prototype.logError = function logError(level, err) {
|
||||
this.logger.logError(level, this.module, err);
|
||||
};
|
||||
|
||||
/**
|
||||
* Output a log to the `warning` log level.
|
||||
* @param {String|Object} obj
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.warning = function warning() {
|
||||
LoggerContext.prototype.warning = function warning(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.WARNING)
|
||||
if (this.logger.level < Logger.levels.WARNING)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.WARNING, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
@ -269,12 +632,15 @@ Logger.prototype.warning = function warning() {
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.info = function info() {
|
||||
LoggerContext.prototype.info = function info(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.INFO)
|
||||
if (this.logger.level < Logger.levels.INFO)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.INFO, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
@ -289,12 +655,15 @@ Logger.prototype.info = function info() {
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.debug = function debug() {
|
||||
LoggerContext.prototype.debug = function debug(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.DEBUG)
|
||||
if (this.logger.level < Logger.levels.DEBUG)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.DEBUG, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
@ -309,12 +678,15 @@ Logger.prototype.debug = function debug() {
|
||||
* @param {...Object} args
|
||||
*/
|
||||
|
||||
Logger.prototype.spam = function spam() {
|
||||
LoggerContext.prototype.spam = function spam(err) {
|
||||
var i, args;
|
||||
|
||||
if (this.level < Logger.levels.SPAM)
|
||||
if (this.logger.level < Logger.levels.SPAM)
|
||||
return;
|
||||
|
||||
if (err instanceof Error)
|
||||
return this.logError(Logger.levels.SPAM, err);
|
||||
|
||||
args = new Array(arguments.length);
|
||||
|
||||
for (i = 0; i < args.length; i++)
|
||||
@ -330,127 +702,26 @@ Logger.prototype.spam = function spam() {
|
||||
* @param {Object[]} args
|
||||
*/
|
||||
|
||||
Logger.prototype.log = function log(level, args) {
|
||||
if (this.closed)
|
||||
return;
|
||||
|
||||
if (this.level < level)
|
||||
return;
|
||||
|
||||
this.writeConsole(level, args);
|
||||
this.writeStream(level, args);
|
||||
LoggerContext.prototype.log = function log(level, args) {
|
||||
this.logger.log(level, this.module, args);
|
||||
};
|
||||
|
||||
/**
|
||||
* Write log to the console.
|
||||
* @param {String} level
|
||||
* @param {Object[]} args
|
||||
* Create logger context.
|
||||
* @param {String} module
|
||||
* @returns {LoggerContext}
|
||||
*/
|
||||
|
||||
Logger.prototype.writeConsole = function writeConsole(level, args) {
|
||||
var name = Logger.levelsByVal[level];
|
||||
var prefix, msg, color;
|
||||
|
||||
assert(name, 'Invalid log level.');
|
||||
|
||||
if (!this.console)
|
||||
return;
|
||||
|
||||
prefix = '[' + name + '] ';
|
||||
|
||||
if (util.isBrowser) {
|
||||
msg = typeof args[0] !== 'object'
|
||||
? util.format(args, false)
|
||||
: args[0];
|
||||
|
||||
msg = prefix + msg;
|
||||
|
||||
return level === Logger.levels.ERROR
|
||||
? console.error(msg)
|
||||
: console.log(msg);
|
||||
}
|
||||
|
||||
if (this.colors) {
|
||||
color = Logger.colors[level];
|
||||
prefix = '\x1b[' + color + 'm' + prefix + '\x1b[m';
|
||||
}
|
||||
|
||||
msg = prefix + util.format(args, this.colors);
|
||||
|
||||
return level === Logger.levels.ERROR
|
||||
? process.stderr.write(msg + '\n')
|
||||
: process.stdout.write(msg + '\n');
|
||||
};
|
||||
|
||||
/**
|
||||
* Write a string to the output stream (usually a file).
|
||||
* @param {String} level
|
||||
* @param {Object[]} args
|
||||
*/
|
||||
|
||||
Logger.prototype.writeStream = function writeStream(level, args) {
|
||||
var name = Logger.levelsByVal[level];
|
||||
var stream = this.stream;
|
||||
var prefix, msg;
|
||||
|
||||
assert(name, 'Invalid log level.');
|
||||
|
||||
if (!stream)
|
||||
return;
|
||||
|
||||
prefix = '[' + name + '] ';
|
||||
msg = prefix + util.format(args, false);
|
||||
msg = '(' + util.date() + '): ' + msg + '\n';
|
||||
|
||||
if (!util.isBrowser)
|
||||
msg = process.pid + ' ' + msg;
|
||||
|
||||
stream.write(msg);
|
||||
};
|
||||
|
||||
/**
|
||||
* Helper to parse an error into a nicer
|
||||
* format. Call's `log` internally.
|
||||
* @private
|
||||
* @param {Error} err
|
||||
*/
|
||||
|
||||
Logger.prototype._error = function error(err) {
|
||||
var msg;
|
||||
|
||||
if (this.closed)
|
||||
return;
|
||||
|
||||
if (util.isBrowser && this.console)
|
||||
console.error(err);
|
||||
|
||||
msg = (err.message + '').replace(/^ *Error: */, '');
|
||||
|
||||
this.log(Logger.levels.ERROR, [msg]);
|
||||
|
||||
if (this.level >= Logger.levels.DEBUG) {
|
||||
if (this.stream)
|
||||
this.stream.write(err.stack + '\n');
|
||||
}
|
||||
LoggerContext.prototype.context = function context(module) {
|
||||
return new LoggerContext(this.logger, module);
|
||||
};
|
||||
|
||||
/**
|
||||
* Log the current memory usage.
|
||||
*/
|
||||
|
||||
Logger.prototype.memory = function memory() {
|
||||
var mem;
|
||||
|
||||
if (!process.memoryUsage)
|
||||
return;
|
||||
|
||||
mem = process.memoryUsage();
|
||||
|
||||
this.debug('Memory: rss=%dmb, js-heap=%d/%dmb native-heap=%dmb',
|
||||
util.mb(mem.rss),
|
||||
util.mb(mem.heapUsed),
|
||||
util.mb(mem.heapTotal),
|
||||
util.mb(mem.rss - mem.heapTotal));
|
||||
LoggerContext.prototype.memory = function memory() {
|
||||
this.logger.memory(this.module);
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Loading…
Reference in New Issue
Block a user