ローリングファイルアペンダーの手引き

1概要

ログファイルは有用な情報を伝えることが多いのですが、時間が経つにつれて自然に大きくなり、無期限に大きくすることが許されている場合、そのサイズが問題になる可能性があります。

ロギングライブラリは、ローリングファイルアペンダを使用してこの問題を解決します。ローリングファイルアペンダは、事前定義された条件が発生したときに自動的に現在のログファイルを「ロール」またはアーカイブし、新しいファイルでロギングを再開します。

この記事では、最も広く使用されているロギング・ライブラリー、Log4j、Log4j2、およびSlf4jのいくつかでローリング・ファイル・アペンダーを構成する方法を探ります。

サイズ、日付/時刻、サイズと日付/時刻の組み合わせに基づいてログファイルをロールする方法を説明します。また、古いログファイルを自動的に圧縮して後で削除するように各ライブラリを設定する方法についても説明します。これにより、面倒なハウスキーピングコードを書く必要がなくなります。

2私たちのサンプルアプリケーション

いくつかのメッセージを記録するサンプルアプリケーションから始めましょう。このコードはLog4jに基づいていますが、Log4j2またはSlf4jで動作するように簡単に変更できます。

import org.apache.log4j.Logger;

public class Log4jRollingExample {

    private static Logger logger = Logger.getLogger(Log4jRollingExample.class);

    public static void main(String[]args) throws InterruptedException {
        for(int i = 0; i < 2000; i++) {
            logger.info("This is the " + i + " time I say 'Hello World'.");
            Thread.sleep(100);
        }
    }
}

アプリケーションは非常に素朴です - それは繰り返しの間の短い遅れで、ループでいくつかのメッセージを書きます。実行するループが2,000回、各ループで100ミリ秒の休止があるため、アプリケーションの完了には3分以上かかります。

このサンプルを使用して、さまざまな種類のローリングファイルアペンダのいくつかの機能を説明します。

3 Log4j でのファイルアペンダのローリング

3.1. Mavenの依存関係

まず、アプリケーションでLog4jを使用するには、この依存関係をプロジェクトの pom.xml ファイルに追加します。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

次の例で使用する apache-log-extras によって提供される追加のアペンダを使用するには、完全な互換性を確保するために必ずLog4j用に宣言したものと同じバージョンを使用して、次の依存関係を追加します。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>apache-log4j-extras</artifactId>
    <version>1.2.17</version>
</dependency>

Log4j およびhttps:/の最新リリースを見つけることができます。 Maven Centralの/search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22log4j%22%20AND%20a%3A%22apache-log4j-extras%22[Apache Log4j補足]]。

3.2. ファイルサイズに基づくローリング

Log4jでは、他のロギングライブラリと同様に、ファイルローリングはアペンダに委任されています。ファイルサイズに基づいてロールするLog4jのローリングファイルアペンダの設定を見てみましょう。

<appender name="roll-by-size" class="org.apache.log4j.RollingFileAppender">
    <param name="file" value="target/log4j/roll-by-size/app.log"/>
    <param name="MaxFileSize" value="5KB"/>
    <param name="MaxBackupIndex" value="2"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n"/>
        </layout>
</appender>

ここでは、 MaxFileSize パラメーターを使用して、ログファイルのサイズが5KBに達したときにログファイルをロールするようにLog4jを構成しました。また、Log4jに MaxBackupIndex パラメータを使用して最大2つのロールログファイルを保持するように指示しました。

サンプルアプリケーションを実行したときに、次のファイルが取得されました。

27/11/2016  10:28    138 app.log
27/11/2016  10:28  5.281 app.log.1
27/11/2016  10:28  5.281 app.log.2

何が起こった? Log4jは app.log ファイルへの書き込みを開始しました。ファイルサイズが5 KBの制限を超えると、Log4jは app.log app.log.1 に移動し、まったく新しい空の app.log を作成し、 app.log に新しいログメッセージを書き込み続けました。

その後、新しい app.log が5 KBの制限を超えた後、このローリングプロセスが繰り返されました。今回は、 app.log.1 app.log.2に移動され、 空の app.log という新しい空のスペースができました。

ローリングプロセスは実行中に数回繰り返されましたが、アペンダは最大2つのロールファイルを保持するように設定されているため、 app.log.3 というファイルはありません。

これで、作成されたログファイルのサイズに制限を設定できるようになったため、元の問題の1つが解決されました。

一方、 app.log.2 の最初の行を確認したところ、700回目の繰り返しに関連するメッセージが含まれていました。これは、以前のすべてのログメッセージが失われたことを意味します。

