Q 业务系统在作发布前检查工做时,发现一台单机的主日志没有打印,而其余生产机器的日志表现则是正常的。api
经过 greys 观察主 service 的业务入口,发现该机器线上流量的请求接受、逻辑处理、结果反馈均正常。排查范围就聚焦在 log jar 配置上。spa
研究了一下 slf4j-log4j12 实现绑定的原理——简单来讲,日志输出到单机本地,须要如下 3 类 jar 包相互配合:日志
具体到代码实现上,就是经过 StaticLoggerBinder.getSingleton ( ) 方法返回的单例,实现包的绑定 ——blog
qjt 程序中,同时存在着两类绑定包:log4j-slf4j-impl-2.7.jar 和 slf4j-log4j12-1.7.2.jar。这实际是一种意义上的日志绑定包冲突 —— 选定哪一个包,取决于 ClassLoader 先加载哪一个,具备必定的随机性。接口
核心:slf4j-log4j12 意指 slf4j 底层桥接到 log4j;log4j-slf4j-impl 意指 log4j 底层桥接到 slf4j。经过机器本地 lib 库也能够看到,qjt 用的 facade 是 log4j。因此若是 classloader 先加载了 slf4j-log4j12 的话,就会没法打印日志 —— 由于 log4j 找不到具体的桥接实现了。ip
再来看一下 slf4j-log4j12-empty_version.jar 是什么东东。经过观察它的包结构,能够看到实际上是 slf4j 绑定包的空实现,由此排掉了其余 jar 包引入的 slf4j-log4j12 实现。ssl
叙述到此,能够发现正是 ClassLoader 随机加载两类绑定包的不一样,从而致使了日志打印表现的不一样。为了不该状况,强烈建议各位同窗排查是否存在绑定包的冲突。部署