web-dev-qa-db-ja.com

slf4j apiと一緒に使用すると、log4j2のすべての機能を使用できますか?

すべてのコードを移行して、slf4 APIを使用して汎用APIを使用しましたが、現在、log4j 1.xからlog4j 2.xへのアップグレードを検討しています。実装としてslf4j APIとlog4j2を使用すると、log4j2のすべての機能を使用できますか?

18
Mayur

Log4j2 APIはSLF4J APIよりも豊富であり、多くのLog4j2 API機能はnot SLF4Jを介してアクセス可能です。詳細については、以下を参照してください。

非同期ロガー、ルックアップ、フィルター、レイアウト、アペンダーなどのLog4j2実装の機能は構成で制御され、アプリケーションで使用するロギングAPIに関係なく使用できます。

この answer の関連する別の質問Log4j2 APIにプログラムすることが安全な理由も参照してください。

10 Log4j2 API機能はSLF4Jでは使用できません

(1) メッセージAPI を使用すると、アプリケーションはテキストだけでなく構造化オブジェクトもログに記録できます。内部的にLog4j2はメッセージに記録されるすべてを変換し、これをAPIに公開すると、アプリケーションがダウンストリームのログコンポーネント(フィルター、レイアウト、アペンダー)とやり取りするあらゆる種類の可能性が開かれます。これは、カスタムコンポーネントをLog4j2へのプラグインとして開発している場合や、組み込みコンポーネントを使用している場合に役立ちます。組み込みの例については、 StructuredDataMessage を使用して Rfc5424Layout を細かく制御する方法を参照してください。

(2)Java 8 lambda support を使用すると、要求されたログレベルが有効かどうかを明示的に確認せずに、パラメーターまたはログメッセージを遅延作成できます。

_// Java-8 style optimization: no need to explicitly check the log level:
// the lambda expression is not evaluated if the TRACE level is not enabled
logger.trace("Some long-running operation returned {}", () -> expensiveOperation());
_

(3){}スタイルのパラメーターをString :: format _%s %d_スタイルのパラメーターと混在させる。 {}スタイルはパフォーマンスが向上し、どのパラメータータイプでも使用できますが、printfスタイルを使用すると、フォーマットを細かく制御できます。 Log4j2では、これらのパラメータースタイルを簡単に組み合わせることができます。例えば:

_logger.debug("Opening connection to {}...", someDataSource);
logger.printf(Level.INFO, "Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
_

(4) CloseableThreadContext は、SLF4Jの通常のThreadContext(MDC)よりも優れた利便性を提供します。完了すると、項目が自動的に削除されます。例えば:

_// Add to the ThreadContext map for this try block only;
try (final CloseableThreadContext.Instance ctc = CloseableThreadContext
        .put("id", UUID.randomUUID().toString())
        .put("loginId", session.getAttribute("loginId"))) {
    logger.debug("Message 1");
    // call some other code that also does logging 
    ...
    logger.debug("Message 2");
    ...
} // "id" and "loginId" are now removed from the ThreadContext map
_

(5)Log4j2の ThreadContext には、キーと値のペアに加えて、スタック機能をサポートするPushおよびpopメソッドもあります(以前はLog4jではNDCと呼ばれていました) 1)。

(6)SLF4JはFATALログレベルをサポートしていません。

(7)Log4j2は カスタムログレベル をサポートしています。これらは、logメソッド(例:logger.log(Level.getLevel("FINE"), "... msg"))とともに使用できます。または、カスタムログレベル用の便利なメソッドを使用してカスタムロガーラッパーを生成できます。

(8)Log4j2 APIは、文字列だけでなく、任意のオブジェクトを受け入れます。これは、Log4j2が " garbage-free "になることを可能にするものの1つです。つまり、新しいオブジェクトの割り当てを回避します。オブジェクトがNumber、CharSequenceの場合、または(Log4j2)StringBuilderFormattableインターフェースを実装する場合、オブジェクトは一時的な文字列を作成せずにログに記録されます。

Log4j2 APIでは、10個以下のパラメーターをログに記録する場合、vararg配列の作成も回避されます。 SLF4Jは、3つ以上のパラメーターをログに記録すると、可変引数配列を作成します。

(9)上記は、Log4j2 APIを直接使用するだけで無料で入手できます。その上、一時的なオブジェクトの作成を避けたい場合(一部のインタラクティブゲームや低レイテンシの金融アプリケーションのように)、 nbox ユーティリティクラスを使用して、プリミティブパラメーターの自動ボックス化を回避できます。

(10)SLF4Jマーカーが粗粒度の同期を使用すると、マルチスレッドアプリケーションのパフォーマンスに影響を与える可能性があります( SLF4J-24 )。この パフォーマンステスト結果 ページの「高度なフィルタリング」セクションを参照してください。


免責事項:私はLog4j2に貢献しています。

46
Remko Popma