ソフトウェア開発プロセスで最も重要な部分の 1 つは、適切なログを記録することです。さまざまな Java ロギング フレームワークが利用可能であるため、使いやすいものを選択することが重要です。同時に、選択するフレームワークは、高性能で拡張可能な機能を備え、カスタマイズが可能である必要があります。 Log4j2 は、すべての機能を備えた無料の Java ロギング ライブラリです。
Log4j2 を任意のアプリケーションと統合すると、高度なフィルタリング、Java 8 ラムダ サポート、プロパティ ルックアップ、カスタム ログ レベルなどのオプションが利用可能になります。 Log4j2 をプロジェクトに追加する方法と、ゲームを常にトップに保つのに役立つ機能を見てみましょう。
Log4j2とは何ですか?

ロギングは、後で参照したり分析したりできる、ログと呼ばれる有用な情報を取得する方法です。ログを使用して、アプリケーション コードを迅速にデバッグできます。アプリケーション ログは、コード フローを理解し、運用上の問題やエラーに対処するのに役立ちます。
診断の使用例以外に、ログは監査目的にも使用されます。たとえば、通知メッセージがユーザーに正常に送信されたかどうかの追跡などです。
Log4j2 は、最も人気のある Java ロギング ライブラリの 1 つです。これは、非常に影響力のある Log4j ライブラリの後継です。 Apache Software Foundation および Apache Logging Services の一部によって開発された Log4j2 は、Apache License バージョン 2.0 に基づいて配布される無料のオープン ソース ソフトウェア (FOSS) です。
Log4j2 は、元の Log4j の強固な基盤の上に構築されています。 Logger を使用することには
System.out.println()
の単純な print ステートメントよりも利点があります。これには、他のログ メッセージを回避しながら、どのメッセージを表示するかを制御することが含まれます。デバッガーが利用できない運用環境では、適切なログを保持することが重要です。
Log4j2 をプロジェクトに追加するにはどうすればよいですか?
Log4j2 を Java プロジェクトに追加するには、いくつかの方法があります。 Log4j2 のすべての機能を使用するには、Java 8 以降を使用することをお勧めします。
要件に応じて Log4j2 を追加できるさまざまな方法について説明します。
Apache Maven を使用して Log4j2 をプロジェクトに追加する
プロジェクトで Apache Maven をビルド システムとして使用する場合は、Log4j2 依存関係を
pom.xml
ファイルに追加する必要があります。
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.20.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.20.0</version>
</dependency>
</dependencies>
異なるアーティファクト間で同じバージョンを維持しやすくするために、Log4j2 には部品表 (BOM) pom.xml ファイルがあります。依存関係管理の下に追加する場合は、バージョンを個別に追加する必要はありません。
<!-- Add the BOM to the dependencyManagement -->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-bom</artifactId>
<version>2.20.0</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<!-- Once the BOM is added, the versions are not required -->
<dependencies>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
</dependency>
</dependencies>
Apache Gradle を使用して Log4j2 をプロジェクトに追加する
ビルド ツールとして Apache Gradle を使用する場合は、Log4j2 依存関係を
build.gradle
ファイルに追加できます。
dependencies {
implementation 'org.apache.logging.log4j:log4j-api:2.20.0'
implementation 'org.apache.logging.log4j:log4j-core:2.20.0'
}
Gradle バージョン 5.0 以降を使用している場合は、一貫した依存関係のバージョンを維持するために、Log4j2 Maven 部品表 (BOM) をインポートするオプションがあります。これは、
build.gradle
ファイルに以下を追加することで実現できます。
dependencies {
implementation platform('org.apache.logging.log4j:log4j-bom:2.20.0')
implementation 'org.apache.logging.log4j:log4j-api'
runtimeOnly 'org.apache.logging.log4j:log4j-core'
}
Gradle バージョン 2.8 ~ 4.10 の場合、Maven BOM を直接インポートするオプションはありません。依存関係管理機能用の追加プラグインを追加する必要があります。
plugins {
id 'io.spring.dependency-management' version '1.0.15.RELEASE'
}
dependencyManagement {
imports {
mavenBom 'org.apache.logging.log4j:log4j-bom:2.20.0'
}
}
dependencies {
implementation 'org.apache.logging.log4j:log4j-api'
runtimeOnly 'org.apache.logging.log4j:log4j-core'
}
ビルド ツールを使用せずに Log4j2 をスタンドアロン アプリケーションに追加する
プロジェクトにビルド ツールがない場合は、公式 Log4j2 ダウンロード ページ から必要なアーティファクト バージョンの Log4j2 をダウンロードできます。
これらをダウンロードしたら、アプリケーションのクラスパスに次の jar が含まれていることを確認する必要があります。
- log4j-api-2.20.0.jar
- log4j-core-2.20.0.jar
Log4j2 のコンポーネントは何ですか?
Log4j2 の機能を理解し、その機能を最大限に活用するには、Log4j2 がどのように動作するかを理解することが重要です。表面下では、いくつかの構成要素が Log4j2 を構成しています。それらについて一つずつ話しましょう。

