我使用 slf4j 登录我的项目。我想使用 MDC 来记录用户 ID 参数。所以我检查教程和文档,并编写如下代码:
MDC.put("key", userId)
userId 实际上是一个字符串。
我使用常用的 log4j xml 以及附加程序等属性。添加 %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 中存储任何内容,也无法在日志记录中显示它。我该如何解决它??
在类路径中我有:
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 应该可以解决这里的问题。
问题解决了。 它是对项目中使用的其他库的超越依赖。即slf4j-jcl,我将部分添加到maven pom中,现在可以正常工作了。