slf4j経由のlog4j2でJSONログを出力する方法
log4j2でJSONログを出力する方法
以下の手順が必要
詳しい話はドキュメントに書いてあるが、デフォルトでtemplateを持っているようなので、そちらを使うことも可能なようだ。
https://logging.apache.org/log4j/2.x/manual/json-template-layout.html
log4j2で特定のログでのみフィールドを生やす方法
JSONのテンプレートを変更することなく、JSONログのフィールドを増やしたい場合、slf4j経由で行う場合、以下の2つのアプローチが考えられる。
- org.slf4j.MDC経由で追加する
- slf4jのfluent API経由で追加する
これらのアプローチを使えば、特定のログでのみフィールドを生やすことができる。
しかし、フィールドとして以下のようなネストしたオブジェクトを設定したい場合は注意が必要である。
{ "some": { // someを特定のログでだけ生やしたい "object": { "key": "value" } } }
前者のMDCの場合は、API的に MDC#put(String, String)
になるので、Object型は渡せないので、HashMapのようなネストしたオブジェクトを渡せない。
後者のfluent APIの場合は、LoggingEventBuilder#addKeyValue(String, Object)
になるので、ネストしたオブジェクトを渡せそうに見える。
が、log4j2の実装では、以下の箇所でString.valueOf(value)といったように、Stringに変換しているため、生やすことができるフィールドはStringのみのようだ。
log4j2のAPIも一応見たが、org.apache.logging.log4j.CloseableThreadContext
や org.apache.logging.log4j.ThreadContext
のAPIは keyもvalueもStringを要求するインターフェースになっており
ネストしたオブジェクトを渡せない。
渡せる方法があったら教えてほしい・・・。
logstash-logback-encoder
のように、logger.info("message", entries(map));
みたいなAPIがあると嬉しかったのだが・・・。
log4j2のLayoutをカスタマイズすれば、ネストしたオブジェクトも生やせるとは思うが
そこまでするなら、logback
で logstash-logback-encoder
を使えば良さそうである。