我正在使用 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
TL;DR 您可能想使用:
try (MDCCloseable unused = MDC.putCloseable(DEFAULT_MDC_KEY, breadcrumbValue)) {
try {
...
} catch (Exception e) {
...
}
}
首先感谢您关注警告:根据我的经验,这是当今的一项罕见技能。
SLF4J的
MDC
提供了两种方法:
MDC.popByKey/pushByKey/getCopyOfDequeByKey
方法(参见 SLF4J-531)。它们提供对每个线程的访问Map<String, Deque<String>>
。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 目前不有一个转换模式,允许用户显示上下文双端队列映射的值。因此,使用旧方法可以让您独立于日志记录实现。