#1. ロガーコンテキスト
LoggerContext は、ロギング システムの中心ユニットです。アプリケーションで要求されたすべてのロガーが保持されます。また、構成への参照も保持します。
#2. 構成
設定には、ロギング システムに必要なすべての情報が含まれています。これには、ロガー、アペンダー、フィルターなどが含まれます。 Log4j2 では、XML、JSON、YAML などのさまざまなファイル形式を使用して構成を定義したり、Log4j2 API を使用してプログラムで構成を定義したりできます。
構成内のプロパティが変更されるたびに、自動再ロードが行われます。したがって、アプリケーションを再起動する必要はありません。
#3. ロガー
Log4j2 システムの主なコンポーネントはロガーです。ロガーは、
LogManager.getLogger()
ステートメントを使用してアプリケーション コード内で取得され、ログの生成に使用されます。ログ メッセージは、デバッグ、情報、警告、エラー、致命的など、さまざまな重大度レベルで生成できます。
#4. ロガー設定
LoggerConfig は、特定の Logger の動作を担当します。これは、特定のロガーによって生成されたイベントをログに記録するための動作と設定を定義します。これにより、さまざまなロギング レベルの構成、アペンダーのセットアップ、フィルターの適用が可能になります。
#5. フィルター
フィルターを使用して、Log4j2 のログ イベントを選択的に処理できます。フィルターは特定の基準に基づいて適用されます。これらのフィルターをロガーまたはアペンダーに適用できます。フィルターは、さらなる処理のためにどのログ イベントがログ パイプラインを通過できるかを制御します。フィルターを使用すると、ログの動作を微調整して、関連するログのみが処理されるようにすることができます。
#6. アペンダー
ログ メッセージの宛先はアペンダーによって決定されます。 1 つのロガーに複数のアペンダーを含めることができます。ログ イベントは、指定されたロガーのすべてのアペンダーに送信されます。 Log4j2 には、事前設定されたアペンダが多数あります。たとえば、ConsoleAppender はコンソールにメッセージを記録するために使用され、FileAppender はメッセージをファイルに出力するために使用されます。各アペンダーには、最終的なログ メッセージがどのように表示されるかを決定する独自のレイアウトが必要です。
#7。 レイアウト
Log4j2 では、レイアウトを使用して、最終的なログ メッセージがどのように表示されるかを定義します。レイアウトはアペンダーに関連付けられます。アペンダーは出力先を決定しますが、レイアウトはメッセージがどのように出力されるかを記述します。
Log4j2 のトップ 5 機能