2016-11-27 10:28:34 INFO  This is the 700 time I say 'Hello World'.

ログメッセージを失うことが最善の方法とは見なされない、運用環境により適した設定を考え出すことができるかどうか見てみましょう。

そうするために私達は apache-log4j-extras と呼ばれる専用のパッケージで出荷される他のより強力で柔軟で設定可能なLog4jアペンダを使うつもりです。

このアーティファクトに含まれているアペンダは、ログローリングを微調整するための多くのオプションを提供し、それらは トリガポリシー ロールポリシー の異なる概念を紹介します。 triggering policy はロールがいつ行われるべきかを記述し、 rolling policy はローリングがどのように実行されるべきかを記述します。これら2つの概念は、ログファイルをローリングするための鍵であり、すぐにわかるように、他のライブラリでもほぼ明示的に使用されています。

3.3. 自動圧縮による圧延

Log4jの例に戻り、スペースを節約するためにロールファイルの自動圧縮を追加して、設定を改善しましょう。

<appender name="roll-by-size" class="org.apache.log4j.rolling.RollingFileAppender">
    <rollingPolicy class="org.apache.log4j.rolling.FixedWindowRollingPolicy">
        <param name="ActiveFileName" value="target/log4j/roll-by-size/app.log"/>
        <param name="FileNamePattern" value="target/log4j/roll-by-size/app.%i.log.gz"/>
    <param name="MinIndex" value="7"/>
    <param name="MaxIndex" value="17"/>
    </rollingPolicy>
    <triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
        <param name="MaxFileSize" value="5120"/>
    </triggeringPolicy>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n"/>
    </layout>
</appender>

triggering policy 要素を使用して、ログが5,120バイトのサイズを超えたときにロールが発生するはずであると述べました。

rolling policy タグ __、 内で、 ActiveFileName パラメーターは最新のメッセージを含むメインログファイルのパスを示し、 FileNamePattern パラメーターはどちらをロールファイルのパスにするかを記述するテンプレートを指定します。特別なプレースホルダ %i__がロールファイルのインデックスに置き換えられるため、これは確かにパターンです。

FileNamePattern は " .gz" 拡張子で終わることにも注意してください。

サポートされている圧縮形式に関連付けられている拡張子を使用するときはいつでも、古いロールファイルを圧縮することになります。

アプリケーションを実行すると、今度は異なるログファイルのセットを取得します。

03/12/2016 19:24 88 app.1.log.gz
...
03/12/2016 19:26 88 app.2.log.gz
03/12/2016 19:26 88 app.3.log.gz
03/12/2016 19:27 70 app.current.log

ファイル app.current.log は、最後のログが発生した場所です。以前のログは、サイズが設定された制限に達するとロールされて圧縮されました。

3.4. 日付と時刻に基づくローリング

他のシナリオでは、ファイルのサイズではなくログメッセージの日付と時刻に基づいてファイルをロールするようにLog4jを設定することができます。たとえば、Webアプリケーションでは、1日に発行されるすべてのログメッセージを同じログファイルに保存することができます。

それには、 TimeBasedRollingPolicy を使用できます。このポリシーでは、時間関連のプレースホルダーを含むログファイルのパスのテンプレートを指定することが必須です。ログメッセージが発行されるたびに、アペンダは結果のログパスがどうなるかを検証し、それが最後に使用されたパスと異なる場合は、ロールが発生します。これは、そのようなアペンダを設定する簡単な例です。

<appender name="roll-by-time"
    class="org.apache.log4j.rolling.RollingFileAppender">
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
        <param name="FileNamePattern" value="target/log4j/roll-by-time/app.%d{HH-mm}.log.gz"/>
    </rollingPolicy>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p - %m%n"/>
    </layout>
</appender>

3.5. サイズと時間に基づくローリング

SizeBasedTriggeringPolicy と__TimeBasedRollingPolicyを組み合わせると、日付/時刻に基づいてロールするアペンダを取得できます。ファイルのサイズが設定された制限に達すると、サイズに基づいてロールします。

<appender name="roll-by-time-and-size" class="org.apache.log4j.rolling.RollingFileAppender">
    <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
        <param name="ActiveFileName" value="log4j/roll-by-time-and-size/app.log"/>
        <param name="FileNamePattern" value="log4j/roll-by-time-and-size/app.%d{HH-mm}.%i.log.gz"/>
    </rollingPolicy>
    <triggeringPolicy
        class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
        <param name="MaxFileSize" value="100"/>
    </triggeringPolicy>
    <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p - %m%n"/>
    </layout>
