使用 winston 记录 moment.js
Logging moment.js with winston
我想在我的 Node.js 应用程序中记录一些包含 moment.js 个对象的对象。
var moment = require('moment');
var myObject = {
anything: 'This is metadata',
moment: moment()
}
当我使用 console.log(myObject)
将此对象记录到我的控制台时,我得到以下输出:
{ anything: 'This is metadata',
moment: moment("2017-03-02T09:35:04.612") }
请注意 moment.js 对象如何打印为紧凑且可读的字符串。
现在,当我使用 winston 使用此对象记录事件时……
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)
.
生成的紧凑字符串
请注意我是如何将 prettyPrint
设置为 true
的。根据 winston 的文档,这意味着元数据(我的对象)将使用 util.inspect
打印
prettyPrint: Boolean flag indicating if we should util.inspect the meta (default false).
所以我自然而然地尝试了以下方法:
console.log(require('util').inspect(myObject));
令我惊讶的是,这会输出与 console.log(myObject)
完全相同的字符串。这是否意味着温斯顿没有像我那样使用 util.inspect ?还有什么我想念的吗?
更新
与winston的common.js文件中的this line有关。当我执行以下代码片段时,这会导致我的控制台中出现一个大对象。
var meta = require('cycle').decycle(myObject);
console.log(meta);
您可以添加一个rewriter:
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
.
在我摆弄的同时,我找到了完美的解决方案:
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
}) ],
});
通过 copying/cloning 原始元对象并返回它,输出正是我想要的样子,并且像着色这样的传输选项得到了尊重。
结果:
info: Test Log Message
{ anything: 'This is metadata',
moment: moment("2017-03-04T19:02:25.578") }
我很惭愧管理员我偶然发现了这个解决方案。我发现我的重写器正在修改我试图记录的实际对象,而没有先复制它。所以我添加了一行来克隆我的元对象,发现不再需要扫描我的对象并自己修改内容了。
如果有人能阐明这一点并且能够解释为什么这个解决方案确实有效,我将不胜感激。
我想在我的 Node.js 应用程序中记录一些包含 moment.js 个对象的对象。
var moment = require('moment');
var myObject = {
anything: 'This is metadata',
moment: moment()
}
当我使用 console.log(myObject)
将此对象记录到我的控制台时,我得到以下输出:
{ anything: 'This is metadata',
moment: moment("2017-03-02T09:35:04.612") }
请注意 moment.js 对象如何打印为紧凑且可读的字符串。
现在,当我使用 winston 使用此对象记录事件时……
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)
.
请注意我是如何将 prettyPrint
设置为 true
的。根据 winston 的文档,这意味着元数据(我的对象)将使用 util.inspect
prettyPrint: Boolean flag indicating if we should util.inspect the meta (default false).
所以我自然而然地尝试了以下方法:
console.log(require('util').inspect(myObject));
令我惊讶的是,这会输出与 console.log(myObject)
完全相同的字符串。这是否意味着温斯顿没有像我那样使用 util.inspect ?还有什么我想念的吗?
更新
与winston的common.js文件中的this line有关。当我执行以下代码片段时,这会导致我的控制台中出现一个大对象。
var meta = require('cycle').decycle(myObject);
console.log(meta);
您可以添加一个rewriter:
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
.
在我摆弄的同时,我找到了完美的解决方案:
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
}) ],
});
通过 copying/cloning 原始元对象并返回它,输出正是我想要的样子,并且像着色这样的传输选项得到了尊重。
结果:
info: Test Log Message
{ anything: 'This is metadata',
moment: moment("2017-03-04T19:02:25.578") }
我很惭愧管理员我偶然发现了这个解决方案。我发现我的重写器正在修改我试图记录的实际对象,而没有先复制它。所以我添加了一行来克隆我的元对象,发现不再需要扫描我的对象并自己修改内容了。
如果有人能阐明这一点并且能够解释为什么这个解决方案确实有效,我将不胜感激。