LoginSignup
50
47

More than 5 years have passed since last update.

Javaのロガーの種類が多すぎ、一元化したい

Last updated at Posted at 2013-05-16

Java のロガーってたくさんありますね。Guavajava.util.logging.Logger を使ってますし、Spring Framework や Apache 関連のライブラリは Apache Commons Logging を使っています。パッと用例が出て来ませんが、Log4J や、SLF4J もあります。

まとめると有名所だけでも、これだけあります:

うんざりですね。

これらを依存ライブラリがバラバラに使っていると、ログレベルごとの出力制御が一元化できなかったり、ログフォーマットのバラツキが発生しやすくなり、つらいです。

上に上がっている SLF4J には、これらの出力をブリッジして1つにまとめることのができるモジュールがあります。

この記事ではこれらのモジュールについて簡単にメモします。

ここに書いてあることは、基本的には Log4j Bridge を見れば全て書いてありますので詳しく知りたい方は参照してください。

これを書くにあたり、以下のようなサンプルを作りました:

それぞれをブリッジしてくれるライブラリ

以下のようになっています:

XXX-over-sjf4j に関しては、maven の依存関係や、クラスパスに追加すれば自動的にブリッジしてくれるようになります。ただし、他の依存関係によって読み込んでいる commons-logginglog4jexclude しないと 予期しない挙動を起こす可能性があります。

jul-to-slf4j は他の2つと違い、ブリッジの実装が違うため、使い方も少し手間が必要になります。

jul-to-slf4j によるブリッジ実現方法

SLF4JBridgeHandler の javadoc にも書いてありますが、java.util.logging.Logger の出力をブリッジするには以下のようなメソッドの呼び出しが必要になります:

SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

サンプルではこう書きました。

これ以降は、java.util.logging.Logger 自身の出力は抑制され(一行目)、代わりに SLF4J がログをとってくれるようになります(二行目)。

ただし、上記した Log4j Bridge も書いてあるとおり注意が必要になります。

jul-to-slf4j の注意点

端的に言うと、ブリッジのオーバーヘッドがあまりにも大きいようです。

これに関しては、Log4j Bridge の jul-to-slf4j の "Note on performance" に書いてあります:

Consequently, j.u.l. to SLF4J translation can seriously increase the cost of disabled logging statements (60 fold or 6000%) and measurably impact the performance of enabled log statements (20% overall increase).

対策としては、logback.xml に以下のようなリスナーを追加すると、オーバーヘッドを軽減できるようです:

<configuration>
  <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
    <resetJUL>true</resetJUL>
  </contextListener>
  ...
</configuration>

サンプルではこう書きました。

以上です。おわり。

50
47
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
50
47