</appender>

この設定でアプリケーションを実行したところ、次のログファイルが得られました。

03/12/2016 19:25 234 app.19-25.1481393432120.log.gz
03/12/2016 19:25 234 app.19-25.1481393438939.log.gz
03/12/2016 19:26 244 app.19-26.1481393441940.log.gz
03/12/2016 19:26 240 app.19-26.1481393449152.log.gz
03/12/2016 19:26 3.528 app.19-26.1481393470902.log

ファイル app.19-26.1481393470902.log は、現在のログ記録が行われる場所です。ご覧のとおり、19:25〜19:26の間のすべてのログは、名前が「__app.19-25」で始まる複数の圧縮ログファイルに保存されます。増え続ける数で。

4 Log4j2 のローリングファイルアペンダー

4.1. Mavenの依存関係

Log4j2を推奨ロギングライブラリとして使用するには、次の依存関係でプロジェクトのPOMを更新する必要があります。

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.7</version>
</dependency>

いつものように、あなたはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.apache.logging.log4j%22%20AND%20a%3A%22log4j-core%を見つけることができますMaven Centralの22[最新バージョン]。

4.2. ファイルサイズに基づくローリング

Log4j2ロギングライブラリを使用するようにサンプルアプリケーションを変更し、__log4j2.xml設定ファイル内のログファイルのサイズに基づいてファイルローリングを設定する方法を調べましょう。

<RollingFile
  name="roll-by-size"
  fileName="target/log4j2/roll-by-size/app.log"
  filePattern="target/log4j2/roll-by-size/app.%i.log.gz"
  ignoreExceptions="false">
    <PatternLayout>
        <Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
    </PatternLayout>
    <Policies>
        <OnStartupTriggeringPolicy/>
        <SizeBasedTriggeringPolicy size="5 KB"/>
    </Policies>
</RollingFile>

Policies タグでは、適用するすべてのトリガーポリシーを指定しました。 OnStartupTriggeringPolicy は、アプリケーションが起動するたびにロールをトリガーします。これは、スタンドアロンアプリケーションに役立ちます。

次に、ログファイルが5KBに達するたびにロールが発生するように指定する SizeBasedTriggeringPolicy を指定しました。

4.3. 日付と時刻に基づくローリング

Log4j2が提供するポリシーを使用して、時間に基づいてログファイルをロールおよび圧縮するためのアペンダを設定しましょう。

<RollingFile name="roll-by-time"
  fileName="target/log4j2/roll-by-time/app.log"
  filePattern="target/log4j2/roll-by-time/app.%d{MM-dd-yyyy-HH-mm}.log.gz"
  ignoreExceptions="false">
    <PatternLayout>
        <Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
    </PatternLayout>
    <TimeBasedTriggeringPolicy/>
</RollingFile>

ここで重要なのは、 TimeBasedTriggeringPolicy を使用することです。これにより、ロールファイル名のテンプレートで時間関連のプレースホルダーを使用できます。

単一のトリガーポリシーのみが必要だったので、前の例のように Policies タグを使用する必要はありません。

4.4. サイズと時間に基づくローリング

前述のように、より説得力のあるシナリオは、時間とサイズの両方に基づいてログファイルをロールおよび圧縮することです。このタスクに対してLog4j2を設定する方法の例を以下に示します。

<RollingFile name="roll-by-time-and-size"
  fileName="target/log4j2/roll-by-time-and-size/app.log"
  filePattern="target/log4j2/roll-by-time-and-size/app.%d{MM-dd-yyyy-HH-mm}.%i.log.gz"
  ignoreExceptions="false">
    <PatternLayout>
        <Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
    </PatternLayout>
    <Policies>
        <OnStartupTriggeringPolicy/>
        <SizeBasedTriggeringPolicy size="5 KB"/>
        <TimeBasedTriggeringPolicy/>
    </Policies>
    <DefaultRolloverStrategy>
        <Delete basePath="${baseDir}" maxDepth="2">
            <IfFileName glob="target/log4j2/roll-by-time-and-size/app.** .log.gz"/>
            <IfLastModified age="20d"/>
        </Delete>
    </DefaultRolloverStrategy>
</RollingFile>

この構成では、時間とサイズに基づいてロールが発生するはずであると述べました。アペンダは、ファイル名に使用されているパターン「__app。%d \ {MM-dd-yyyy-HH-mm}。%i.log.gz」により、参照している時間間隔を理解できます。これは、毎分ロールが発生するように暗黙的に設定し、ロールファイルを圧縮します。

