node-bunyan
とは
Node.js で利用できるロガー。手軽に JSON 形式でログを出力できるのが特徴。サードパーティ製のプラグインを利用することで、CloudWatch Logs や DynamoDB 等の他のリソースにログの出力先を向けることも簡単にできる。 基本的な Log Method API
code:javascript
// 文字列/数値をログに出力
log.info('hi')
// util.format を使用してフォーマットしたメッセージをログに出力
const user = 'tasuwo'
log.info('hi %s', user)
// log レコードにマージするフィールドを第一引数に指定できる
log.info({foo: 'bar'}, 'hi');
// err フィールドを追加し、エラーの詳細情報をログに出力する
// msg には exception message が出力される
log.info(err)
ログストリームの設定
デフォルトでは、出力先は標準出力で、ログレベルは info になっている。これは、以下の設定でロガーを作成したのと同等。
code:javascript
var log = bunyan.createLogger({
name: 'myapp',
stream: process.stdout,
level: 'info'
});
アプリケーション内で、異なるレベルのストリームを複数定義することも可能。
code:javascript
var log = bunyan.createLogger({
name: 'myapp',
streams: [
{
level: 'info',
stream: process.stdout // log INFO and above to stdout
},
{
level: 'error',
path: '/var/tmp/myapp-error.log' // log ERROR and above to a file
}
]
});
Serializers
JavaScript のオブジェクトを JSON-able に変換するために、Serializer 機能を持っている。例えば、あるフィールド req に渡されたオブジェクトを、特定の方法で Serialize したい場合...
code:javascript
function reqSerializer(req) {
return {
method: req.method,
url: req.url,
headers: req.headers
};
}
var log = bunyan.createLogger({
name: 'my-home-skill',
serializers: {
req: reqSerializer
}
});
const sample = {
method: "test",
dummy: "dummy"
}
log.info({req: sample});
このとき、出力は以下のようになる。
code:json
{
"name": "my-home-skill",
"hostname": "ip-10-128-254-241",
"pid": 1,
"level": 30,
"req": {
"method": "test",
"headers": [
"hoge",
"fuga"
]
},
"msg": "",
"time": "2018-12-29T03:20:21.667Z",
"v": 0
}
Serializer を追加するタイミングは、logger の作成時でも作成後でもよい。
code:javascript
// 作成時
var log = bunyan.createLogger({
name: 'myapp',
serializers: {
foo: function fooSerializer(foo) { ... },
...
}
});
// 作成後
var log = bunyan.createLogger({name: 'myapp'});
log.addSerializers({req: reqSerializer});
Serializer 関数にはとくに保護されていないオブジェクトが渡されてくるため、場合によっては副作用を発生させてしまう。logger はこのようなことをすべきでない。適切な serializer 関数のために、いくつかのルールが提示されている。
Serializer 関数は、例外を投げてはいけない
例外が投げられると、bunyan により以下のような対処がなされる
stderr にメッセージがはかれる
ログレコードのフィールドに短いエラーメッセージが格納される
Serializer 関数は、受け取ったオブジェクトを変更してはいけない
アプリケーションにロガーが副作用を及ぼすことになってしまうため
Serializer 関数は、防御的にプログラミングすべき
渡ってくるオブジェクトは、null かもしれないし、undefined かもしれないし、全く想定していない型の値かもしれない
bunyan には標準で以下の Serializer が用意されている。
table:stdSerializers
フィールド 概要
err JS の Error オブジェクト用の Serializer。エラーの cause chain を格納する
req node.js の HTTP リクエストオブジェクト用の Serializer
res node.js の HTTP レスポンスオブジェクト用の Serializer
src フィールド
src フィールドを追加すると、ログ出力を行ったコード上の場所をログにはくことができる。ただ、これはアプリケーションが重くなるので、本番では使用すべきではない。
code:javascript
var log = bunyan.createLogger({src: true, ...});
code:json
{
"name": "src-example",
"hostname": "banana.local",
"pid": 123,
"component": "wuzzle",
"level": 4,
"msg": "This wuzzle is woosey.",
"time": "2012-02-06T04:19:35.605Z",
"src": {
"file": "/Users/trentm/tm/node-bunyan/examples/src.js",
"line": 20,
"func": "Wuzzle.woos"
},
"v": 0
}
ログレベル
table:logLevel
レベル ナンバー 概要
fatal 60 サービス/アプリが停止/利用できない状態。オペレータは真っ先に確認すべき
error 50 要求は失敗したが、サービス/アプリはまだ他の要求を捌ける状態。オペレータは早めに確認すべき
warn 40 オペレータが最終的には確認すべき事項
info 30 通常の操作に対する詳細
debug 20 その他。例えば、info レベルに含めるには冗長な情報等
trace 10 アプリケーションから利用している外部ライブラリのログ等、かなり詳細な情報
設定の変更方法
code:javascript
// 現在のレベルの取得
log.level()
// 全てのストリームのログレベルを INFO にする
log.level(INFO)
// ストリーム名 foo を WARN レベルにする
log.levels("foo", WARN)