Kengo's blog

Technical articles about original projects, JVM, Static Analysis and TypeScript.

SLF4JとLogbackは2023年末現在で積極採用していいよ

2年前のブログが未だにブクマされるので、念のため掲題の件について書いておきます。 端的に書くと、あのブログで挙げた懸念事項が解消されたのでどんどん使うと良いと思います。

SLF4J v2の安定版がリリースされた

良かったですね。ちなみにv2.0.9から slf4j.provider プロパティでproviderを指定できるようになったので、Service Loaderによるprovider探索をガツッとスキップできます。多くのユースケースでは利用したほうがログの単純化や起動の高速化に有効のはずです。

SLF4Jの活動は最近活発

JIRAのデータを見れば一目瞭然。私もGitHub Issueで回答に回ったりしますが、著者の方も頻繁にコメントしてくれてます。最近のLogbackの脆弱性への対応も充分に早かったのではないでしょうか。

図1 2023年の活動状況。緑の線が6ヶ月近く右肩上がりなのに注目。
図2 比較用に前回のブログに貼ったやつ。緑の線がほぼ横ばい。

ということで、好きにすればいいと思います。もちろんLog4j2も適材適所でどんどん使っていきましょう。

おまけ:依存を小さくするためという誘惑に負けずにSLF4J使っとけ、という話

SLF4Jを使ったソフトウェアを配布される方、最近なかのひとがこちらの投稿をされていたのでご参考まで。

ChatGPTによる要約を掲載しておきます。なおここで言うoptional dependencyとはMavenで言う <optional>true</optional> な依存のことではなく、独自のログAPIを提供したうえでクラスパスにSLF4JがいるかどうかによってそのAPIの挙動を変える書き方を想定していると思われます。

このテキストでは、ソフトウェアプロジェクトがロギング戦略を考える際に、SLF4Jを任意の依存関係にすることについて議論しています。SLF4JをWombatというライブラリの依存関係に加えることは、新しい依存関係を生み出します。一部の開発者はSLF4Jのラッパーを作成して、SLF4Jを任意の依存関係にすることを検討するかもしれません。しかし、このラッパーは将来的な変更に対して複雑さを増すだけでなく、SLF4Jの内部インターフェースに依存するため、メジャーバージョンによる互換性の問題が生じる可能性があります。さらに、各ライブラリが独自のロギングラッパーを持つと、ユーザーは複数のロギングフレームワークを扱う必要があり、これは利用者にとって煩わしいことです。そのため、開発者は独自のロギングラッパーを書くことに抵抗すべきです。

私は最近gRPCを使うんですが、あれはJUL(java.util.logging)のロガーに依存しているので、jul-to-slf4j とかいうおまじないを強制されるんですよね。こんな感じのコードを main() 直後に埋めて回る必要があるわけです:

// io.grpc がJULを使っているため、JULがSLF4Jを経由してLogbackに送るようにする
SLF4JBridgeHandler.removeHandlersForRootLogger()
SLF4JBridgeHandler.install()

Java標準APIでさえこれなのに、配布ソフトウェアが独自のログAPIを提供していたらもっとめんどくさいだろうなというのは想像できます。JVM世界でコードを書くなら難しいことを考えずにSLF4Jに乗っとくくらいがちょうどよいのは実際そうでしょう*1

*1:NodeJS書いてるとまともなロギングファサードのあるJVM世界がすごい羨ましくなるやつ