我试图使用winston进行日志记录,但我看到如果我想用2个arg获取数据,那么我得到了日志,但如果我想得到3个参数,那么我没有得到数据,
例如:
logger = new (winston.Logger)({
transports: [
new (winston.transports.Console)({colorize : true, timestamp:true}),
]
});
现在尝试获取如下日志:
1. logger.info("We got the data %s, %d", data, port);
O/P: We got the data %s, %d => No data and port value
2. logger.info("We got the data, port", data, port);
O/P: We got the data, port => No data and port value
3. logger.info("We got the data", data);
===> Getting the data correctly.
你能不能让我知道我在1,2中丢失了什么,或者winston没有记录案例1和1中的数据。 2真的吗?
答案 0 :(得分:3)
您假设有一个varargs样式API,但没有。完整的API是level, msg, meta, callback
,但是当您使用其中一种方法时,它只是msg, meta, callback
。您需要构造一个meta
对象并传递它。
https://github.com/flatiron/winston/blob/master/lib/winston/logger.js#L115
//
// ### function log (level, msg, [meta], callback)
// #### @level {string} Level at which to log the message.
// #### @msg {string} Message to log
// #### @meta {Object} **Optional** Additional metadata to attach
// #### @callback {function} Continuation to respond to when complete.
// Core logging method exposed to Winston. Metadata is optional.
//
答案 1 :(得分:1)
我通过包装winston函数和使用包装器解决了这个问题。我希望现在有更好的解决方案。
var logger = new (winston.Logger)({
transports:[new (winston.transports.Console)({ json : false, timestamp : true, level : 0, colorize : true}),
new (winston.transports.File)({ filename: filepath, json : false, timestamp : true, level : 0, colorize: true })]
});
// pass in function arguments object and returns string with whitespaces
function argumentsToString(v){
// convert arguments object to real array
var args = Array.prototype.slice.call(v);
for(var k in args){
if (typeof args[k] === "object"){
// args[k] = JSON.stringify(args[k]);
args[k] = util.inspect(args[k], false, null, true);
}
}
var str = args.join(" ");
return str;
}
// wrapping the winston function to allow for multiple arguments
var wrap = {};
wrap.info = function () {
logger.log.apply(logger, ["info", argumentsToString(arguments)]);
};
wrap.error = function () {
logger.log.apply(logger, ["error", argumentsToString(arguments)]);
};
wrap.warn = function () {
logger.log.apply(logger, ["warn", argumentsToString(arguments)]);
};
wrap.debug = function () {
logger.log.apply(logger, ["debug", argumentsToString(arguments)]);
};
///然后返回换行,因为它是你的记录器。 ///并使用像log.info(1,2,3,4,“foo”,“bar”);
答案 2 :(得分:0)
由于Winston API不能像console.log
那样工作,因此一种解决方法是创建一个包装器函数,该函数可以通过以下方式利用util.format
:
const util = require('util')
...
function log(...msg) {
logger.info(util.format(...msg))
}
然后您可以像这样调用日志:
log('my log entry', 'foo, 'bar')
将这样记录:{"message":"my log entry foo bar","level":"info"}
答案 3 :(得分:0)
这对我和Winston 3.2.x都有效:
const { format, createLogger, transports } = require('winston');
const jsonStringify = require('fast-safe-stringify');
const logLikeFormat = {
transform(info) {
const { timestamp, label, message } = info;
const level = info[Symbol.for('level')];
const args = info[Symbol.for('splat')];
const strArgs = args.map(jsonStringify).join(' ');
info[Symbol.for('message')] = `${timestamp} [${label}] ${level}: ${message} ${strArgs}`;
return info;
}
};
const debugFormat = {
transform(info) {
console.log(info);
return info;
}
};
const logger = createLogger({
format: format.combine(
// debugFormat, // uncomment to see the internal log structure
format.timestamp(),
format.label({ label: 'myLabel' }),
logLikeFormat,
// debugFormat, // uncomment to see the internal log structure
),
transports: [
new transports.Console()
]
});
logger.info('foo', 'bar', 1, [2, 3], true, { name: 'John' });
其结果是:2019-07-04T21:30:08.455Z [myLabel] info: foo "bar" 1 [2,3] true {"name":"John"}
基本上format.combine
设置info
对象的管道。对于每个格式函数,将调用transform
,最后的日志消息应写入info[Symbol.for('message')]
希望对您有帮助