winstonでのエラーログにエラーメッセージを含める
winstonでエラーをロギングするときに発生する問題
以下のようにwinstonのloggerを用意したとします。
const winston = require('winston'); const logger = winston.createLogger({ level: 'info', format: winston.format.json(), transports: [ new winston.transports.Console(), ], });
そして以下のような文を実行します。
logger.info('something has happened');
結果は想像の通り、以下のようになります。
{"message":"something has happened","level":"info"}
しかし、以下の場合はどうでしょう。
logger.error(new Error('something has happened'));
このような出力になり、スタックの内容やエラーメッセージは表示されません。
{"level":"error"}
解決策
そこで、loggerの定義を拡張して以下のようにします。
loggerに渡されたオブジェクト(iとしています)がErrorオブジェクトのインスタンスだった場合に、i.messageの内容をログ出力のmessageとして設定するようにしています。
const logger = winston.createLogger({ level: 'info', format: winston.format.combine( winston.format((i) => { if (i instanceof Error) { return Object.assign({}, i, { message: i.message, }); } return i; })(), winston.format.json(), ), transports: [ new winston.transports.Console(), ] });
さきほどと同じ文を実行すると以下のような出力となり、うまくいっていることがわかります。
{"level":"error","message":"something has happened"}
stackなど、Errorオブジェクトの他のプロパティに関しても、同じようにして追加することができるはずです。
おまけ
winstonのloggerは、オブジェクトを渡されたとき、列挙可能なプロパティ(とそれに対応する値)のみをログに含めるようです。Errorオブジェクトのmessageプロパティややstackプロパティは列挙可能ではないので、このようなことになっているみたいです。
※ 執筆時のwinstonのバージョンは3.2.1です。