警告 StatusConsoleListener 密钥 MDC_KEY 在字符串和堆栈值 MDC 中都使用了

问题描述 投票:0回答:1

我正在使用 slf4j v2.0.9 和 log4j v2.21.1。

MCD 日志按预期工作,但我还收到以下警告。

警告 StatusConsoleListener 密钥 MDC_KEY 在字符串和堆栈值 MDC 中均使用。

除了设置日志记录的值之外,我还读取 MDC 值以获取该值,以便我可以将其传递给下一个 REST 请求。在 log4j.xml 文件中,我使用以下模式来写入 MDC 值 --> %X{MDC_KEY}

在我正在使用的代码中

public static final String DEFAULT_MDC_KEY = "MDC_KEY";


@Override
   protected void doFilterInternal(final HttpServletRequest request, final HttpServletResponse response, final FilterChain filterChain) throws ServletException, IOException
   {
     try
     {
        //...
        MDC.pushByKey(DEFAULT_MDC_KEY, breadcrumbValue);
        //...
     }
     catch(Exception ex)
     {
        //... 
     }
     finally
     {
         MDC.clear();
     }
   }

在另一个类中,我正在检索设置的值。

 MDC.get(DEFAULT_MDC_KEY)

什么可能导致警告? 有什么办法可以抑制警告吗?

谢谢, MH

log4j slf4j mdc
1个回答
0
投票

TL;DR 您可能想使用:

try (MDCCloseable unused = MDC.putCloseable(DEFAULT_MDC_KEY, breadcrumbValue)) {
    try {
        ...
    } catch (Exception e) {
        ...
    }
}

首先感谢您关注警告:根据我的经验,这是当今的一项罕见技能。

SLF4J的

MDC
提供了两种方法:

  • 2.x 中引入的
    MDC.popByKey/pushByKey/getCopyOfDequeByKey
    方法(参见 SLF4J-531)。它们提供对每个线程的访问
    Map<String, Deque<String>>
  • SLF4J 1.x 中的
    MDC.get/put/putCloseable/getCopyOfContextMap
    方法。 尽管 Javadoc 中并不清楚,但该映射的默认实现与上下文双端队列映射不同

为了在 SLF4J API 和 Log4j API 之间的桥梁中实现这些功能(参见LOG4J2-3583)而不扩展Log4j API,我们决定将上下文映射和上下文双端队列映射映射到单个

Map<String, Object> 
ThreadContext
提供。

这就是为什么这两个地图都可以通过

%X{...}
模式转换器访问。

但是,为了防止用户使用

MDC.set
错误地覆盖整个堆栈,当上下文映射和上下文双端队列映射中使用相同的键时,我们会发出警告。

要消除警告不要对不同组的方法使用相同的键。我建议使用支持更好的

MDC.get/put/putCloseable
方法。

备注:据我所知,Logback 目前有一个转换模式,允许用户显示上下文双端队列映射的值。因此,使用旧方法可以让您独立于日志记录实现。

© www.soinside.com 2019 - 2024. All rights reserved.