私はこれについてグーグルを持っていて、複数の提案を見ましたが、何も役に立たないようです。
MDC を使用する JAX-RS アプリケーションがあります。エンドポイントがヒットすると、デバッグを容易にするために transactionId が設定されます。ただし、Tomcat を停止または再起動すると、ログには次のようなエントリが記録されます。
27-Sep-2014 09:42:14.858 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks Web アプリケーション [/core-1.0.0-RC2] は、タイプ [ org.apache.log4j.helpers.ThreadLocalMap] (値 [org.apache.log4j.helpers.ThreadLocalMap@464437fc]) およびタイプ [java.util.Hashtable] の値 (値 [{siteCode=000tst, transactionId=dc8f3a1b- 1d7a-4f91-abf6-58d015632d03}]) ですが、Web アプリケーションが停止したときに削除できませんでした。スレッドは、メモリ リークの可能性を回避するために、時間の経過とともに更新されます。
MDC が呼び出される RequestFilter があります。
import org.slf4j.MDC;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import java.io.IOException;
import java.util.UUID;
public void filter(ContainerRequestContext containerRequestContext) throws IOException {
String siteCodeHeader = containerRequestContext.getHeaderString("Site-Code");
if (siteCodeHeader != null) {
MDC.put("siteCode", siteCodeHeader);
} else {
MDC.put("siteCode", "NULL");
}
MDC.put("transactionId", UUID.randomUUID().toString());
}
これらは私の sl4fj 依存関係です:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.7</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.7</version>
</dependency>
MDC.clear() を使用した ResponseFilter がある場合、MDC から値を削除しますが、スレッドをクリアしていないようです:
27-Sep-2014 09:12:58.216 SEVERE [localhost-startStop-2] org.apache.catalina.loader.WebappClassLoader.checkThreadLocalMapForLeaks Web アプリケーション [/core-1.0.0-RC2] は、タイプ [ org.apache.log4j.helpers.ThreadLocalMap] (値 [org.apache.log4j.helpers.ThreadLocalMap@391216c7]) と [java.util.Hashtable] 型の値 (値 [{}]) を削除できませんでしたWeb アプリケーションが停止したとき。スレッドは、メモリ リークの可能性を回避するために、時間の経過とともに更新されます。
どうやら log4j 1.2.17 で修正されたようですが、変更は slf4j には反映されていないようです。