用winstonloggingmoment.js

我想在我的Node.js应用程序中包含一些包含moment.js对象的对象。

var moment = require('moment'); var myObject = { anything: 'This is metadata', moment: moment() } 

当我使用console.log(myObject)这个对象logging到我的控制台时,我得到以下输出:

 { anything: 'This is metadata', moment: moment("2017-03-02T09:35:04.612") } 

请注意,如何将moment.js对象打印为紧凑且可读的string。

现在,当我用winstonlogging这个对象的事件时…

 var winston = require('winston'); winston.configure({ transports: [ new (winston.transports.Console)({ prettyPrint: true }) ] }); winston.info('Test Log Message', myObject); 

它在我的控制台中转储了一个巨大的对象:

 info: Test Log Message { anything: 'This is metadata', moment: { _isAMomentObject: true, _isUTC: false, _pf: { empty: false, unusedTokens: [], unusedInput: [], overflow: -2, charsLeftOver: 0, nullInput: false, invalidMonth: null, invalidFormat: false, userInvalidated: false, iso: false, parsedDateParts: [], meridiem: null }, _locale: { _calendar: { sameDay: '[Today at] LT', nextDay: '[Tomorrow at] LT', nextWeek: 'dddd [at] LT', lastDay: '[Yesterday at] LT', lastWeek: '[Last] dddd [at] LT', sameElse: 'L' }, _longDateFormat: { LTS: 'h:mm:ss A', LT: 'h:mm A', L: 'MM/DD/YYYY', LL: 'MMMM D, YYYY', LLL: 'MMMM D, YYYY h:mm A', LLLL: 'dddd, MMMM D, YYYY h:mm A' }, etc, etc, etc… 

这不是我想在我的日志中看到的。 我更喜欢由console.log(myObject)生成的紧凑string。

请注意我如何将prettyPrint设置为true 。 根据Winston的文档,这意味着将使用util.inspect打印元数据(我的对象)

prettyPrint :布尔标志,指示是否应该检查元(默认为false)。

所以自然我尝试了以下几点:

 console.log(require('util').inspect(myObject)); 

令我惊讶的是,输出与console.log(myObject)完全相同的string。 这是否意味着winston并没有像我这样使用util.inspect? 还有什么我失踪?

更新

这与winston的common.js文件中的这一行有关。 当我执行下面的代码片段时,这会导致我的控制台中有一个很大的对象。

 var meta = require('cycle').decycle(myObject); console.log(meta); 

当我在摆弄时,我发现了一个完美的解决scheme:

 var winston = require('winston'); winston.configure({ rewriters: [ function (level, msg, meta) { return winston.clone(meta); } ], transports: [ new (winston.transports.Console)({ level: 'debug', colorize: true, prettyPrint: true }) ], }); 

通过复制/克隆原始元对象并将其返回,输出结果就是我想要的,并且像colorize这样的传输选项得到了尊重。

结果:

 info: Test Log Message { anything: 'This is metadata', moment: moment("2017-03-04T19:02:25.578") } 

我对pipe理员感到羞耻,我偶然发现了这个解决scheme。 我发现我的重写器正在修改我正在尝试login的实际对象,而不是先复制它。 所以我添加了一行来克隆我的元对象,发现没有必要扫描我的对象,并自己修改内容了。

如果任何人都可以对此发表一些看法,并能够解释为什么这个解决scheme真的有效,我将不胜感激。

您可以添加一个重写器 :

 winston.configure({ transports: [ new (winston.transports.Console)({ prettyPrint: true }) ], rewriters: [ (level, msg, meta) => { if (moment.isMoment(meta.moment)) { meta.moment = meta.moment.toString(); } return meta; } ] }); 

这不是非常通用的,因为它只适用于一个叫做moment的属性,但是很容易使它成为通用的。 此外,您可以将Moment实例格式化为任何您喜欢的内容,该示例仅调用toString