【经验】日志框架冲突排查与常规日志依赖梳理

发表信息: by Creative Commons Licence

字数:206 字, 预计阅读时间:2 分钟

背景

一次评论的需求上线,回归预发验证后,上线过程中总是偶发性的发布失败。

排查记录,略

排包提交清单:

  1. 强制指定 log4j-jcl 版本: 略
  2. 新引入包排包: 略
  3. 排除老包中 log4j-jcl依赖: 略
  4. 全局排除老包中 slf4j-log4j12 依赖: 略

异常结论

1. 迭代过程中引入新的依赖,导致依赖树发生变化
2. 历史隐藏的日志冲突导致偶发性的日志循环依赖启动异常(回归、预发启动正常,线上机器部分启动正常)

本次细节相关

  1. jcl-over-slf4j 和 log4j-jcl 不能同时存在,否则容易造成类找不到等问题。
    • 高版本的 log4j-core 拿掉了 log4j-jcl,如果 log4j-core 和 log4j-jcl 不一致,会造成 ClassNotFound 启动异常
  2. slf4j-log4j12 和 log4j-slf4j-imp 不能同时存在,否则容易出现循环依赖问题。
    • 多绑定冲突: org.slf4j.spi.LoggerFactoryBinder 接口自己项目中查看实现类有多个 启动异常

知识点

常规的日志框架如下,若以 log4j2 为主(绿色部分):

日志框架

区分 log4j 和 log4j2

  1. log4j 主要实现在 log4j:log4j.jar
  2. log4j2 的依赖实现主要在 apache 的 log4j-apilog4j-core 两个包内

日志接口规范(slf4j)

  1. java 日志的通用 api: slf4j-api(Simple Logging Facade for Java)
    • 绑定 slf4j 主要是通过实现 slf4j-api 里面定义的 org.slf4j.spi.LoggerFactoryBinder 接口
  2. log4j 绑定 slf4j: slf4j-log4j12(与 5 互斥)
  3. Log4j2 绑定slf4j: log4j-slf4j-impl(与 4 互斥)

主日志框架之外的日志框架桥接

  1. log4j 的 api 桥接到 Log4j2 输出: log4j-1.2-api
    • 防止有些三方包使用了 log4j,将日志也桥接到 Log4j2
  2. log4j 桥接到 slf4j: log4j-over-slf4j
  3. log4j2 桥接到 slf4j: log4j-to-slf4j(如果以 log4j2 实现绑定 slf4j,则不需要桥接)
  4. jcl 桥接到 slf4j: jcl-over-slf4j
    • jcl 全称为 Jakarta Commons Logging,是 Apache 提供的一个通用日志 API(commons-logging)
    • commons-logging 可能有两个 jar,分别是 commons-logging: commons-logging 和 org.apache.commons:commons-logging,都需要排掉
  5. jul 桥接到 slf4j: jul-to-slf4j
    • java.util.logging.Logger(JDK)

相关资料

  1. 公司日志框架各个包的作用: 公司文档-略
  2. 日志框架之间的桥接和依赖: https://codeantenna.com/a/aW5ov78Flk
  3. Jar包冲突检查工具: 公司文档-略
  4. 日志输出的疑难杂症: 公司文档-略
邀请标记你的阅读体验😉 | →