java - 如何确定该请求是否不是 Filter 中的初始请求?

标签 java logback slf4j servlet-filters mdc

我正在尝试执行以下操作: 修改 logback 以在日志行上写出用户 id 和请求 id。 例如

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 中。例如(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

最佳答案

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

编辑:另一个想法是将过滤器映射到“/*”,但在您的 doFilter 方法中,不要 MDC 任何在 URL 中包含“swagger”的请求。您可能需要进行试验,并可能包含从 Swagger 页面生成的所有 URL,因为有些 URL 中可能不包含“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();
    }
}

关于java - 如何确定该请求是否不是 Filter 中的初始请求?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47478932/

相关文章:

java 数组排序

java - 为什么Throwable::printStackTrace持有PrintStream锁并导致回退死锁

tomcat - 重新部署时使用 Janino + Logback + Tomcat 的 sun.reflect.MethodAccessorImpl 的 ClassNotFoundException

java - 记录改造到 Logback 记录器

java - 使用 Maven 切换 SLF4J SimpleLogger 属性文件

logging - 如何以编程方式禁用Jetty 9日志记录?

java - 在struts 1.x中导出为pdf

java - system.out.println 的时间复杂度

java - 悲观锁无法使用 spring data jpa

java - 滚动 logback 日志记录不起作用