从MDC清除requestId的位置

gar*_*560 6 java jax-rs filter interceptor mdc

我想要一个添加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();
    }
}
Run Code Online (Sandbox Code Playgroud)

这样做的问题是,它设置和删除 requestIdMDC上述过滤器.我还记录了我的应用程序生成的响应的主体WriterInterceptor.问题是,因为拦截器在过滤器之后运行,所以当我WriterInterceptor执行时,没有requestId MDC.

我的问题是,是否可以MDC.clear()在结束时打电话WriterInterceptor(感觉某种程度上是hacky),还是有更好的方法来实现这一目标?

dus*_*van 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();
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

可以在这里的finally块中清除整个MDC...但我不知道Spring何时记录异常。我会不会太早清算?我的新计划是在开始请求时清除 MDC。

我不确定这是否是完整的答案,但清除最高优先级过滤器中的 MDC 应该可行。