2024年4月15日月曜日

clojureプロジェクトで発生するslf4jの警告を消す


要約: 消すだけならslf4j-nopを、ログを出したいならslf4j-simpleなどをdepsに追加

下記のようにslf4j-nopライブラリ追加でログ取り処理は動かさないまま警告は消えます。
最新版はMavenのページで確認してください。
SLF4J NOP Provider - Maven Repository
deps.edn
{:deps {org.slf4j/slf4j-nop {:mvn/version "2.0.13"}}}

slf4j-simpleというライブラリを適用するとログが出ます。
最新版はMavenのページで確認してください。
SLF4J Simple Provider - Maven Repository
deps.edn
{:deps {org.slf4j/slf4j-simple {:mvn/version "2.0.13"}}}

logback-classicでもログを出せるらしいですが、classicと書かれているので試していません。

Javaのログ取りライブラリの脆弱性について2021年末頃に騒がれたのはlog4jというライブラリの2.15.0より前のバージョンです。
log4jとはslf4jとは別の呼び出し口ライブラリなので、今回のslf4jの利用とは関係ありません。(違ったら指摘していただけると嬉しいです。)
Mavenのページを見ると、記事を書いている時点での最新は2.31.1で、2.17.1以後は脆弱性が解消されているようなので、slf4jではなくlog4jを使う場合は脆弱性が無いとされているバージョンを使いましょう。

背景

clojureのライブラリでslf4j-apiに依存しているライブラリがあると、読み込みに失敗したという下記のような警告が実行時に表示されます。
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

上記の警告の2行目にある通りno-operation(何もしない)となっているので挙動に問題はありませんが、毎度目にして気になったので消す方法を調べて実施しました。
取り組んだ内容や関連情報を記事に残します。

使ったもの

slf4j-apiに依存するライブラリを利用するclojure-cliプロジェクト
自分が作っているログ取りサーバープログラムでは、フロントエンド側もバックエンド側もslf4j-apiに依存するライブラリがあり警告が出ていました。

clojure-cliのプロジェクトなら下記のコマンドで依存関係を表示できます。
clj -Stree

フロントエンドの依存抜粋
thheller/shadow-cljs 2.27.5
. io.methvin/directory-watcher 0.17.1
. org.slf4j/slf4j-api 1.7.36

バックエンドの依存抜粋
io.pedestal/pedestal.jetty 0.6.3
. io.pedestal/pedestal.log 0.6.3
. io.dropwizard.metrics/metrics-core 4.2.18
. org.slf4j/slf4j-api 1.7.36 :newer-version
X org.slf4j/slf4j-api 1.7.35 :superseded
. io.dropwizard.metrics/metrics-jmx 4.2.18
. org.slf4j/slf4j-api 1.7.36

slf4jとは? いくつかのログライブラリ共通の上書き・呼び出し口

Javaには複数のログ記録ライブラリがあるため、slf4jが対応しているライブラリなら呼び出しを共通化してライブラリの配置だけで機能を有効化できるようです。

参考:
SLF4J
SLF4J、Logback、Log4Jの関係を挙動とともに整理する

ログを取らないならslf4j-nopをdepsに追加

記事の冒頭でも紹介した通り、slf4j-nopをライブラリとして追加すればログを取らない挙動のまま依存先が無い警告が消えます。
deps.edn
{:deps {org.slf4j/slf4j-nop {:mvn/version "2.0.13"}}}
記事を書いている時点での最新版は2.0.13でしたが、使う場合はnopの最新をMavenのページで調べて適用してください。
SLF4J NOP Provider - Maven Repository

参考; Avoid SLF4J warnings

ログを取るなら該当するライブラリを追加

slf4j-simpleというライブラリを適用するとログが出ました。
最新版はMavenのページで確認してください。
SLF4J Simple Provider - Maven Repository
deps.edn
{:deps {org.slf4j/slf4j-simple {:mvn/version "2.0.13"}}}

それまでは下記のように警告が出ていた場所に、
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
in start-server 0.0.0.0:3000
server starts on http://0.0.0.0:3000

下記のような処理内容のログが表示されました。
in start-server 0.0.0.0:3000
[main] INFO org.eclipse.jetty.util.log - Logging initialized @20788ms to org.eclipse.jetty.util.log.Slf4jLog
[main] INFO org.eclipse.jetty.server.Server - jetty-9.4.53.v20231009; built: 2023-10-09T12:29:09.265Z; git: 27bde00a0b95a1d5bbee0eae7984f891d2d0f8c9; jvm 18.0.1.1+2-6
[main] INFO org.eclipse.jetty.server.handler.ContextHandler - Started o.e.j.s.ServletContextHandler@21e5ce58{/,null,AVAILABLE}
[main] INFO org.eclipse.jetty.server.AbstractConnector - Started ServerConnector@10acff2e{HTTP/1.1, (http/1.1, h2c)}{0.0.0.0:3000}
[main] INFO org.eclipse.jetty.server.Server - Started @20979ms
server starts on http://0.0.0.0:3000

logback-classicでもログを出せるらしいですが、ライブラリ名にclassicと書かれているので試していません。

参考:
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder"

脆弱性で騒がれたのはlog4jの2.15.0より前のバージョン: slf4jは無関係

2021年末頃に任意の処理を実行可能な脆弱性が見つかったと話題になったのはlog4jというslf4jとは別のログ呼び出し口ライブラリの2.15.0より前のバージョンです。
今回の記事で扱っているslf4jとは無関係です。(違ったら指摘していただけると嬉しいです。)

Mavenのlog4jのページを見ると、開発と調査が進み2.17.0以前のバージョンには脆弱性が含まれているようなので、slf4jではなくlogj4を利用する場合は新しいものを使いましょう。

参考:
2021年12月に公表されたLog4jの脆弱性について

おわり

slf4jの警告はライブラリとしてnopを指定すればログ表示も警告も無しに、simpleを指定すればログが表示されると分かりました。
また、脆弱性で騒がれたlog4jはslf4jとは無関係のログ取り処理呼び出し口と分かりました。

警告を消す方法を把握しつつ脆弱性とは無関係と分かって良かったです。

参考

nopやsimpleのライブラリの存在を知ったページです。
Avoid SLF4J warnings
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder"

nopとsimpleのMavenのページです。
SLF4J NOP Provider - Maven Repository
SLF4J Simple Provider - Maven Repository

脆弱性把握の参考にしたページです。
2021年12月に公表されたLog4jの脆弱性について
セキュリティ・ホットトピックス 元・Java専門記者がLog4j 2脆弱性に見た「複雑性と魔神のかけら」 Javaの歴史とバザールの矛盾
javaのログライブラリまとめ(slf4j, logback, log4j2)
SLF4JとLogbackは2023年末現在で積極採用していいよ

0 件のコメント :