consoleに出力区分と時間を追加しただけですが、意外と見やすくなります。
自分がよく使う部分しか実装してません。(dirとかassertは未実装)
メモ書き程度に
参考
code
colorConsole.js
var
util = require('util'),
red = '\u001b[31m',
green = '\u001b[32m',
yellow = '\u001b[33m',
blue = '\u001b[34m',
magenta = '\u001b[35m',
cyan = '\u001b[36m',
reset = '\u001b[0m';
function df(dt, format){
var year = dt.getFullYear().toString(),
month = ('0'+(dt.getMonth()+1)).slice(-2),
date = ('0'+dt.getDate()).slice(-2),
hour = ('0'+dt.getHours()).slice(-2),
min = ('0'+dt.getMinutes()).slice(-2),
sec = ('0'+dt.getSeconds()).slice(-2),
misec = ('00'+dt.getMilliseconds()).slice(-3);
if(format.match(/yyyy/g)) format = format.replace(/yyyy/g, year);
else if(format.match(/yy/g)) format = format.replace(/yy/g, year.slice(-2));
if(format.match(/MM/g)) format = format.replace(/MM/g, month);
else if(format.match(/M/g)) format = format.replace(/M/g, month.slice(-1));
if(format.match(/dd/g)) format = format.replace(/dd/g, date);
else if(format.match(/d/g)) format = format.replace(/d/g, date.slice(-1));
if(format.match(/hh/g)) format = format.replace(/hh/g, hour);
else if(format.match(/h/g)) format = format.replace(/h/g, hour.slice(-1));
if(format.match(/mm/g)) format = format.replace(/mm/g, min);
else if(format.match(/m/g)) format = format.replace(/m/g, min.slice(-1));
if(format.match(/ss/g)) format = format.replace(/ss/g, sec);
else if(format.match(/s/g)) format = format.replace(/s/g, sec.slice(-1));
if(format.match(/SSS/g)) format = format.replace(/SSS/g, misec);
return format;
};
var ColorConsole = function(format){
stdout = process.stdout;
stderr = process.stderr;
if (!(this instanceof ColorConsole)) {
return new ColorConsole(stdout, stderr);
}
if (!stdout || !util.isFunction(stdout.write)) {
throw new TypeError('Console expects a writable stream instance');
}
if (!stderr) {
stderr = stdout;
}
var prop = {
writable: true,
enumerable: false,
configurable: true
};
prop.value = stdout;
Object.defineProperty(this, '_stdout', prop);
prop.value = stderr;
Object.defineProperty(this, '_stderr', prop);
prop.value = {};
Object.defineProperty(this, '_times', prop);
Object.keys(ColorConsole.prototype).forEach(function(k) {
this[k] = this[k].bind(this);
}, this);
this._fmt = format;
}
ColorConsole.prototype.log = function() {
var s = magenta + '[LOG]';
if(this._fmt)
s += df(new Date(), this._fmt);
s+=reset + ' ';
this._stdout.write(s + util.format.apply(this, arguments) + '\n');
};
ColorConsole.prototype.info = function() {
var s = green + '[INFO]';
if(this._fmt)
s += df(new Date(), this._fmt);
s+=reset + ' ';
this._stdout.write(s + util.format.apply(this, arguments) + '\n');
};
ColorConsole.prototype.warn = function() {
var s = yellow + '[WARN]';
if(this._fmt)
s += df(new Date(), this._fmt);
s+=reset + ' ';
this._stderr.write(s + util.format.apply(this, arguments) + '\n');
};
ColorConsole.prototype.error = function() {
var s = red + '[ERROR]';
if(this._fmt)
s += df(new Date(), this._fmt);
s+=reset + ' ';
this._stderr.write(s + util.format.apply(this, arguments) + '\n');
};
ColorConsole.prototype.trace = function() {
var err = new Error;
err.name = 'Trace';
err.message = util.format.apply(this, arguments);
Error.captureStackTrace(err, arguments.callee);
var s = cyan + '[TRACE]';
if(this._fmt)
s += df(new Date(), this._fmt);
s+=reset + ' ';
this._stderr.write(s + '\n' + err.stack + '\n');
};
ColorConsole.prototype.time = function(label) {
this._times[label] = Date.now();
};
ColorConsole.prototype.timeEnd = function(label) {
var time = this._times[label];
if (!time) {
throw new Error('No such label: ' + label);
}
var duration = Date.now() - time;
this.log('%s: %dms', label, duration);
};
module.exports = ColorConsole;
DEMO
var ColorConsole = new require('./colorConsole.js');
var logger = new ColorConsole('yy-MM-dd hh:mm:ss.SSS');
logger.log('%s world', 'hello');
logger.info('pid = %d', process.pid);
logger.warn('warn');
logger.error('error', [1,2,3,4]);
logger.trace('Error Name');
logger.time('time');
setTimeout(logger.timeEnd, 1000, 'time');
出力結果