Node.jsでロギングに Winston を使用しています。各ログメッセージに個別にメタデータを追加できることは知っていますが、毎回指定したくないので、すべてのログメッセージ(アプリ名など)に追加されるメタデータのデフォルトセットを指定する方法はありますか?ログメッセージを送信する必要があります。
これを行うための組み込みの方法はありませんが、自分で追加することはできます。方法は次のとおりです。
まず、通常どおりにロガーを設定します。例えば:
_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モジュールの代わりにloggerモジュールをインポートします。
var logger = require('./logger.js');
お役に立てば幸いです。
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*/
]
});
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"}
現在(8/20/19)defaultMeta
に渡されるプロパティcreateLogger
があり、指定したメタをすべてのログに挿入します。
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' })
]
});
Log4j(s)のような出力を持つ別のオプション:
コンソールトランスポートには(現在文書化されていない) 'label'プロパティがあり、出力(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] .......
このブログ で読んだ内容に基づいて、 til-extend を使用するより良い方法を見つけました。すべての場合にデータが追加されます。これは、logger.infoと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);
};
コンソールとログに出力されます。