7

ここrequestIdに示すように、Web アプリのログにを追加しようとしています。

public class MDCFilter implements ContainerRequestFilter, ContainerResponseFilter
{
    private static final String CLIENT_ID = "client-id";

    @Context
    protected HttpServletRequest r;

    @Override
    public void filter(ContainerRequestContext req) throws IOException
    {
        Optional<String> clientId = Optional.fromNullable(r.getHeader("X-Forwarded-For"));
        MDC.put(CLIENT_ID, clientId.or(defaultClientId()));
    }

    @Override
    public void filter(ContainerRequestContext req, ContainerResponseContext resp) throws IOException
    {
        MDC.remove(CLIENT_ID);
    }

    private String defaultClientId()
    {
        return "Direct:" + r.getRemoteAddr();
    }
}

これに関する問題は、上記のフィルターで設定および削除する requestIdことです。MDCまた、アプリケーションが生成する応答の本文もWriterInterceptor. 問題は、インターセプターが filtersの後に実行されるため、 myWriterInterceptorが実行されるまでに requestId が にないことですMDC

MDC.clear()私の質問は、最後に呼び出しても大丈夫ですWriterInterceptorか (これはなんとなくハックに感じます)、またはこれを達成するためのより良い方法はありますか?

4

1 に答える 1

0

私は同じ問題を抱えています。これは、私が開発しているコードで現在どのように機能するかです

@Order(Ordered.HIGHEST_PRECEDENCE)
public final class RequestFilter implements Filter {
  @Override
  public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    try {
      //stuff
      chain.doFilter(request, response);
    } finally {
      // this clears a specific entry from the MDC but not the entire MDC
      RequestContext.clear();
    }
  }
}

ここでは、finally ブロックで MDC 全体をクリアできますが、Spring がいつ例外をログに記録するかはわかりません。クリアするのが早すぎますか?私の新しい計画は、リクエストを開始するときに MDC をクリアすることです。

これが完全な答えかどうかはわかりませんが、優先順位が最も高いフィルターで MDC をクリアするとうまくいくはずです。

于 2019-06-27T15:51:36.677 に答える