slf4j 始终使用 NOPMDCAdapter

slf4j always use NOPMDCAdapter

提问人:Wizzard 提问时间:1/16/2013 更新时间:6/18/2021 访问量:1877

问:

我使用 slf4j 登录我的项目。我想使用 MDC 来记录用户 ID 参数。所以我检查教程和文档,并编写如下代码:

MDC.put("key", userId)

userId 实际上是一个字符串。

我使用我通常的 log4j xml 和 appenders 等属性。添加 %X{key},但没有任何反应。我根本没有看到任何代替 %X{key} 的东西,但其他参数(如 %-5p 或 %c)效果很好。

所以我使用 debug 来观察 MDC.put() 方法中发生的事情,并发现在 MDC 的初始化中使用:

MDCAdapter mdcAdapter;
mdcAdapter = StaticMDCBinder.SINGLETON.getMDCA();

IDEA 中的调试显示它具有“Log4jMDCAdapter”,类似于 MDCAdapter 的实现之一。 但是后来我看了一下 StaticMDCBinder,有这样的代码:

public MDCAdapter getMDCA() {
   return new NOPMDCAdapter();
}

那么 slf4j 怎么可能使用适当的适配器(例如 log4j)初始化 MDC ???我不明白。因为它总是使用 NOPMDCAdapter,所以它不能在 MDC 中存储任何内容,也不能在日志记录中显示它。我该如何解决它??

在类路径中,我有:

  • log4j-1.2.16.jar
  • slf4j-api-1.6.1.jar
  • slf4j-api-1.6.2.jar
  • slf4j-jcl-1.6.2.jar
  • slf4j-log4j12-1.6.2.jar
Java 日志4j slf4j MDC

评论


答:

1赞 Wizzard 1/17/2013 #1

问题解决了。 它是对项目中使用的其他库的超越依赖。即slf4j-jcl,我将部分添加到maven pom中,现在它工作正常。

评论

0赞 granadaCoder 11/12/2020
你能再详细说明一下吗?您是否添加或排除“slf4j-jcl”?我有点困惑。
0赞 Wizzard 11/18/2020
@granadaCoder嗯,现在我真的不记得了,可能我添加了排除到错误的超验版本并添加到正确版本的显式依赖关系。
0赞 granadaCoder 11/20/2020
我终于弄清楚了我的问题。未来的读者可能想看看这个答案:stackoverflow.com/questions/64787265/......
2赞 malware 6/18/2021 #2

SLF4J 的 MDC 只是一个基于底层记录器切换适用的 MDC 实现的门面。如果它没有从记录器中找到任何合适的 MDCAdapter,它将回退到 NO-OP 适配器。 为此,它尝试查找名为 StaticMDCBinder 的类 https://github.com/qos-ch/slf4j/blob/v_1.7.25/slf4j-api/src/main/java/org/slf4j/MDC.java#L99

因此,在这种情况下,如@Wizzard的回答中所述,如果您的类路径中有两个 StaticMDCBinder 类,tomcat 将选择其中一个。

slf4j-simple 确实有一个 StaticMDCBinder,它默认为 NO-OP 适配器,因此删除 slf4j-simple jar 应该可以解决这里的问题。