Node.js Winston logger自定义格式覆盖时间戳
我正在节点应用程序中使用logger版本3.3.3。我有一个用于输出的自定义格式化程序,如下所示:Node.js Winston logger自定义格式覆盖时间戳,node.js,logging,winston,Node.js,Logging,Winston,我正在节点应用程序中使用logger版本3.3.3。我有一个用于输出的自定义格式化程序,如下所示: const winston = require('winston'); const jsonStr = require('fast-safe-stringify'); const customFormat = winston.format.printf(data => { const { level, message, timestamp } = data; const a
const winston = require('winston');
const jsonStr = require('fast-safe-stringify');
const customFormat = winston.format.printf(data => {
const { level, message, timestamp } = data;
const args = data[Symbol.for('splat')];
let strArgs = '';
if (args) {
strArgs = args.map(jsonStr).join(' ');
}
return `${timestamp} ${level}: ${message} ${strArgs}\n`;
});
logger = winston.createLogger({
level: 'debug',
format: winston.format.combine(winston.format.timestamp(), customFormat),
transports: [new winston.transports.Console()]
});
logger.log('debug', 'hi', 123, { a: 1, b: 'two' });
logger.log('debug', 'hi', { timestamp: 'this is bad' });
这使我可以使用不同类型的多个参数记录事件:
logger.log('debug', 'hi', 123, { a: 1, b: 'two' });
> 2020-11-11T19:01:46.942Z debug: hi 123 {"a":1,"b":"two"}
这就是我想要的。问题是,如果我记录了一个包含名为timestamp
的字段的对象,它会覆盖格式化程序中的timestamp
字段
logger.log('debug', 'hi', { timestamp: 'this is bad' } );
> this is bad debug: hi {"timestamp":"this is bad"}
因此,现在记录器的时间戳是字符串“this is bad”
,这是坏的。如果我将data
参数输出到printf()
方法,我会看到:
{
timestamp: 'this is bad',
level: 'debug',
message: 'hi',
[Symbol(level)]: 'debug',
[Symbol(splat)]: [ { timestamp: 'this is bad' } ] }
}
您可以看到,timestamp
字段显然被我传入的参数覆盖了。只有当log()
方法的第三个参数是具有名为timestamp
的属性的对象时,才会发生这种情况。所以这很好:
logger.log('debug', 'hi', 123, { timestamp: 'this is fine' } );
data: {
level: 'debug',
message: 'hi',
timestamp: '2020-11-11T19:08:27.326Z',
[Symbol(level)]: 'debug',
[Symbol(splat)]: [ 123, { timestamp: 'this is fine' } ]
}
> 2020-11-11T19:08:27.326Z debug: hi 123 {"timestamp":"this is fine"}
这是winston中的错误还是我的printf()
方法不正确
注:我有一份git回购协议复制了这个问题。嘿)我试图复制你的案例,但无法复制。试试这个代码
const winston = require('winston');
const customFormat = winston.format.printf((data) => {
const { level, message, timestamp } = data;
console.log('data', data);
const args = data[Symbol.for('splat')];
let strArgs = '';
if (args) {
console.log('args', args);
strArgs = args.map((argument) => JSON.stringify(argument)).join(' ');
}
return `${timestamp} ${level}: ${message} ${strArgs}\n`;
});
const logger = winston.createLogger({
format: customFormat,
transports: [
new winston.transports.Console({
level: 'debug',
}),
],
});
logger.log('debug', 'hi', 123, { a: 1, b: 'two' });
// logger.log('debug', 'hi', { timestamp: 'this is bad' });
我检查了,在第一种情况下,时间戳是未定义的。在第二种情况下,我得到了时间戳:“这是坏的”。Winston不会将自己的时间戳传递给我的日志信息。一个简单的解决方案是在
timestamp.format()
中为时间戳添加格式或别名,如下所示
logger = winston.createLogger({
level: 'debug',
format: winston.format.combine(
winston.format.timestamp({ format: 'YYYY-MM-DD HH:mm:ss' }), // can also alias
customFormat
),
transports: [new winston.transports.Console()]
});
logger.log('debug', 'hi', { timestamp: 'this is bad' } );
// outputs
2020-11-19 20:08:36 debug: hi {"timestamp":"this is bad"}
{
timestamp: '2020-11-19 20:08:36',
level: 'debug',
message: 'hi',
[Symbol(level)]: 'debug',
[Symbol(splat)]: [ { timestamp: 'this is bad' } ]
}
说到解释部分,我实际上不知道为什么时间戳会被覆盖,这很奇怪。这是因为
格式:
属性没有指定使用包含时间戳。请尝试此操作(抱歉格式化):const logger=winston.createLogger({format:winston.format.combine(winston.format.timestamp(),customFormat),transports:[new winston.transports.Console({level:'debug'})]代码>我接着写了一个更完整的代码示例和一个git回购协议,非常好,谢谢。但是你怎么知道指定格式可以解决这个问题呢?我不知道,这只是一个猜测。我只是浏览了我的一个项目,发现我提供了日期格式。我把它添加到了你的代码片段中,效果很好。这里有一些有用的链接