用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
。