Javaのログ出力ライブラリの選び方
あいさつに代えて
先日、デブサミ2024に行ってきました。4年ぶりのオフライン開催で、行く前は「どんな感じになるのかな」だったのですが、会場に着いたら「昔と変わらないな」になりました。
今回の画像は、会場のベルサール羽田空港がある「羽田エアポートガーデン」の1階から外に出た所で撮影した空です。
Javaのログ出力ライブラリ、どれを選べば良い?
運用を意識したログを出力する様に設計して、いざJavaでプロダクト実装!となった際には、ログ出力ライブラリを選ぶことになります。
今現在(2024年)であれば、「Apache Log4j2」か「SLF4J+Logback」のいずれかを選ぶと思います。
ここで実装のコードを全て自分たちで書くのであれば、悩むことは無いのですが、、、実際はそんなことは無く、外部ライブラリ(他社提供のライブラリやOSSライブラリ)を利用することになります。
この場合、外部ライブラリが利用するログ出力ライブラリから、プロダクトで利用するログ出力ライブラリに対してログを出力する為にはどれを選べば良いか、混乱する事があると思います。
今回は、ログ出力ライブラリを整理して、どの様に選べば良いかをまとめたいと思います。
ログ出力ライブラリを「ログAPI」「ログ実装」「APIと実装の関係」の切り口で整理
まずは、よく使われるJavaのログ出力ライブラリを「ログAPI」「ログ実装」と「APIと実装の分離」の切り口で整理したいと思います。
Apache Log4j2
ログAPI:あり
ログ実装:あり
APIと実装の関係:分離
Apache Software Foundation(ASF)から提供されるフレームワークです。
ログAPI・ログ実装共に提供されています。
APIと実装は分離されています。
SLF4J(Simple Logging Facade for Java)
ログAPI:あり
ログ実装:実質なし(簡易な実装のみ)
APIと実装の関係:分離
スイスのQOS.chから提供されるフレームワークです。
ログAPIのみを提供する事に注力している為、ログ実装は実質ありません(一応簡易な実装slf4j-simpleは提供されています)。
APIと実装は分離されています。
Logback
ログAPI:なし(SLF4Jを利用)
ログ実装:あり
スイスのQOS.chから提供されるフレームワークです。
ログ実装のみの提供です。ログAPIはSLF4Jを利用します。
reload4j ← Apache Log4j1
ログAPI:あり
ログ実装:あり
APIと実装の関係:一体化
Apache Log4j1は、ASFから提供されていたフレームワークでしたが、2015/8/5にサポート終了となりました。セキュリティ問題に対応する為、最終バージョン(1.2.17)のソースをフォークしたのが、スイスのQOS.chから提供されるreload4jです。
ログAPI・ログ実装共に提供されています。
APIと実装は一体化されていて分離できません。
Apache Commons Logging(JCL)
ログAPI:あり
ログ実装:実質なし(簡易な実装のみ)
APIと実装の関係:分離(簡易な実装は一体化)
ASFから提供されるフレームワークです。昔Jakarta Commons Loggingと呼ばれていた為、JCLと略される事があります。
他のログ実装を使う事を想定していますので、ログ実装は実質ありません(一応簡易な実装SimpleLogは提供されています)。
APIと実装は分離されていますが、簡易な実装は一体化しています。
Java Logging API(JUL)
ログAPI:あり
ログ実装:あり
APIと実装の関係:一体化(別実装の利用可)
JavaSEでバージョン1.4から提供されています。パッケージ名のjava.util.loggingからJULと略される事があります。
ログAPI・ログ実装共に提供されています。
APIと実装は一体化されていて分離できませんが、設定により別実装の利用が可能です。
このパッケージはjava.loggingモジュールで提供されますので、必要なモジュールのみ含まれたJREでは利用できない可能性があります。
JDK Platform Logging
ログAPI:あり
ログ実装:実質なし(簡易な実装のみ)
APIと実装の関係:分離(簡易な実装は一体化)
JavaSEでバージョン9から提供されています。java.baseモジュールで提供されますので、全てのJREで利用できます。
他のログ実装を使う事を想定していますので、ログ実装は実質ありません(一応簡易な実装は提供されています)。
APIと実装は分離されていますが、簡易な実装は一体化しています。
ログ出力ライブラリの選び方
では、ログ出力ライブラリの選び方を書いていきます。
なお、これは私の選び方なので違う意見の方もいるとは思いますが、その辺はご容赦下さい。
どの「ログ実装」に出力するか決める
まず、どの「ログ実装」に出力したいか決めます。
「ログ実装」を持つログ出力ライブラリとして2024年現在サポートされているものは、「Apache Log4j2」「Logback」「reload4j」「Java Logging API」の4つです。
この内、「Java Logging API」は一般的なログレベルと異なる為、よほどの事が無い限り選びません。また、「reload4j」は基本的には脆弱性対応で大きな機能追加はありませんので、積極的には選びません。
となると、残りは「Apache Log4j2」「Logback」のどちらかになりますが、、、正直どちらを選んでも問題ありません。
外部ライブラリが利用する「ログAPI」が「SLF4J」を多く利用している場合、「Logback」を選んだ方が良いと思います。
「ログAPI」と「ログ実装」を繋ぐ
「ログ実装」でログ出力ライブラリが決まったら、プロダクトや外部ライブラリが利用する「ログAPI」と「ログ実装」を繋ぐ様に選びます。
ライブラリの指定方法は、Gradleでの記述です。
「ログ実装」に「Apache Log4j2」を使う
共通:'org.apache.logging.log4j:log4j-core:{Log4j2のバージョン}'を追加
「ログAPI」が「Apache Log4j2」の場合:'org.apache.logging.log4j:log4j-api:{Log4j2のバージョン}'を追加
「ログAPI」が「SLF4J」バージョン1.7.*の場合:'org.slf4j:slf4j-api:{SLF4Jのバージョン}'と'org.apache.logging.log4j:log4j-slf4j-impl:{Log4j2のバージョン}'を追加
「ログAPI」が「SLF4J」バージョン2.0.*の場合:'org.slf4j:slf4j-api:{SLF4Jのバージョン}'と'org.apache.logging.log4j:log4j-slf4j2-impl:{Log4j2のバージョン}'を追加
「ログAPI」が「reload4j」「Apache Log4j1」の場合:'org.apache.logging.log4j:log4j-1.2-api:{Log4j2のバージョン}'を追加
「ログAPI」が「Apache Commons Logging」の場合:'org.apache.logging.log4j:log4j-api:{Log4j2のバージョン}'と'commons-logging:commons-logging:1.3.0'を追加
「ログAPI」が「Java Logging API」の場合:'org.apache.logging.log4j:log4j-jul:{Log4j2のバージョン}'を追加して、設定を追加
「ログAPI」が「JDK Platform Logging」の場合:'org.apache.logging.log4j:log4j-jpl:{Log4j2のバージョン}'を追加して、実行にはJava11以降を使用
「ログ実装」に「Logback」を使う
共通:'org.slf4j:slf4j-api:{SLF4Jのバージョン}'と'ch.qos.logback:logback-classic:{Logbackのバージョン}'を追加
「ログAPI」が「Apache Log4j2」の場合:'org.apache.logging.log4j:log4j-api:{Log4j2のバージョン}'と'org.apache.logging.log4j:log4j-to-slf4j:{Log4j2のバージョン}'を追加
「ログAPI」が「SLF4J」の場合:なし
「ログAPI」が「reload4j」「Apache Log4j1」の場合:'org.slf4j:log4j-over-slf4j:{SLF4Jのバージョン}'を追加
「ログAPI」が「Apache Commons Logging」の場合:'commons-logging:commons-logging:1.3.0'を追加
「ログAPI」が「Java Logging API」の場合:'org.slf4j:jul-to-slf4j:{SLF4Jのバージョン}'を追加して、設定を追加
「ログAPI」が「JDK Platform Logging」の場合:'org.slf4j:slf4j-jdk-platform-logging:{SLF4Jのバージョン}'を追加して、実行にはJava9以降を使用
おまけ:Apache Commons Logging バージョン1.3.0について
2023/12/3に、Java8以降に対応したバージョン1.3.0がリリースされました。バージョン1.2が2014/7/11なので、9年以上経ってのリリースですね。
変更点はこちらになりますが、主な変更は次の通りです。
サポートするJavaのバージョンが8以降に更新
Apache Log4j1のサポートが非推奨に、利用には設定の追加が必要
Apache Log4j2 API・SLF4Jの標準サポート