3

私はこれについてグーグルを持っていて、複数の提案を見ましたが、何も役に立たないようです。

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 には反映されていないようです。

4

3 に答える 3

2

前の2つの回答を組み合わせて使用​​ して、問題を解決できました。

SLF4J ではなく MDC の log4j 実装を使用し、ResponseFilter も追加して消去しました。影響したかどうかはわかりませんが、web.xml でクラスを規定するのではなく、プロバイダー アノテーションも使用しました。

RequestFilter (ほぼ同じ):

package com.example.jaxrs;

import org.apache.log4j.MDC;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.UUID;

@Provider
public class TransactionIdentifierRequestFilter implements ContainerRequestFilter {

    @Override
    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());

    }
}

応答フィルタ:

package com.example.jaxrs;

import org.apache.log4j.MDC;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class TransactionIdentifierResponseFilter implements ContainerResponseFilter {

    @Override
    public void filter(ContainerRequestContext containerRequestContext, ContainerResponseContext containerResponseContext) throws IOException {
        MDC.clear();
    }
}

web.xml

<init-param>
    <param-name>jersey.config.server.provider.packages</param-name>
    <param-value>com.example.jaxrs</param-value>
</init-param>
于 2014-09-28T15:04:34.340 に答える
1

MDC は、 を使用して現在のスレッドに保持されますThreadLocal。フィルターに値を追加した場合は、サービス呼び出しの後にそれらを削除する必要があります。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
   try
   {

     //add your mdcs

     // proceed along the chain
     chain.doFilter(request, response);

  } 
  finally
  {

     //remove your mdcs

  }
}
于 2014-09-27T13:59:42.013 に答える
0

これは明らかに SLF4J の問題ではなく、Log4J の問題のみです。runtime修正された Log4J バージョンをスコープ付きの POM への直接の依存関係として追加すると、問題は解決するはずです。

于 2014-09-27T13:52:27.847 に答える