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. ConsoleAppenderとPatternLayout
別の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です。