2017-01-13 21 views

答えて

26

Log4j2 APIはSLF4Jよりも豊富であり、多くのLog4j2 API機能はであり、SLF4J経由ではにはアクセスできません。詳細は以下を参照してください。

Async Logger、Lookups、Filters、Layouts、AppendersなどのLog4j2実装の機能は、設定によって制御され、アプリケーションで使用するロギングAPIに関係なく使用できます。

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

10 Log4j2のAPIは

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

(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)文字列で{}スタイルパラメータ::フォーマット%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"); 
    ... 
} // "is" and "loginId" are now removed from the ThreadContext map 

(5)Log4j2のThreadContext、キーと値のペアに加えて、さらに(Log4jの1 NDCと呼ばれて使用されるもの)は、スタック機能をサポートするpushpop方法を有しています。

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

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

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

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

(9)上記はLog4j2 APIを直接使用するだけで無料で利用できます。さらに、一時的なオブジェクト(対話型ゲームや待ち時間の少ない金融アプリケーションなど)の作成を避けることを本当に気にしているのであれば、Unboxユーティリティクラスを使用してプリミティブの自動ボックス化を避けることができます。

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


免責事項:Log4j2に寄付します。

+0

すべてのimpのためにRemkoありがとうございます。あなたが指摘したポイント。 – Mayur

+0

SLF4J-240は今日最終的に修正され、SLF4J 1.7.24に含まれることに注意してください。免責事項 - 私はLog4j 2にも貢献します。 – rgoers

関連する問題