【问题标题】:Logback sfl4j MDC unique for http requestLogback sfl4j MDC 对 http 请求唯一
【发布时间】:2018-04-24 01:13:09
【问题描述】:

我正在使用 Sping Boot 1.5.7。该应用程序提供 API Restful。 我有一个过滤器,我在其中使用用户名和事务 ID 设置 MDC。

    MDC.put("user", authentication.getPrincipal().toString());
    MDC.put("trans-id",authentication.getTokenId());

我希望每个请求都有一个 MDC 映射,而不是 MDC 数据在不同请求之间共享。

你能帮帮我吗?谢谢。

更新:

每一行下面的日志都是一个http请求:

2017-11-10 21:34:52.867 | user=USER, trans-id=c28f4b68-b5f3-4b5c-9bb5-f18ba9d1cd7d, session-id=daaddaadda |   INFO 976 - [tp1005246661-89] i.e.h.controller.IsAliveController       : /isAlive WSC | 

2017-11-10 21:34:59.551 | user=USER, trans-id=4a0eaec1-184a-4587-8fce-ab013ad6539b, session-id=daaddaadda |   INFO 976 - [tp1005246661-89] i.e.h.controller.IsAliveController       : /isAlive public | 

在第二个请求中,我只设置了 trans-id,而不是在 MDC 映射中,在第一个请求中设置了 session-id 和用户。

【问题讨论】:

    标签: java spring-boot logging logback mdc


    【解决方案1】:

    我假设您使用 logback 作为日志记录实现,并且在任何时间点,一个线程正在处理一个请求直到完成。根据documentation,MDC 已经存储在每个线程中,因此它足以满足您的用例。在我们的项目中,我们使用 MDC 来跟踪线程 ID(不是线程名称)以进行调试,它按预期工作

    MDC 以每个线程为基础管理上下文信息。通常,在开始为新的客户端请求提供服务时,开发人员会在 MDC 中插入相关的上下文信息,例如客户端 ID、客户端 IP 地址、请求参数等

    【讨论】:

    • 我已经用更多信息更新了我的帖子。谢谢。
    • 明白。您可以在 spring 拦截器中清除 MDC 值。覆盖 HandlerInterceptorAdapter#preHandle 可能就足够了
    • 你有例子吗?
    • 当然,我只是快速测试一下。它似乎工作正常
    • 好的。我会试试看。现在我在第一次初始化之前已经清除了 MDC 映射。似乎工作正常。谢谢
    【解决方案2】:

    这是示例配置类

    @Configuration
    public class SpringConfig extends WebMvcConfigurerAdapter {
        private static final Logger LOG = LoggerFactory.getLogger(SpringConfig.class);
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new HandlerInterceptor() {
            @Override
            public boolean preHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o) throws Exception {
                LOG.info("Inside pre-handle");
                MDC.clear();
                return true;
            }
    
            @Override
            public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
            }
    
            @Override
            public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception 
    {
    
            }
        });
    }
    }
    

    【讨论】:

    • 谢谢。拦截器在过滤器之前开始?
    • 没错,对于每一个传入的请求,MDC都会先被清空,才会来到实际的请求处理程序
    • 我会试试的。谢谢
    • @Apolozeus perhpas 您应该编辑您的other answer(通过单击答案下方的edit 链接)而不是发布同一问题的第二个答案?
    • @Apolozeus 在我的情况下,我在过滤器中插入了 MDC.clear()。 Filter 在 Interceptor 之前执行。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-07
    • 1970-01-01
    • 1970-01-01
    • 2020-06-09
    • 2017-07-13
    相关资源
    最近更新 更多