log4jを使う

仕事上は何度か使ったことあるけれど
自分で実装したことが無かったので,これを機会に勉強.

log4jというのは,java向けのlog管理ツールとでも呼ぶべきもの.
apacheから提供されている.
Log4j – Apache Log4j 2 - Apache Log4j 2
設定ファイルさえ用意しておけば,あとはシンプルなコマンドで
ログを出力することが可能となる.

仕組みは以下に整理されている.
Log4j – Log4j 2 Architecture - Apache Log4j 2
書いていることを要約すると,以下のような感じ.

・Loggerは名前を持ち,1つのLogConfigを持つ.
・LogConfigはログレベルを管理し,複数のAppenderを持つ.
・Appenderは出力先と出力フォーマット(Layout)を管理する.

また,LogConfigには継承関係も成り立つ.
「foo」の子供は「foo.bar」になる,といった具合だ.
で,継承の方法については以下になる.

・ログレベルの継承は「上書き」
・出力先(Appender)の継承は「追加」

たとえば,
foo:ログレベルはtrace,コンソール出力のAppenderを設定
foo.bar:ログレベルはerror,ファイル出力のAppenderを設定
と設定した場合,
foo.barは
「errorイベントのログを,コンソールとファイルの両方に出力する」
という振る舞いを見せる.

Appenderの継承方法も「上書き」にしたい場合,
additivityの設定をfalseにしておけば良いそうだ.
その辺は以下を見ると分かりやすい.
Log4j – Log4j 2 API - Apache Log4j 2


というわけで,御託はこれくらいにして,実装してみる.
今回は超シンプルに,以下.

package jp.nk5.stockanalyzer.controller;

import jp.nk5.stockanalyzer.application.DownloadStockDataService;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class BatchController {

  private static final Logger logger = LogManager.getLogger();
	
  public static void main(String[] args) {
    logger.error("main() started.");
    DownloadStockDataService application = new DownloadStockDataService();
    application.downloadStockData();
    logger.error("main() finished.");
  }

}

ちなみに,設定ファイルはまだ用意していない.
「設定ファイルが無い場合,log4jはログレベル=errorでコンソール出力する」
という仕様があるため.上記は設定ファイル無しでも動くのだ.

実際の実行結果が,以下.

10:45:38.365 [main] ERROR jp.nk5.stockanalyzer.controller.BatchController - main() started.
10:45:40.257 [main] ERROR jp.nk5.stockanalyzer.controller.BatchController - main() finished.

さらに設定ファイルを以下の内容で用意してやれば,
app.logというファイルにログを出力してくれるようになる.

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
  <Appenders>
    <File name="logFile" fileName="app.log">
      <PatternLayout>
        <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
      </PatternLayout>
    </File>
  </Appenders>
  <Loggers>
    <Root level="error">
      <AppenderRef ref="logFile"/>
    </Root>
  </Loggers>
</Configuration>

設定ファイル(log4j2.xml)はクラスパス上であればどこに置いても良い.


というわけで,ロギング出来るようになったので,次回こそサーバ側を実装.