Log4jでは、NDCとMDCの違いは何ですか? それらが使用されている簡単な例を教えてください。
2 に答える
Sikorski がコメントに入れたリンクを展開するには:
NDC
NDC では、N はネストされたを表し、スタックで単一の値を制御することを意味します。文字列を「プッシュ」すると、処理が指示するたびに別の文字列を「プッシュ」できます。処理が完了したら、ポップして以前の値を確認できます。この種のコンテキスト ロギングは、深くネストされた処理で役立ちます。
コンテキスト文字列の設定
NDC.push("processingLevel2");
log.info("success");
%x
これにより、ログに(小文字の) パターンが出力されます。
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %C %x = %m%n
MDC
M は mapping を表し、これにより異なるタイプのコントロールが得られます。単一のスタックを使用して単一のコンテキスト文字列を制御する代わりに、名前と値のペアを使用します。これは、ユーザー名と IP をログに記録するなど、複数のコンテキスト ビットを追跡するのに役立ちます。
マップされた値の設定:
MDC.put("userIP", req.getRemoteAddr());
MDC.put("userName", foo.getName());
log.info("success");
MDC log4j パターンの例
"userIP"
例と"userName"
文字列を含む大文字の X。これらは、コードと log4j 構成で一致する必要があります。
log4j.appender.CA.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSSS} %p %X{userIP} %C %X{userName} = %m%n
これらを 1 つの )context string* に結合します。
類似点と相違点
どちらの場合も、 を実行するlog.info("success");
と、出力には提供した追加のコンテキストが含まれます。log.info(req.getRemoteAddr()) + " success");
これは、ログを記録するたびに文字列を連結するよりもはるかにクリーンです。
スレッド化とリソースに関して、両者には重大な違いがあることに注意してください。特に、NDC はスレッドへのハンドルを保持します。これは、NDC スタックのポップとクリアに注意を払わないと、リソースの解放に影響を与える可能性があります。
リンクから: メソッドを定期的に呼び出さないと、NDC を使用するとメモリ リークが発生する可能性がありますNDC.remove()
。
MDC では、log4j のカスタム タグを追加できます。例えば:
%X{mytag} in log4j.xml
によって参照されます
MDC.put("mytag","StackOverflow");
MDC 子スレッドは、その親のマップされた診断コンテキストのコピーを自動的に継承します。
、、、、などの NDC 操作push
はpop
、現在のスレッドの NDC のみに影響しclear
ますgetDepth
。setMaxDepth