slf4j-api下的log4j与logback包冲突

1 问题描述#

千丁洗衣项目qd-laundry工程在部署到线上服务器时,由于会存在memcached的心跳机制,不断的有心跳日志输出,且日志级别为DEBUG,导致每天的日志文件都非常大,大概在27G左右。所以必须要关掉memcached的心跳日志输出。

2 排查过程#

  1. 问题重现:在DEV环境,确定Slf4j与Log4j Jar包依赖是否正确;【结果:Jar包依赖无问题】
  2. 确定log4j.xml的日志级别,全部改成INFO,不存在DEBUG。【结果:memcached的心跳日志仍输出】
  3. 查看启动日志,确定Log4j加载的log4j.xml是否正确。【结果:确实加载正确的log4j.xml】
  4. 确定是否依赖其他具体日志实现的Jar包。【结果:在POM依赖中,有平台Jar包依赖了logback】
    
        com.qding.basis.user
        api
    
    # 其api的POM中又依赖了logback:
    
        ch.qos.logback
        logback-classic
    

3 解决方案#

  • 修改POM文件去掉logback的依赖,或者排除掉logback依赖。
    
        com.qding.basis.user
        api
        
            
                ch.qos.logback
                logback-classic
            
            
                ch.qos.logback
                logback-core
            
        
    
  • 在此再罗嗦一下,简单说一下Mvn工程Pom文件中dependency之间各jar包版本的依赖关系:
  1. pom文件的依赖按声明顺序上到下读取,即先声明的优先,例如:pom文件中依赖的声明顺序由上向下为:
dependency:A(1.0.1)
dependency:A(1.0.2)

那么系统依赖肯定是依赖A1.0.1,因为该依赖最先被声明,后面的被Omitted(忽略)。

  1. 对于间接依赖,采用最短路径优先算法,距离短的被采用, 其中“—”表示间接依赖:
A—B—C—D(1.0.0)
F—E—D(1.0.1)

其中A间接依赖B,B又间接依赖C,C又间接依赖D,此时路径距离为3;另一个依赖:F间接依赖E,E间接依赖D,此时路径为2;根据最短路径优先原则,会依赖F-E-D(1.0.1)中的D(1.0.1)版本。

  1. 对于间接依赖路径长度相同的,谁先声明选谁,和A的规则是一样的:
A—B—C—D(1.0.0)
F—E—K—D(1.0.1)

路径长度相同,先声明者优先选取,肯定选取D(1.0.0)。

4 问题总结#

  • 对于排除同个jar包多个版本的冲突问题:

首先搞清楚各个Jar包之间的依赖关系:对于用eclipse工具的mvn工程,可以直接查看pom文件中的dependency Hierarchy或者用命令 mvn dependency:tree将依赖关系展现出来,这样就知道哪个间接的版本有问题;

然后选择合适的版本,剔除不想要的版本**通常是高版本优先**,可以在Pom文件中比较靠前的位置显示声明一个高版本,或者排除某个低版本依赖;

  • 当Slf4j下同时存在log4j和logback包时,会存在多个StaticLoggerBinder类冲突,Slf4j会随机选择一个StaticLoggerBinder加载生成实例。

你可能感兴趣的:(slf4j-api下的log4j与logback包冲突)