特定の条件に一致する古いロールファイルを削除するための DefaultRolloverStrategy も追加しました。 20日以上経過している場合は、指定されたパターンに一致するファイルを削除するように設定します。

4.5. Mavenの依存関係

Log4j2を推奨ロギングライブラリとして使用するには、次の依存関係でプロジェクトのPOMを更新する必要があります。

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.7</version>
</dependency>

いつものように、あなたはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22org.apache.logging.log4j%22%20AND%20a%3A%22log4j-core%を見つけることができますMaven Centralの22[最新バージョン]。

5 Slf4j のローリングファイルアペンダー

5.1. Mavenの依存関係

ロギングライブラリとしてLogbackバックエンドを持つSlf4j2を使用する場合は、この依存関係を pom.xml に追加します。

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.7</version>
</dependency>

いつものように、あなたはhttps://search.maven.org/classic/#search%7Cga%7C1%7Cg%3A%22ch.qos.logback%22%20AND%20a%3A%22logback-classic%22[を見つけることができますMaven Centralの最新バージョン]

5.2. ファイルサイズに基づくローリング

では、代わりにSlf4jをデフォルトのバックエンド Logback で使用する方法を見てみましょう。アプリケーションのクラスパスに配置されている設定ファイル logback.xml でファイルローリングを設定する方法を調べてみましょう。

<appender name="roll-by-size" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>target/slf4j/roll-by-size/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
        <fileNamePattern>target/slf4j/roll-by-size/app.%i.log.zip</fileNamePattern>
        <minIndex>1</minIndex>
        <maxIndex>3</maxIndex>
        <totalSizeCap>1MB</totalSizeCap>
    </rollingPolicy>
    <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
       <maxFileSize>5KB</maxFileSize>
    </triggeringPolicy>
    <encoder>
        <pattern>%-4relative[%thread]%-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>

繰り返しになりますが、ローリングポリシーの概念があります。基本的なメカニズムは、Log4jとLog4j2で使用されているものと同じです。 FixedWindowRollingPolicy を使用すると、ロールファイルの名前パターンにインデックスプレースホルダを使用できます。

ログファイルのサイズが設定された制限を超えると、新しいファイルが割り当てられ、古いコンテンツがリストの最初のファイルとして保存され、既存のファイルがさらに1つ移動します。

5.3. 時間に基づくローリング

Slf4jでは、提供された TimeBasedRollingPolicy を使用して、時間に基づいてログファイルをロールバックできます。このポリシーでは、時間と日付に関連するプレースホルダーを使用してローリングファイルのテンプレート名を指定できます。

<appender name="roll-by-time" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>target/slf4j/roll-by-time/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>target/slf4j/roll-by-time/app.%d{yyyy-MM-dd-HH-mm}.log.zip
        </fileNamePattern>
        <maxHistory>20</maxHistory>
        <totalSizeCap>1MB</totalSizeCap>
    </rollingPolicy>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</pattern>
    </encoder>
</appender>

5.4. サイズと時間に基づくローリング

時間とサイズの両方に基づいてファイルをロールバックする必要がある場合は、提供されている SizeAndTimeBasedRollingPolicy を使用できます。このポリシーを使用するときは、時間関連のプレースホルダーとインデックスのプレースホルダーの両方を指定する必要があります。

特定の時間間隔のログファイルのサイズが設定されたサイズ制限を超えるたびに、時間関連のプレースホルダに同じ値を持ち、インデックスが増加する別のログファイルが作成されます。

<appender name="roll-by-time-and-size"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>target/slf4j/roll-by-time-and-size/app.log</file>
    <rollingPolicy
      class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>
            target/slf4j/roll-by-time-and-size/app.%d{yyyy-MM-dd-mm}.%i.log.zip
        </fileNamePattern>
        <maxFileSize>5KB</maxFileSize>
        <maxHistory>20</maxHistory>
        <totalSizeCap>1MB</totalSizeCap>
    </rollingPolicy>
    <encoder>
        <pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</pattern>
    </encoder>
</appender>

6. 結論

これまで見てきたように、ログライブラリを利用してファイルをロールすることで、ログファイルを手動で管理する手間が省け、ビジネスロジックの開発に集中することができます。ローリングファイルアペンダは、すべての開発者のツールボックスに含まれるべき貴重なツールです。

いつもどおり、https://github.com/eugenp/tutorials/tree/master/logging-modules/log4j[on GitHub]というソースがあります。この記事で紹介するサンプルアプリケーションは、さまざまな方法でログを記録するように設定されています。あなたのニーズに合うようにさらに調整されるべき良い基本設定を見つけることを可能にするためにローリングセットアップ。