如何确定请求是否不是过滤器中的初始请求?

时间:2017-11-24 19:14:06

标签: java logback slf4j servlet-filters mdc

我要做的是以下内容: 修改logback,在日志行中写出用户id和request id。 e.g。

2017-11-24 [userid:abcd123 - requestId:12345679] [ClassA:MethodA1] message...
2017-11-24 [userid:abcd123 - requestId:12345679] [ClassA:MethodA2] message...
2017-11-24 [userid:abcd123 - requestId:12345679] [ClassB:MethodB1] message...

请注意,requestId保持不变,因为它是最终用户向系统发出的一个请求的全部内容。

我创建了一个基于几个示例的过滤器,其中显示了如何将值设置到MDC中。 e.g(https://logback.qos.ch/manual/mdc.html 1

...
@Component
public class RequestFilter implements Filter {

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        try {
            String mdcData = String.format("[userId:%s | requestId:%s] ", user(), requestId());
            MDC.put("mdcData", mdcData); //Referenced from logging configuration.
            chain.doFilter(request, response);
        } finally {
            MDC.clear();
        }
    }

    private String requestId() {
        return UUID.randomUUID().toString();
    }

    private String user() {
        return "tux";
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void destroy() {
    }
}
...

如果我向休息服务发出请求,它会执​​行一次,而系统不会向系统发出任何其他请求以获取信息。这是我所期望的,我可以看到它们都包含相同requestId的日志条目。 如果我向其中一个Swagger页面发出浏览器页面请求,那么该网页会对页面上显示的其他信息进行多次内部请求。由于页面需要呈现的所有其他信息请求,日志记录捕获了加载网页请求所产生的大约20个请求。当发生这种情况时,我最终得到X个日志条目,其中每个内部请求都生成一个唯一的请求,并为每个请求记录requestId。这不是我的意图。

如何通过内部请求调用向系统请求启动部分?

我不需要一遍又一遍地为requestId设置MDC值。我只需要根据从外部用户发出的第一个请求,每次调用设置一次。

甚至不确定除了请求的生命周期之外你会称之为什么,但我找不到答案。

感谢任何指导。感谢。

编辑:链接到我在那里的另一个问题,该问题仅涉及识别original user request

1 个答案:

答案 0 :(得分:1)

解决此问题的一种方法是将RequestFilter映射到您要记录的服务的URL模式,而不是#34; / *"。

编辑:另一个想法是将过滤器映射到" / *"但是在你的doFilter方法中,请不要MDC任何包含" swagger"在URL中。您可能需要尝试并可能包含从Swagger页面生成的所有网址,因为有些网址可能不包含单词" swagger"在他们中间。

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

    if (isRequestSwaggerUrl(request)) {
        chain.doFilter(request, response);
        return;
    }

    try {
        String mdcData = String.format("[userId:%s | requestId:%s] ", user(), requestId());
        MDC.put("mdcData", mdcData); //Referenced from logging configuration.
        chain.doFilter(request, response);
    } finally {
        MDC.clear();
    }
}