Log4j2の紹介 - アペンダ、レイアウト、フィルタ

Log4j2の概要–アペンダー、レイアウト、フィルター

1. 概要

イベントのログ記録は、ソフトウェア開発の重要な側面です。 Javaエコシステムには多くのフレームワークがありますが、Log4Jは柔軟性とシンプルさのために何十年もの間最も人気があります。

Log4j 2は、従来のLog4jフレームワークの新しく改良されたバージョンです。

この記事では、最も一般的なアペンダー、レイアウト、フィルターを実際の例で紹介します。

Log4J2では、アペンダーは単にログイベントの宛先です。コンソールのように単純なものでも、RDBMSのように複雑なものでもかまいません。 レイアウトはログの表示方法を決定し、フィルターはさまざまな基準に従ってデータをフィルターします。

2. セットアップ

いくつかのロギングコンポーネントとその構成を理解するために、それぞれがlog4J2.xml構成ファイルとJUnit 4テストクラスで構成されるさまざまなテストユースケースを設定しましょう。

2つのMaven依存関係は、すべての例に共通です。


    org.apache.logging.log4j
    log4j-core
    2.7


    org.apache.logging.log4j
    log4j-core
    2.7
    test-jar
    test

メインのlog4j-coreパッケージに加えて、パッケージに属する「test jar」を含めて、珍しい名前の構成ファイルのテストに必要なコンテキストルールにアクセスする必要があります。

3. デフォルト設定

ConsoleAppenderは、Log4J 2コアパッケージのデフォルト構成です。 次の単純なパターンでシステムコンソールにメッセージを記録します。



    
        
            
        
    
    
        
            
        
    

この単純なXML構成のタグを分析してみましょう。

  • Configuration:Log4J 2構成ファイルのルート要素と属性statusは、ログに記録する内部Log4Jイベントのレベルです。

  • Appenders:この要素は、1つ以上のアペンダーを保持しています。 ここでは、標準出力でシステムコンソールに出力するアペンダーを構成します

  • Loggers:この要素は、複数の構成済みLogger要素で構成できます。 特別なRootタグを使用すると、アプリケーションからすべてのログメッセージを受信する名前のない標準ロガーを構成できます。 各ロガーは最小ログレベルに設定できます

  • AppenderRef:この要素は、Appendersセクションからの要素への参照を定義します。 したがって、属性 ‘ref‘はアペンダー ‘name‘属性にリンクされています

対応する単体テストも同様に簡単になります。 Logger参照を取得し、2つのメッセージを出力します。

@Test
public void givenLoggerWithDefaultConfig_whenLogToConsole_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger(getClass());
    Exception e = new RuntimeException("This is only a test!");

    logger.info("This is a simple message at INFO level. " +
      "It will be hidden.");
    logger.error("This is a simple message at ERROR level. " +
    "This is the minimum visible level.", e);
}

4. ConsoleAppenderPatternLayout

別のXMLファイルでカスタマイズされたカラーパターンを使用して新しいコンソールアペンダーを定義し、それをメイン構成に含めましょう。



    

このファイルは、実行時にLog4J 2に置き換えられるいくつかのパターン変数を使用しています。

  • %style\{…}{colorname}:これにより、最初の角かっこペア()のテキストが指定された色(colorname)で印刷されます。

  • %highlight\{…}\{FATAL=colorname, …}:これは「style」変数に似ています。 ただし、ログレベルごとに異なる色を指定できます。

  • %date{format}:これは、指定されたformatの現在の日付に置き換えられます。 ここでは、「DEFAULT」DateTime形式yyyy_-MM-dd HH:mm:ss、SSS'_を使用しています。

  • %-5level:ログメッセージのレベルを右揃えで出力します。

  • %message:生のログメッセージを表します

ただし、PatternLayout.には、さらに多くの変数とフォーマットが存在します。これらは、Log4J 2の公式ドキュメントを参照してください。

次に、定義済みのコンソールアペンダーをメイン構成に含めます。



    
        
    
    
        
            
        
    

単体テスト:

@Test
public void givenLoggerWithConsoleConfig_whenLogToConsoleInColors_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger("CONSOLE_PATTERN_APPENDER_MARKER");
    logger.trace("This is a colored message at TRACE level.");
    ...
}

5. JSONLayoutおよびBurstFilterを使用した非同期ファイルアペンダー

ログメッセージを非同期で書き込むと便利な場合があります。 たとえば、アプリケーションのパフォーマンスがログの可用性よりも優先される場合です。

このようなユースケースでは、AsyncAppender.を使用できます

この例では、非同期のJSONログファイルを構成しています。 さらに、指定されたレートでログ出力を制限するバーストフィルターを含めます。



    
        ...
        
            
            
        
        
            
        
    
    
        ...
        
            
        
        
            
        
    

次のことに注意してください。

  • JSONLayoutは、行ごとに1つのログイベントを書き込むように構成されています

  • BurstFilterは、イベントが3つ以上ある場合、「INFO」レベル以上のすべてのイベントをドロップしますが、最大10個のイベントがドロップされます

  • AsyncAppenderは、80個のログメッセージのバッファに設定されます。その後、バッファはログファイルにフラッシュされます

