log4j2を使用したwebアプリでのファイルへのログ出力

Webアプリケーションでログの制御をlog4j2を使用して行う方法についてのメモ。
以下はEclipseを使って作成した手順です。

環境

手順

1. jarファイルの用意

公式ページに行って、Log4j 2 のjarファイルを取得する。
Log4j 2.3はJavaの6がサポートされる最後のバージョンで以下のjarファイルが必要。

2.設定ファイル(log4j2.xml)について

設定ファイルがない場合は、デフォルト設定でのログ出力が行われる。
デフォルト設定を設定ファイルで記述した場合以下の記載となる。

<?xml version="1.0" encoding="UTF-8"?>
  <Configuration status="WARN">
    <Appenders>
      <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
       </Console>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Console"/>
        </Root>
      </Loggers>
    </Configuration>

Configuration
statusはlog4j2自体の内部ログの出力レベル設定。status="off"で出力停止

Appenders
どのようにLogEventを配信するかを定義する。
Console appenderは System.out または System.errへの出力
targetで標準出力か標準エラー出力かを定義する。

PatternLayout
出力形式の設定。細かな設定値はマニュアルに記載参照。 デフォルトのpatternの記載内容は以下

%d{HH:mm:ss.SSS} -> 時刻形式。%d{}で時刻形式を囲んで設定
%t               ->  スレッド名
%msg             ->  ログメッセージ
hh:mm:ss.SSS [threadName] [logLevel] [loggerName]-[msg]のような形式で出力される

Loggers
Javaパッケージ毎に出力するログレベルやログの出力方法(Appender)を指定する。
設定ファイルがない場合、またはLogger name="hoge"の形でロガー名を指定しない場合は
Rootの設定を適用。 level="error"であればERROR以上のレベル(ERROR,FATAL)で出力を行う。
AppenderRef refで指定する名称にはAppenderのnameを使用する。

仮に、

<Loggers>
    <Root level="debug" ・・・>
    ・・・・
    <Logger name="X"  level="error"  >
    ・・・・

の設定が存在した場合、下記のJavaパッケージは以下のレベルで出力を行う

X --> Xが適用 ERROR,FATAL
X.Y --> Xが適用 ERROR,FATAL
Z --> Rootが適用 DEBUG,INFO,WARN,ERROR,FATAL

3.ファイル出力のための設定ファイル(log4j2.xml)の準備

今回は、ファイル出力を行うため、RollingFileAppenderを用いて以下に設定

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off">
<Appenders>
<RollingFile name="RollingFile" fileName="D:/testlogs/test.log"
     filePattern="D:/testlogs/test-%d{yyyy-MM-dd}-%i.zip">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger - %msg%n"/>
          <Policies>
              <OnStartupTriggeringPolicy />
              <SizeBasedTriggeringPolicy size="20 MB" />
              <TimeBasedTriggeringPolicy />
          </Policies>
          <DefaultRolloverStrategy max="20"/>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>  
      </Loggers>
    </Configuration>

ログ出力先/名称
D:/testlogs/test.log
フルパス、相対パスどちらの指定も可能

ログローテート条件
以下の条件で新たなファイルを生成し、ログローテートを実施
- ログの開始日と日付が異なる場合
- 新たなJVMが起動した場合
- ファイルサイズが20MBを超えた場合

ローテートファイル形式
test-%d{yyyy-MM-dd}-%iの名称でzip圧縮(%iは連番でmaxは20)

4.Tomcatプロジェクトの作成

Eclipseのメニュー -> ファイル -> 新規 -> プロジェクト -> Tomcatプロジェクトを選択

プロジェクト名は任意の名前を入力 f:id:genepon:20190121224924p:plain

5.jarの配置と設定ファイル(log4j2.xml)の配置

WEB-INF/lib以下のファイルにダウンロードしたJarファイルを配置する。 また、log4j2.xmlをsrc直下に配置する。 配置したらeclipse上のプロジェクトフォルダ上で右クリックして更新。 jarファイルがパッケージ・エクスプローラーに表示されたら、 ファイルを選択して右クリック->ビルドパスへ追加。

f:id:genepon:20190121224926p:plain

6.ログを出力するためのサーブレットクラスの作成

「WEB_INF/src」フォルダの上で右クリック、新規 -> クラス を選択し、適当なパッケージ名とクラス名を入力 f:id:genepon:20190121224931p:plain

サンプルコード(LogOut.java)
package foo;
import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;


public class LogOut extends HttpServlet {
    static Logger logger = LogManager.getLogger(LogOut.class.getName());
     
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
               throws ServletException, IOException {
        
        logger.trace("Logged by logger.trace");
        logger.debug("Logged by logger.debug");
        logger.info ("Logged by logger.info");
        logger.warn ("Logged by logger.trace");
        logger.error("Logged by logger.error");
        logger.fatal("Logged by logger.fatal");
    }   
}

7.web.xmlの作成

WEB_INF/src/フォルダの上で右クリック、新規 -> ファイル、ファイル名をweb.xmlとして作成

<?xml version="1.0" encoding="ISO-8859-1"?>

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    version="2.5">
    
    <servlet>
        <servlet-name>LogOut</servlet-name>
        <servlet-class>foo.LogOut</servlet-class>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>LogOut</servlet-name>
        <url-pattern>/LogOut</url-pattern>
    </servlet-mapping>
    
</web-app>

8.ブラウザでアクセスして確認

設定したERRORとFATALレベルのログがD:\testlogs\test.logに出力されていることを確認

23:06:02.434 [http-8080-1] ERROR foo.LogOut - Logged by logger.error
23:06:02.437 [http-8080-1] FATAL foo.LogOut - Logged by logger.fatal

log4j2.xmlPoliciesOnStartupTriggeringPolicyを設定しているためTomcatの再起動で、 ログがローテートされ圧縮される

f:id:genepon:20190121225004p:plain

参考

Log4j – Overview - Apache Log4j 2