以下は、良好なパフォーマンスを確保するために、すべてのプロジェクトで従う一連のガイドラインです。私は、インターネットのさまざまな情報源からの入力に基づいて、この一連のガイドラインを作成するに至りました。
今日と同じように、Log4j 2 は Java でログインするための最良のオプションであると信じています。
ベンチマークはこちらから入手できます。最高のパフォーマンスを得るために私が従う練習は次のとおりです。
- 次の理由から、現時点では SLF4J の使用を避けています。
- パフォーマンスを向上させるために、非同期ロガーを使用してすべての定期的なログを実行します
- エラーメッセージが発生したらすぐに確認したいので、同期ロガーを使用してエラーメッセージを別のファイルに記録します
- 通常のロギングでは、ファイル名、クラス名、メソッド名、行番号などの位置情報を使用しないでください。これらの情報を取得するために、フレームワークはスタックのスナップショットを取得し、それをウォークスルーするためです。これはパフォーマンスに影響します。したがって、通常のログではなく、エラー ログでのみ位置情報を使用します。
- 個別のスレッドによって処理される個々のリクエストを追跡する目的で、こちらで説明されているように、スレッド コンテキストとランダム UUID の使用を検討してください。
- エラーを別のファイルに記録しているため、コンテキスト情報もエラー ログに記録することが非常に重要です。たとえば、ファイルの処理中にアプリケーションでエラーが発生した場合は、エラー ログ ファイルに処理中のファイル名とファイル レコードをスタック トレースと共に出力します。
- ログ ファイルは grep が可能で、理解しやすい必要があります。たとえば、アプリケーションが複数のファイルで顧客レコードを処理する場合、各ログ メッセージは次のようになります。
12:01:00,127 INFO FILE_NAME=file1.txt - Processing starts
12:01:00,127 DEBUG FILE_NAME=file1.txt, CUSTOMER_ID=756
12:01:00,129 INFO FILE_NAME=file1.txt - Processing ends
- 以下に示すように、SQL マーカーを使用してすべての SQL ステートメントをログに記録し、フィルターを使用して有効または無効にします。
private static final Marker sqlMarker =
MarkerManager.getMarker("SQL");
private void method1() {
logger.debug(sqlMarker, "SELECT * FROM EMPLOYEE");
}
- Java 8 Lambda を使用してすべてのパラメーターをログに記録します。これにより、指定されたログ レベルが無効になっている場合に、アプリケーションがメッセージをフォーマットするのを防ぐことができます。
int i=5, j=10;
logger.info("Sample output {}, {}", ()->i, ()->j);
文字列連結を使用しないでください。上記のようにパラメーター化されたメッセージを使用する
アプリケーションを再起動しなくても、アプリケーションがロギング構成の変更を自動的に再ロードするように、ロギング構成の動的再ロードを使用します。
使用しないでくださいprintStackTrace()
。System.out.println()
アプリケーションは、終了する前にロガーをシャットダウンする必要があります。
LogManager.shutdown();
- 最後に、皆さんの参考のために、次の構成を使用します。
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorinterval="300" status="info" strict="true">
<Properties>
<Property name="filePath">${env:LOG_ROOT}/SAMPLE</Property>
<Property name="filename">${env:LOG_ROOT}/SAMPLE/sample
</Property>
<property name="logSize">10 MB</property>
</Properties>
<Appenders>
<RollingFile name="RollingFileRegular" fileName="${filename}.log"
filePattern="${filePath}/sample-%d{yyyy-dd-MM}-%i.log">
<Filters>
<MarkerFilter marker="SQL" onMatch="DENY"
onMismatch="NEUTRAL" />
</Filters>
<PatternLayout>
<Pattern>%d{HH:mm:ss,SSS} %m%n
</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy
interval="1" modulate="true" />
<SizeBasedTriggeringPolicy
size="${logSize}" />
</Policies>
</RollingFile>
<RollingFile name="RollingFileError"
fileName="${filename}_error.log"
filePattern="${filePath}/sample_error-%d{yyyy-dd-MM}-%i.log"
immediateFlush="true">
<PatternLayout>
<Pattern>%d{HH:mm:ss,SSS} %p %c{1.}[%L] [%t] %m%n
</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy
interval="1" modulate="true" />
<SizeBasedTriggeringPolicy
size="${logSize}" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<AsyncLogger name="com"
level="trace">
<AppenderRef ref="RollingFileRegular"/>
</AsyncLogger>
<Root includeLocation="true" level="trace">
<AppenderRef ref="RollingFileError" level="error" />
</Root>
</Loggers>
</Configuration>
- 必要な Maven 依存関係は次のとおりです。
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.8.1</version>
</dependency>
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.3.6</version>
</dependency>
<!-- (Optional)To be used when working
with the applications using Log4j 1.x -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-1.2-api</artifactId>
<version>2.8.1</version>
</dependency>