Log4j 2(※Log4jのver.2)が2014年7月にリリースされました。本記事執筆時点(※2014年12月)で2.1が最新です。
最後発となるLog4j 2は、SLF4J w/ Logbackが提供しているAPIや機能のほとんどを継承しつつ、さらなる機能追加や性能の向上を図っています。Apache Foundationとしてロギングフレームワークの実装を改めてラインナップに加えることができた、という意味もあるのでしょう。Log4j 2はSLF4J w/ Logbackの後継として主流の地位を得ることとなるかどうかは未知数ですが、内容的には素直に「SLF4J/Logbackの拡張版」と捉えていいと思いました。
■ Log4j 2の機能
気になった機能を列挙します。(※ここに挙げる機能はLog4j 1.xやLogbackで既に実現されているものも含んでいます。Log4j 1.x〜SLF4J/Logback〜Log4j 2の系譜の最新状況を復習も兼ねつつ押さえておく、と捉えてください。)
非同期処理
Logger#debug/info/errorメソッド等呼び出し後直ちにリターンして、実際のログ出力処理は別スレッドで行うように構成できます。これでアプリケーション本体側のパフォーマンスが劇的に向上する、とのことです。
"Asynchronous Loggers for Low-Latency Logging":
MapMessage
Stringだけでなく、Map構造を持つMapMessageがサポートされました。PatternLayoutでMapMessageの要素を個別に参照する事ができます。
他にも様々な機能性をもったMessageの実装が用意されています。独自の実装も容易に追加できそうです。
ThreadContext
ロギングするとき"5W1H"情報を添えるのが常套かと思いますが、その"5W1H"情報を保持するための仕組みとして利用できるThreadContextが提供されています。ThreadLocalをラップした実装のようです。ThreadContextクラス一つでMap構造とStack構造をサポートしています。ThreadContextにセットした情報はPatternLayoutで個別に参照できます。
"Thread Context":
PatternLayout
Patternを指定することで任意の表現ができます。前述のとおりMapMessageやThreadContextの内容を参照する事もできます。
"PatternLayout":
JSONLayout
JSONLayoutを用いると、ログレコードをJSON形式の(半)構造化データとして出力する事ができます。
※が、ぐるぐるせんせいによると使い勝手に難がある様子です。MapMessageとJSONLayoutを組み合わせれば非常に簡易に(半)構造化データでのロギングが実現できるとも思われますが、少なくとも2.0時点ではうまくいかないようです。2.1でどうかは筆者は未確認です。
CouchDB、MongoDBをAppenderに使用できる
NoSQLAppenderなるAppenderが用意されています。具体的には現時点ではCouchDBとMongoDBがサポートされているとのことです。
※(半)構造化データでのロギング目的としてはこちらが本命かもしれません。
"NoSQLAppender":
多彩なFilter
Appender、Loggerに対してFilterを設定できます。Filterには下記のようなものが用意されています。(※主だったもの)
ThresholdFilter ... ログのLevelRegexFilter ... ログのMessageテキストに対して正規表現マッチMapFilter ... MapMessageの項目の値ThreadContextMapFilter ... ThreadContextの項目の値
設定ファイル内でPropertyが扱える
設定ファイルは新しい"log4j2.xml"となります。"log4j2.xml"では、Propertyを定義し別の箇所で参照する書き方ができます。例えば、PatternLayoutのpatternをPropertyで定義しておいて、Console AppenderとFile Appenderそれぞれで定義されたパターンを参照する書き方ができます。別の例としては、、複数のFile Appenderの出力先ファイルパスの共通ベース部分を、Propertyとして外出し定義することができます。
"Property Substitution":
■ 1.xとの互換性
packageが変更、クラスとメソッドは“ほぼ”互換
Java APIとしてはpackageが異なっています。Loggerのインスタンス取得の手順まわりに多少変更があります。Logger#debug/info/error等のログ出力メソッドは完全に上位互換です。それ以外もsemanticsが変わる程のAPI変更は無いので、書き換えが必要でも機械的な対応で済むと思います。
設定ファイルが"log4j.xml"から"log4j2.xml"に変更となります。syntaxも変更されていて互換性はありません。全般に実装クラスのフルネームを書かなくて済むようになっています。(※専用のXMLの要素名で表されます。"log4j2.xml"を定義するようなXML Schemaは存在せず、記述に自由度があります。)しかしこちらもsemanticsが変わる程ではないので、機械的な書き換えで済むでしょう。(※XSLTでいけるかもしれません。)
"Configuration":
1.2 to 2 Bridgeの提供
前述のように、Log4j 1.2 to 2のブリッジ実装が提供されています。これを用いれば、Javaのソースコードは1.x系のAPIを用いたままでも、実装をLog4j 2に差し替えられます。サードパーティ製のプログラムでソースコードに手が入れられない場合でも、1.x系の.jarファイルを削除して、1.2 to 2 Bridgeの.jarファイルを配置すれば、実装を差し替えることができます。差し替えられた実装はもちろん"log4j2.xml"を必要とします。"log4j.xml"があっても読みません。
1. 対象のプロジェクトに対して下記コマンドを適用してLog4j 1.xの存在をチェックします。
mvn dependency:tree
2. Log4j 1.xの存在が確認されたら、そのLog4j 1.xに依存しているサブプロジェクトについての指定に、Log4j 1.xについての 指定を追記します。
Maven、"Dependency Exclusions":
http://maven.apache.org/guides/introduction/introduction-to-optional-and-excludes-dependencies.html#Dependency_Exclusions
3. 「2.」の後、再度「 mvn dependency:tree 」を実施します。すると別のサブプロジェクトにLog4j 1.xへの依存が見出されることがあります。そうしたら、そのサブプロジェクトについても「2.」を実施します。以上をLog4j 1.xが出現しなくなるまで繰り返します。
■ 注意点
.jarファイルが細かく分かれている
必要な機能によって必要な.jarファイルが分かれています。主だったものを下記にまとめました。
*1:Web App.サポートの.jarは実行時のみ必要、コンパイル時は不要です。「Web App.サポート」については次項を参照してください。
機能 group id artifact id version scope 必須(I/F) org.apache.logging.log4j log4j-api 2.1 必須(Impl.) org.apache.logging.log4j log4j-core 2.1 Web App.サポート(*1) org.apache.logging.log4j log4j-web 2.1 runtime Log4j 1.2 to 2 Bridge org.apache.logging.log4j log4j-1.2-api 2.1 NoSQL Appender(*2) org.apache.logging.log4j log4j-nosql 2.1
*2:NoSQL Appenderを用いる場合は、他にCouchDBやMongoDBのドライバーが必要です。
"NoSQL Appenders":
http://logging.apache.org/log4j/2.x/log4j-nosql/index.html
他詳細は下記ページを参照してください。
"Maven, Ivy, and Gradle Artifacts":
※一番重要です!
Log4j 2の基本機能では、File Appenderなど外部資源を使用しているとき、アプリケーションのプロセス起動時にそれらの初期化が行われ、停止時に開放が行われます。ところでWebアプリケーションでは、一般にWebアプリが配置されているアプリケーションサーバーのプロセスを起動/停止することなく、Webアプリのdeploy/undeploy、startup/shutdownが行われます。このとき、Log4jの基本機能では外部資源の管理オブジェクトがリークしたりファイルのflushがなされず一部データが失われる等の可能性があります。
これらを避ける為の対応コードが「Web App.サポート」("log4j-web-2.x.jar")として提供されています。"log4j-web-2.x.jar"は実行時にWebアプリの.warファイル等に含まれていればよく、コンパイル時には不要です。
「Web App.サポート」を利用するためにアプリケーションのソースコードの書き換えは不要です。Servlet 2.5では"web.xml"への設定追記が必要です。Servlet 3.0では"log4j-web-2.x.jar"さえ存在すれば"web.xml"の設定追記も不要です。「Web App.サポート」はServlet 2.5以上をサポートします。Servlet 2.4以下はサポート対象外です。
"Using Log4j 2 in Web Applications":
◆以上
関連記事