ApacheがLog4jバージョン1のサポートを終了すると発表した。2014年7月にバージョン2をリリース済みだが,バージョン1も2015年8月初めまでメンテナンスされていたのだ。新バージョンではログライブラリが完全に書き直された他,バージョン1にあった多くの問題に対処し,前例のないパフォーマンスを実現している。Apacheはアップグレードを容易にするための努力を続けているが,上級ユーザはマイグレーション作業が必要になる場合もある。
Apacheが報告しているように,1999年にリリースされたロギングフレームワークであるLog4jバージョン1には,アーキテクチャ的な問題やリリースプロセスの不備が数多くあり,開発を比較的難しいものにしていた。このことがLog4jをメンテナンスするコミュニティ開発者の動機となり,フレームワークという範囲を離れたLogbackのような他のプロジェクトの開発が始まると同時に,ユーザの同じような行動をも助長していた。このためApacheは,バージョン1の欠点を克服してコミュニティベースを回復すべく,バージョン2をスクラッチから開発することを決定したのだ。
Log4jバージョン2のメリットにも関わらず,その採用はあまり進んでいない。 Maven Centralでの統計によると,本記事の時点でLog4jバージョン2を使用するアーティファクトが350程度であるのに対して,バージョン1は6,000近くに達している。これに比較して,Logbackを使用するアーティファクトの数は5,000を超えている。
この事態を克服するためにApacheは,アップグレードパスを可能な限り簡単にする作業に取り組んできた。SLF4Jなど,ロギングファサード経由でLog4jが使用されるケースでのアップグレードは,バインドされているjarファイルのslf4j-log4j12からlog4j-slf4j-impl-2.0への変更,Log4jバージョン1の参照をすべて削除,バージョン2用の実装jarファイルの追加,というステップになる。Log4jを直接使用している場合は,まずApacheのマイグレーションガイドを参照する必要がある。ガイドには,すべてのコールを新しいAPIに変更する方法と,Log4jバージョン1内のインフラストラクチャに対するコールをすべてキャプチャして,Log4jバージョン2に転送するブリッジ用jarファイルを使用する方法の2つが紹介されている。
AppenderやFilterなどを自分自身で定義しているユーザは,残念ながらブリッジファイルを使うことはできない。Log4jバージョン2でこれらの動作が変更されているからだ。例えばAppenderを独自に定義する場合,バージョン1ではAppenderSkeletonを拡張して,継承するメソッドを実装する必要があった。しかしバージョン2では,プラグインとして作成したものを登録する方法になっている。変換作業が必要なことを考えると,このような状況であれば,新バージョンに完全移行する方がよい選択かも知れない。
その一方で,推移従属性(transitive dependency)に注目するユーザは,バージョン2の追加段階で意外な事実を見つけることだろう。一部のユーザが報告しているように,ロギングフレームワークの新バージョンでは,最大で30ほどの直接的な依存関係が導入される可能性がある。ところが,さらに調査を進めると,大部分がテストスコープあるいはオプションに関するものだと分かる。つまり,実行環境に追加が必要な本当のフットプリントは,実は2つの直接的な参照だけなのだ。
よりシンプルな代替策
ごく基本的なログ機能が必要なユーザは,ロギングフレームワークの選択やアップグレードの対処に悩まされることはないだろう。Java 4(1.4)以降には,java.util.loggingパッケージの一部としてログ機能が含まれているからだ。Log4jやLogbackなどのライブラリほど効率的ではなく,機能面でも遅れているが,標準的なOpenJDKに含まれているという事実によって,ほとんどのケースに適した選択肢となる。