java - slf4j 总是使用 NOPMDCAdapter

标签 java log4j slf4j mdc

我使用 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 中存储任何东西,也不能在日志记录中显示它。我该如何解决??

在类路径中我有:

  • 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

最佳答案

SLF4J的MDC只是一个门面,可以根据底层logger来切换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 确实有一个默认为 NO-OP 适配器的 StaticMDCBinder,因此删除 slf4j-simple jar 应该可以解决这里的问题。

关于java - slf4j 总是使用 NOPMDCAdapter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14358889/

相关文章:

tomcat - Apache Tomcat 中的每个应用程序系统属性

java - 将 log4j2 与 slf4j 一起使用 : java. lang.StackOverflowError

java - GCM Android 客户端未触发 WakefulService?

java - Java - 方法是 - parse Byte(String s, int radix) - 我无法理解

java - kafka-log4j-appender 0.9.0.1 省略了错误的可抛出信息

java - Velocity 中 SimpleLogger (SLF4j) 的配置错误

java - 使用 PowerMock 和 Mockito 模拟 Logger 和 LoggerFactory

java - 访问动态壁纸服务类中的子方法

java - 如何使Java ServiceActivator在JUnit Test中可见?

java - Log4j configureAndWatch() 产生数千个线程