在node.js winston中添加行号configuration以logging日志时,时间戳会消失

我正在使用winston做一个自我logging器,它允许我在logging中添加时间戳和行号。 代码可以完成每个function,但是当它们合并时,它们不能按预期工作。

// **help to add timestamp** var logger = new (winston.Logger)({ transports : [new (winston.transports.Console)({ json : false, timestamp : true, colorize: true }), new winston.transports.File({ filename : __dirname + '/debug.log', json : true })] ,exitOnError : false }); // **help me to add line number** var logger_info_old = winston.info; logger.info = function(msg) { var fileAndLine = traceCaller(1); return logger_info_old.call(this, fileAndLine + ":" + msg); } 

但是,添加行号configuration时,logging的时间戳将消失。

例如,在添加行号configuration之前。

 logger.info("abc"); 2013-11-24T09:49:15.914Z - info:339:abc 

当添加行号configuration

 logger.info("abc"); info: (H:\Dropbox\node\fablab\utils\logging.js:85:abc 

我想要的最佳结果就像

 logger.info("abc"); 2013-11-24T09:49:15.914Z - info: (H:\Dropbox\node\fablab\app.js:339:abc 

我能解决这个问题吗?

我得到了这个工作,这是我做到了。

 var transports = [ new(winston.transports.Console)({ colorize: true, prettyPrint: true, timestamp : true, level: 'debug', }) ]; var log = new(winston.Logger)({ "transports": transports }); for (var func in winston.levels) { var oldFunc = log[func]; log[func] = function() { var args = Array.prototype.slice.call(arguments); args.unshift(traceCaller(1)); oldFunc.apply(log, args); } } 

与此同时,我得到了时间戳和文件。 (注意traceCaller(1)是从这个stackoverflow的问题: 我想显示在日志语句中的文件名称 )。 我在winston.levels上做了for循环,所以我不但可以获取所有的函数信息。

你没有工作的原因是你的logger_info_old来自winston,而不是logging器。 所以

 var logger_info_old = winston.info; 

本来应该

 var logger_info_old = logger.info; 

我更新了@ jeff-whiting的答案(使用闭包和修复string插值)并将其作为一个单一的函数。
通过一个现有的logging器添加callsite信息到它的关卡function。
注意logger.log()不会更改,只有logger.{level}()被更改。

 // add callsite info to winston logger instance function addCallSite(logger) { // WARNING: traceCaller is slow // http://stackoverflow.com/a/20431861/665507 // http://stackoverflow.com/a/13411499/665507 /** * examines the call stack and returns a string indicating * the file and line number of the n'th previous ancestor call. * this works in chrome, and should work in nodejs as well. * * @param n : int (default: n=1) - the number of calls to trace up the * stack from the current call. `n=0` gives you your current file/line. * `n=1` gives the file/line that called you. */ function traceCaller(n) { if( isNaN(n) || n<0) n=1; n+=1; var s = (new Error()).stack , a=s.indexOf('\n',5); while(n--) { a=s.indexOf('\n',a+1); if( a<0 ) { a=s.lastIndexOf('\n',s.length); break;} } b=s.indexOf('\n',a+1); if( b<0 ) b=s.length; a=Math.max(s.lastIndexOf(' ',b), s.lastIndexOf('/',b)); b=s.lastIndexOf(':',b); s=s.substring(a+1,b); return s; } // assign to `logger.{level}()` for (var func in logger.levels) { (function (oldFunc) { logger[func] = function() { var args = Array.prototype.slice.call(arguments); if (typeof args[0] === 'string') { args[0] = traceCaller(1) + ' ' + args[0]; } else { args.unshift(traceCaller(1)); } oldFunc.apply(logger, args); }; })(logger[func]); }; }