Log4j2 は機能が豊富で、それが利用可能な他の Java ロギング フレームワークとの違いです。非同期ロガーの搭載から Java 8 ラムダのサポートまで、Log4j2 は他のものよりも優れています。このフレームワークの注目すべき機能のいくつかについて説明しましょう。
#1. プラグインを使用して機能を拡張する
Log4j 1.x では、拡張機能を作成するには、多くのコード変更が必要でした。 Log4j2 は、プラグイン システムを導入することで拡張性の問題を解決します。
クラスで
@Plugin
アノテーションを使用して、新しいプラグインを宣言できます。プラグインの機能を利用すると、フィルターやアペンダーなどの独自のコンポーネントを作成できます。サードパーティのコンポーネントもライブラリに簡単に追加できます。
#2. Java 8 Lambdaのサポート
Log4j2 バージョン 2.4 のリリースにより、Java 8 ラムダ式のサポートが導入されました。ラムダ式を使用すると、ロギング ロジックをインラインで定義できます。これにより、複数行のチェックや匿名の内部クラスの必要性が減ります。これにより、高価なメソッドが不必要に実行されることもなくなります。したがって、コードがすっきりして読みやすくなるだけでなく、システムのオーバーヘッドも削減されます。
デバッグ レベルが有効な場合にのみ、負荷の高い操作の結果をログに記録する例を考えてみましょう。ラムダがサポートされる前は、これは以下のコードを使用して実行されていました。
if (logger.isDebugEnabled()) {
logger.debug("The output of the given operation is: {}", expensiveOperation());
}
このような使用例が複数あると、不必要に条件チェックが導入されてしまいます。ただし、Log42 を使用すると、次のように同じアクションを実行できます。
logger.debug("The output of the given operation is: {}", () -> expensiveOperation()
メソッド
exprensiveOperation()
デバッグ レベルが有効な場合にのみ評価されます。明示的なチェックは必要ありません。
#3. 非同期ロガー
すべてのログ イベントは I/O 操作であるため、システムのオーバーヘッドが増加します。これを軽減するために、Log4j2 では、アプリケーション スレッドとは別のスレッドで実行される非同期ロガーが導入されています。非同期ロガーを使用する場合、呼び出し側スレッドは、
logger.log()
メソッドを呼び出した後、すぐに制御を取り戻します。
これにより、ロギング イベントの完了を待たずに、アプリケーション ロジックを続行できるようになります。この非同期動作を利用すると、ロギングのスループットが向上します。デフォルトですべてのロガーを非同期にするか、同期動作と非同期動作の両方を混合するかを選択できます。
#4. ガベージフリーのロギング
Java では、ガベージ コレクションは、アプリケーション内の未使用のオブジェクトを自動的にクリアするプロセスです。この操作を手動で行う必要はありませんが、ガベージ コレクションには独自のオーバーヘッドがあります。
アプリケーションが短期間に作成するオブジェクトの数が多すぎる場合、ガベージ コレクション プロセスが必要以上に多くのシステム リソースを消費する可能性があります。 Log4j の以前のバージョンを含むいくつかのログ ライブラリは、ログ プロセス中に大量の一時オブジェクトを作成します。その後、ガベージ コレクターへの負荷が増大し、システムのパフォーマンスに影響を与えます。
バージョン 2.6 以降、Log4j2 は「ガベージフリー」モードで実行されます。これはデフォルトの動作です。したがって、オブジェクトは再利用され、一時的なオブジェクトの作成が大幅に削減されます。
次の画像は、Log4j2 バージョン 2.5 と比較して、Log4j2 バージョン 2.6 が不要なオブジェクトの問題をどのように軽減するかを示しています。


#5. ルックアップ
log4j2 では、ルックアップを使用してコンテキスト情報をログに追加できます。これらを利用すると、システム プロパティ、環境変数、カスタム定義値など、さまざまなソースからデータを追加できます。したがって、動的に取得される関連情報を含めることができ、ログがより便利になります。
ユーザーのセッション ID をすべてのログ行で記録する例を考えてみましょう。これにより、セッション ID に対応するすべてのログを検索できるようになります。
これを行う強引な方法は、セッション ID を個別に明示的に追加することですが、これは保守が困難になります。すぐに追加を忘れてしまい、貴重な情報が失われる可能性があります。
logger.info("The user data has been fetched for session id {}", sessionId);
...
logger.info("The transaction has been processed for session id {}", sessionId);
...
logger.info("Request has been successfully processed for session id {}", sessionId);
より良い方法は、コンテキスト マップ ルックアップを使用することです。セッション ID は、アプリケーション コードのスレッド コンテキストに追加できます。この値は Log4j2 構成内で使用できます。したがって、ログ メッセージで明示的に言及する必要がなくなります。
ThreadContext.put("sessionId", sessionId);
値が追加されると、キーワード
ctx
を使用して同じ値をルックアップで使用できます。
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${ctx:sessionId} %m%n</pattern>
</PatternLayout>
</File>
Log4j2 でカスタム ログ レベルを作成するにはどうすればよいですか?
Log4j2 のログ レベルは、重大度または重要性に基づいてログ イベントを分類するために使用されます。アプリケーション コードでメッセージを記録するときに、ログ レベルを制御できます。
たとえば、
logger.debug()
DEBUG レベルを追加します。同様に、
logger.error()
ERROR レベルを追加します。これにより、どのメッセージが最終的に出力に表示されるかが決まります。ログ レベルは構成ファイルで構成できます。
Log4j2 の事前設定されたログ レベルとそれに対応する値については、以下で説明します。
オフ | 0 |
致命的 | 100 |
エラー | 200 |
警告 | 300 |
情報 | 400 |
デバッグ | 500 |
痕跡 | 600 |
全て | 最大値 |
ログ レベルが特定のレベルに設定されている場合、その対応する値とその上の (値が小さい) ログ行がすべて出力されます。他は無視されます。
たとえば、ログ レベルを WARN に設定すると、WARN、ERROR、および FATAL メッセージが表示されます。異なるレベルのログ行は無視されます。これは、同じコードを異なる環境で実行する場合に特に便利です。
開発環境でコードを実行するときは、ログ レベルを INFO または DEBUG に設定するとよいでしょう。これにより、より多くのログを表示し、開発プロセスに役立つようになります。ただし、実稼働環境で実行する場合は、これを ERROR に設定することをお勧めします。したがって、異常が発生した場合に、不必要なログ行を参照する必要がなく、問題の発見に集中できます。
事前に構成されたログ レベルに加えて、独自のカスタム ログ レベルを追加したい場合があります。 Log4j2 を使用すると、これを簡単に行うことができます。独自のログ レベルを追加し、アプリケーションで使用する方法を見てみましょう。
#1. 構成ファイルを使用したカスタム ログ レベルの追加
構成ファイルで宣言することで、カスタム ログ レベルを追加できます。
以下の例では、NOTICE という名前のカスタム ログ レベルが値 450 で定義されています。これにより、INFO (値 400) と DEBUG (値 500) の間に配置されます。これは、レベルが NOTICE に設定されている場合、INFO メッセージはログに記録されますが、DEBUG メッセージはスキップされることを意味します。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<CustomLevels>
<CustomLevel name="NOTICE" intLevel="450" />
</CustomLevels>
<Appenders>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
</File>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="MyFile" level="NOTICE" />
</Root>
</Loggers>
</Configuration>
#2. コードにカスタム ログ レベルを追加する
構成ファイルで宣言する以外に、コード内で独自のカスタム ログ レベルを定義できます。
final Level VERBOSE = Level.forName("VERBOSE", 550);
これにより、VERBOSE という名前の新しいログ レベルが作成されます。このログ レベルは、DEBUG (値が 500) と TRACE (値が 600) の間にあります。ロガーが VERBOSE レベルに設定されている場合、DEBUG を含む VERBOSE 以上のすべてのログ メッセージが記録されます。ただし、TRACE メッセージはスキップされます。
#3. コード内でのカスタム ログ レベルの使用
カスタム ログ レベルは、使用する前にまず宣言する必要があります。これらは構成ファイルまたはコードで宣言できます。宣言後は自由に使用できます。
このコード例は、NOTICE というカスタム レベルを宣言し、それを使用する方法を示しています。
final Level NOTICE = Level.forName("NOTICE", 550);
final Logger logger = LogManager.getLogger();
logger.log(NOTICE, "a notice level message");
これにより、新しく作成されたレベルで必要なメッセージが生成されますが、レベルを常に明示的に渡すのは面倒になる可能性があります。ありがたいことに、ソース コードを生成して、カスタム レベルをログに記録するためのヘルパー メソッドを取得できます。これを使用すると、 logger.debug
logger.debug()
または
logger.error()
を使用する場合と同様に、
logger.notice()
() の独自のメソッドを使用できるようになります。
Log4j2 には、独自の拡張ロガーの作成に役立つユーティリティが付属しています。次のコマンドは、CustomLogger.java という名前の Java ファイルを作成します。このファイルには、既存のログ メソッドと、NOTICE レベル用に新しく生成されたメソッドが含まれています。
java -cp log4j-core-2.20.0.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator \
com.example.CustomLogger NOTICE=450 > com/example/CustomLogger.java
ファイルが生成されたら、コード内でそのクラスを使用して新しいロガーを作成できます。これらのロガーには、カスタム ログ レベルの追加メソッドが含まれています。したがって、ロガーの機能を拡張できます。
final Logger logger = CustomLogger.create(ValueFirstSmsSender.class);
//this new method is similar to using logger.debug()
logger.notice("a notice level message");
結論
Log4j2 は非常に強力な Java ロギング フレームワークであり、幅広い機能、構成、パフォーマンスの向上などを提供します。ログはソフトウェア開発プロセスの非常に重要な部分であるため、Log4j2 のような堅牢なフレームワークを使用すると、アプリケーションの機能が強化されます。
Log4j2 の柔軟性と拡張性により、アプリケーション内で発生するイベントを適切にキャプチャできます。その後、ログをデバッグと監査のための強力なツールとして考えることができるようになります。 Log4j2 は、そのすべての機能と改良点により際立っており、さまざまなソフトウェア プロジェクトで優先される選択肢となっています。
これらの Java IDE およびオンライン コンパイラにも興味があるかもしれません。