Log4j 2を使った。おまけで他のloggingも用意した。

はじめに


今はRails使いですが、数年前まではJava使いでした。
何やらlog4jがメジャーバージョンアップ始めたという噂を聞いたので試してみました。
因みに、自分が最後に使っていたのは「slf4j + logback」です。

コード類


コードはgithubに置きました。
どれも必要最低限のライブラリしか使っていませんので、動作の参考になるかと思います。

特にivy, maven, gradleを使うと必要以上のライブラリまで取ってくるので、解決に困っている方がいれば役立つかも・・・

# 自分が偶に忘れるなんてことは言えない・・・

log4j 2.x


本家曰く、何やらこんなことが増えたらしい。

  • APIの分離
  • パフォーマンス(性能)改良
  • multiple API(commons-logging, slf4j)のサポート
  • 設定の自動リロード
  • logbackライクなFilter設定
  • plugin機構の追加

後は、地味に細かい改良があったりします。。。

セットアップ


ライブラリ(2013/12/22時点)は、以下のものがあればよいようです。

  • log4j-api-2.0-beta9.jar
  • log4j-core-2.0-beta9.jar

slf4jと連携させたいときは、以下を追加します。

  • log4j-slf4j-impl-2.0-beta9.jar
  • slf4j-api.1.7.5.jar

Gradleだとこんな感じですね。(transitiveをつけるのは余計なライブラリをダウンロードさせないため)

1
2
3
4
5
6
dependencies {
    compile ('org.apache.logging.log4j:log4j-core:2.0-beta9') {transitive = false}
    compile ('org.apache.logging.log4j:log4j-api:2.0-beta9') {transitive = false}
    compile ('org.apache.logging.log4j:log4j-slf4j-impl:2.0-beta9') {transitive = false}
    compile ('org.slf4j:slf4j-api:1.7.5') {transitive = false}
}

このあたりを参考にするといいかも

設定ファイルの置き場ですが、こちらは「クラスパス」が通ったところに置けばよいでしょう。
# eclipseとかだとsrcの直下の置けばよいです。

因みに、この設定ファイルですが以下に変更となったようです。

  • log4j2.xmlもしくはlog4j2.jsonのどちらかを設定ファイルとする
  • propertiesファイルでは記載できなくなった
  • ファイル名の規則が「log4j2」になった

# Javaの特徴という感じだったのでプロパティファイル結構好きだったんだけどなぁ(日本語書くとアレなのは置いておいて)
# 複雑なことは書けないという致命傷もあったので、設定が複雑なことには向かなかったというのも分かる
# jsonのサポートは今風かも。

ログの設定にjsonを使う場合は、以下のライブラリを追加する必要があるようです。

  • jackson-core-2.2.2.jar
  • jackson-databind-2.2.2.jar

設定


ログって基本、一度設定してしまうと何か特別な理由が無い限り設定変更ってしませんよね。
# ログ分析が必要になったとか、ログレベルの変更をする必要が出たとか

  • デフォルトはERRORとFATALのみ表示(ログレベルは、FATAL > ERROR> WARN > INFO > DEBUG > TRACE)
  • 指定できる出力フォーマット
  • appenderは、コンソールやファイルの出力するフォーマット定義
  • loggersは、どのappendersを使うかを指定することでログの出力方式を決定できます
  • 最低限、appenderとloggersを設定すれば動きます。

以下のような感じでlog4j2.xmlを設定します。

  • Consoleとログファイルの両方にログを出力するようにしています
  • ログファイルの出力は、JSONを設定しています
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="OFF">
  <appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout>
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</pattern>
      </PatternLayout>
    </Console>

    <RollingFile name="RollingFile" fileName="log4j2_sample_log.log" filePattern="log4j2_sample_log_%d{yyyy-MM-dd}.log.gz">
      <JSONLayout complete="true" charset="UTF-8" />
      <Policies>
        <TimeBasedTriggeringPolicy />
      </Policies>
    </RollingFile>
  </appenders>

  <loggers>
    <root level="trace">
      <appender-ref ref="Console" />
      <appender-ref ref="RollingFile" />
    </root>
  </loggers>
    
</configuration>

他にも出来そうなこと

  • 「<property name="LOG_PATH" value="" />」のように定義することもできるような感じなので柔軟に出来そうですね。
  • appenderを追加すれば、状況に応じたログ出力が出来そう(普通のログとJSONのログ等)
  • JSONでログ出力すれば、ログの分析がしやすそう(分析基盤(Fluentdとか)を使ったり作ればですが)

おまけ(その1)


いつもSLF4jを使用するときの組み合わせを忘れるので、ここにメモします。 SLF4jはFacadeパターンを採っていまして、以下のメリットがあるようです。

  • 柔軟な切り替え
  • 効率化

これのお陰で、移行とかがスムーズにできるというわけです。 以下の表に組み合わせをメモしておきます。

Log4j Log4j2 Logback Logging Simple
SLF4J/コア slf4j-api.jar slf4j-api.jar slf4j-api.jar slf4j-api.jar slf4j-api.jar
SLF4J/アダブタ slf4j-log4j12.jar log4j-slf4j-impl logback-classic.jar, logback-core.jar slf4j-jdk14.jar slf4j-simple.jar
ロギング・ライブラリ log4j-1.2.x.jar log4j-core, log4j-api logback-classic.jar, logback-core.jar java.util.logging slf4j-simple.jar

# どちらかと言うとこちらのほうが必要だったかもw

おまけ(その2)


ついでといってはなんですが、他にJavaでよく使いそうなloggingも用意しました。
どれも必要最低限のライブラリしか使っていませんので、動作の参考になるかと思います。

  • Commons Logging + SimpleLog
  • SLF4j + Log4j
  • SLF4j + Logback
  • SLF4j + Log4j2

ここに置きました。

Gradleがあれば使えるようにしてあります。