我在Node.js中使用Winston进行日志记录。我知道我可以单独为每条日志消息添加元数据,但有没有办法指定一个默认的元数据集,它将被添加到每个日志消息(例如应用程序名称),因为我不想每次都指定它我需要发送一条日志消息。
答案 0 :(得分:41)
对于Winston v2(见评论)
现在有rewriters
是记录在案的官方方式:
logger.rewriters.push(function(level, msg, meta) {
meta.app = 'myApp';
return meta;
});
将为此记录器中的每个元数据添加一个属性app
您也可以在构建记录器时声明它:
new (winston.Logger)({
level: config.log[file].level,
rewriters: [
(level, msg, meta) => {
meta.app = 'myApp';
return meta;
}
],
transports: [
/*your transports*/
]
});
答案 1 :(得分:21)
没有内置的方法可以做到这一点,但你绝对可以自己添加 - 这是如何:
首先,像往常一样设置记录器。例如:
var logger = new (winston.Logger)({
"exitOnError" : true,
"transports" : [
new (winston.transports.Console)({ "colorize" : true, "level" : "silly", "silent" : false, "handleExceptions" : false }),
]
});
然后覆盖log()方法(这总是由级别方法调用 - logger.foo()
实际调用logger.log('foo')
。)
logger.log = function(){
var args = arguments;
if(args[2]) args[3] = args[2];
args[2] = {
"foo" : "bar"
}
winston.Logger.prototype.log.apply(this,args);
}
我上面所做的就是在调用logger.log()
时这样做,而是调用上面的方法,该方法添加了元数据(在本例中是一个包含foo
键的对象)。然后它从正确的上下文中调用winston的Logger.log方法。
上面的代码将在您创建的模块中,在底部只导出记录器:
module.exports = logger;
并导入记录器模块而不是子类中的winston模块。
var logger = require('./logger.js');
希望有所帮助!
答案 2 :(得分:11)
对于Winston v3:
const addAppNameFormat = winston.format(info => {
info.appName = "My Program";
return info;
});
const logger = winston.createLogger({
format: winston.format.combine(
addAppNameFormat(),
winston.format.json()
),
transports: [new winston.transports.Console()]
});
logger.warn('Danger Will Robinson!');
// {"message":"Danger Will Robinson!","level":"warn","appName":"My Program"}
答案 3 :(得分:3)
输出更像log4j(s)的另一个选项:
有一个(目前未记录的)标签' Console传输中的属性,它将向输出(json或line)添加标签:
var _ = require('lodash');
var winston = require('winston');
var path = require('path');
var baseDir = path.resolve(__dirname, '..');
// SETUP WINSTON LOGGER
var container = new winston.Container();
container.add("exception", {
console: {
handleExceptions: true,
timestamp: true,
label: "EXCEPTION",
colorize: true
}
});
container.get("exception").exitOnError = false;
var keys = [];
module.exports = function(filename) {
var label = path.relative(baseDir, filename);
if (!_.contains(keys, label)) {
container.add(label, {
console: {
handleExceptions: false,
level: 'debug',
timestamp: true,
label: label,
colorize: true
}
});
keys.push(label);
}
var logger = container.get(label);
logger.exitOnError = false;
return logger;
};
在其他模块中需要这样:
var logger = require('./logger')(__filename);
示例输出:
2014-07-23T07:05:27.770Z - info: [config/config.js] .......
答案 4 :(得分:2)
现在(19/8/20)有一个属性defaultMeta
传递给createLogger
,该属性将为每个日志注入您指定的元数据。
https://github.com/baronapp/cameo-microservices-sdk/pull/49
const logger = winston.createLogger({
level: 'info',
format: winston.format.json(),
defaultMeta: { service: 'user-service' },
transports: [
//
// - Write to all logs with level `info` and below to `combined.log`
// - Write all logs error (and below) to `error.log`.
//
new winston.transports.File({ filename: 'error.log', level: 'error' }),
new winston.transports.File({ filename: 'combined.log' })
]
});
答案 5 :(得分:0)
根据我在util-extend上阅读的内容,我找到了使用this blog的更好方法。它将在所有情况下附加数据,我发现这对于捕获logger.info vs logger.log(" info",message)非常有用,并且不会覆盖您的其他参数。
logger.log = function(){
var args = arguments;
var level = args[0];
var newArgs = {
foo: "bar",
baz: "abc"
};
var originalMeta = args[2] || {};
args[2] = extend(originalMeta, newArgs);
winston.Logger.prototype.log.apply(this,args);
};
将在控制台和日志中输出。