対応する単体テストを見てみましょう。 追加されたバッファをループで埋め、ディスクに書き込んでログファイルの行数を調べます。

@Test
public void givenLoggerWithAsyncConfig_whenLogToJsonFile_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger("ASYNC_JSON_FILE_APPENDER");

    final int count = 88;
    for (int i = 0; i < count; i++) {
        logger.info("This is async JSON message #{} at INFO level.", count);
    }

    long logEventsCount
      = Files.lines(Paths.get("target/logfile.json")).count();
    assertTrue(logEventsCount > 0 && logEventsCount <= count);
}

6. RollingFileアペンダーとXMLLayout

次に、ローリングログファイルを作成します。 設定されたファイルサイズの後、ログファイルは圧縮およびローテーションされます。

今回はXMLレイアウトを使用しています。



    
        
            
            
                
            
        
    
    
        
            
        
        
            
        
    

次のことに注意してください。

  • RollingFileアペンダーには「filePattern」属性があります。これは、ローテーションされたログファイルに名前を付けるために使用され、プレースホルダー変数を使用して構成できます。 この例では、ファイルサフィックスの前に日付とカウンターを含める必要があります。

  • XMLLayoutのデフォルト構成では、ルート要素なしで単一のログイベントオブジェクトが書き込まれます。

  • ログファイルのローテーションには、サイズベースのポリシーを使用しています。

ユニットテストクラスは、前のセクションのクラスのようになります。

@Test
public void givenLoggerWithRollingFileConfig_whenLogToXMLFile_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger("XML_ROLLING_FILE_APPENDER");
    final int count = 88;
    for (int i = 0; i < count; i++) {
        logger.info(
          "This is rolling file XML message #{} at INFO level.", i);
    }
}

7. Syslogアペンダー

ログに記録されたイベントをネットワーク経由でリモートマシンに送信する必要があるとします。 Log4J2を使用してこれを行う最も簡単な方法は、Syslog Appender:を使用することです。



    
        ...
        
        
    
    
        ...
        
            
        
        
            
        
    

Syslogタグの属性:

  • name:はアペンダーの名前を定義し、一意である必要があります。 同じアプリケーションと構成に対して複数のSyslogアペンダーを使用できるため

  • format: BSDまたはRFC5424のいずれかに設定でき、Syslogレコードはそれに応じてフォーマットされます

  • host & port:リモートSyslogサーバーマシンのホスト名とポート

  • protocol:TCPまたはUPDのどちらを使用するか

  • イベントが書き込まれるSyslogファシリティのfacility:

  • 確立された接続を待機するconnectTimeoutMillis:期間、デフォルトはゼロ

  • reconnectionDelayMillis:接続を再試行する前に待機する時間

8. FailoverAppender

現在、1つのアペンダーがログイベントの処理に失敗し、データを失いたくない場合があります。 このような場合、FailoverAppenderが便利です。

たとえば、Syslogアペンダーがリモートマシンへのイベントの送信に失敗した場合、そのデータを失う代わりに、一時的にFileAppenderにフォールバックする可能性があります。

FailoverAppenderは、プライマリアペンダーとセカンダリアペンダーの数を取ります。 プライマリが失敗した場合、プライマリが成功するか、試行するセカンダリがなくなるまで、セカンダリのログイベントを順番に処理しようとします。


    
        
    

テストしてみましょう:

@Test
public void givenLoggerWithFailoverConfig_whenLog_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger("FAIL_OVER_SYSLOG_APPENDER");
    Exception e = new RuntimeException("This is only a test!");

    logger.trace("This is a syslog message at TRACE level.");
    logger.debug("This is a syslog message at DEBUG level.");
    logger.info("This is a syslog message at INFO level.
      This is the minimum visible level.");
    logger.warn("This is a syslog message at WARN level.");
    logger.error("This is a syslog message at ERROR level.", e);
    logger.fatal("This is a syslog message at FATAL level.");
}

9. JDBC Appender

JDBCアペンダーは、標準JDBCを使用して、ログイベントをRDBMSに送信します。 接続は、JNDIデータソースまたは接続ファクトリーを使用して取得できます。

基本構成は、DataSourceまたはConnectionFactory、ColumnConfigs、およびtableName:で構成されます。


    
    
    
    
    
    

では、試してみましょう。

@Test
public void givenLoggerWithJdbcConfig_whenLogToDataSource_thanOK()
  throws Exception {
    Logger logger = LogManager.getLogger("JDBC_APPENDER");
    final int count = 88;
    for (int i = 0; i < count; i++) {
        logger.info("This is JDBC message #{} at INFO level.", count);
    }

    Connection connection = ConnectionFactory.getConnection();
    ResultSet resultSet = connection.createStatement()
      .executeQuery("SELECT COUNT(*) AS ROW_COUNT FROM logs");
    int logCount = 0;
    if (resultSet.next()) {
        logCount = resultSet.getInt("ROW_COUNT");
    }
    assertTrue(logCount == count);
}

10. 結論

この記事では、Log4J2でさまざまなロギングアペンダー、フィルター、レイアウトを使用する方法、およびそれらを構成する方法の非常に簡単な例を示します。

記事に付随する例は利用可能なover on GitHubです。