DailyRollingFileAppender 不输出

最近接手了一个老项目,莫名其妙的就不输出日志了,然后翻了一下,里面啥日志框架都有,然后记录一下埋坑的过程。

1由于是一个SSH的项目,用的也是往lib包中添加jar包的方式,所以一开始就猜测是jar包冲突导致的log4j不被加载,因为log4j已经退出历史的舞台了,加上前端时间爆炸的bug,那个貌似是log4j2,因为老项目的日志很久没有升级过了。所以猜测是因为hibernate中自带的log4j2影响了项目的输出,后来发现是hibernate3,自带的非log4j2,而是slf4j,所以在想是不是这个地方影响到了。于是看了一下互转
============================以下内容为互转的内容===========================
原文连接:https://www.jianshu.com/p/d7b0e981868d

由于java日志框架众多(common-logging,log4j,slf4j,logback等),引入jar包的时候,就要为其添加对应的日志实现。。

不同的jar包,可能用了不同的日志框架,那引用了之后就得给不同的日志框架添加配置,这个是比较麻烦的。

slf4j就是为了解决这个麻烦事的。

slf4j全称为Simple Logging Facade for JAVA,java简单日志门面。类似于Apache Common-Logging,是对不同日志框架提供的一个门面封装,可以在部署的时候不修改任何配置即可接入一种日志实现方案。但是,他在编译时静态绑定真正的Log库。使用SLF4J时,如果你需要使用某一种日志实现,那么你必须选择正确的SLF4J的jar包的集合(各种桥接包)。

这个东西要用图才能说得清楚,借用官网一张图:

 

下载了slf4j的压缩包后,这里下的版本是slf4j-1.7.25.zip,里面有很多jar文件。

slf4j的核心包是slf4j-api-1.7.25.jar,需要配合日志实现,才能将日志绑定另一种输出。我们先看看slf4j里的jar包的作用.

jcl-over-slf4j.jar  -->    (jcl    -> slf4j)    将Jakarta Commons Logging日志框架到 slf4j 的桥接  
jul-to-slf4j.jar    -->    (juc    -> slf4j)    将java.util.logging的日志桥接到 slf4j  
log4j-over-slf4j.jar-->    (log4j  -> slf4j)    将log4j 的日志,桥接到slf4j  
osgi-over-slf4j.jar -->    (osgi   -> slf4j)    将osgi环境下的日志,桥接到slf4j  
slf4j-android.jar   -->    (android-> slf4j)    将android环境下的日志,桥接到slf4j  
slf4j-api.jar       -->                         slf4j 的api接口jar包  
slf4j-ext.jar       -->                         扩展功能  
slf4j-jcl.jar       -->    (lf4j -> jcl )          slf4j 转接到 Jakarta Commons Logging日志输出框架  
slf4j-jdk14.jar     -->    (slf4j -> jul )          slf4j 转接到 java.util.logging,所以这个包不能和jul-to-slf4j.jar同时用,否则会死循环!!  
slf4j-log4j12.jar   -->    (slf4j -> log4j)         slf4j 转接到 log4j,所以这个包不能和log4j-over-slf4j.jar同时用,否则会死循环!!  
slf4j-migrator.jar  -->                                       一个GUI工具,支持将项目代码中 JCL,log4j,java.util.logging的日志API转换为slf4j的写法  
slf4j-nop.jar       -->    (slf4j -> null)          slf4j的空接口输出绑定,丢弃所有日志输出  
slf4j-simple.jar    -->    (slf4j -> slf4j-simple ) slf4j的自带的简单日志输出接口  

这样整理之后,slf4j的jar包用途就比较清晰了。
目前个人遇到的项目里,一般还会有log4j和log4j2混用的问题。
因为log4j项目已经停止更新了,官方建议用log4j2。
然后,log4j2里也提供了对各类log的桥接支持,这里就只列举相关的几个jar包说明。

log4j-1.2-api.jar   -->    (log4j  -> log4j2)               将log4j 的日志转接到log4j2日志框架  
log4j-api.jar       -->                                     log4j2的api接口jar包  
log4j-core.jar      -->    (          log4j2 -> log4j-core) log4j2的日志输出核心jar包  
log4j-slf4j-impl.jar-->    (slf4j  -> log4j2)               slf4j 转接到 log4j2 的日志输出框架  (不能和 log4j-to-slf4j同时用)  
log4j-to-slf4j.jar  -->    (          log4j2 -> slf4j)      将 log4j2的日志桥接到 slf4j  (不能和 log4j-slf4j-impl 同时用)  

从这里就已经可以看到,日志框架之间的关系有点乱。
因为log4j2和slf4j都能对接多种日志框架,所以这些包的依赖,作用,还有命名,都容易让人混淆。

这里针对 log4j, log4j2, slf4j做一个简单总结。

log4j

这个最简单,单独使用jar包就一个,已经停止更新,当前最新版是 log4j-1.2.17.jar
只有输出功能,没有转接功能。
可以用

//    PropertyConfigurator.configure("conf/log4j.properties");  
//    DOMConfigurator.configure("conf/log4j.xml");  

来指定配置文件位置。

log4j2

同时有日志输出和转接功能。
单独使用时,jar包是 log4j-api-2.x.x.jar 和 log4j-core-2.x.x.jar
如果配置文件不在src目录,或者项目build Path 的source目录下,可以用以下代码指定配置文件位置:

String config = System.getProperty("user.dir");// 获取程序的当前路径
ConfigurationSource source = new ConfigurationSource(
    new FileInputStream(config + File.separator + "conf" + File.separator + "log4j2.xml"));
Configurator.initialize(null, source);

  // 以下代码是log4j已经加载配置的情况下,指定加载其他的配置
LoggerContext logContext = (LoggerContext) LogManager.getContext(false);
File conFile = new File("conf/logs/log4j2.xml");
logContext.setConfigLocation(conFile.toURI());
logContext.reconfigure();

log4j -> log4j2 桥接

去掉 log4j 1.x jar,添加log4j-1.2-api.jar,配合 log4j-api-2.x.x.jar 和 log4j-core-2.x.x.jar 即可,依赖如下

log4j-1.2-api.jar
    log4j-api-2.x.x.jar
        log4j-core-2.x.x.jar

log4j2 -> log4j 桥接

不建议。
本来log4j在2015年停止更新后,就建议转向log4j2,并提供了到log4j2的桥接接口。
所以反过来log4j2到log4j是不建议这么做的,log4j2也没有提供直接支持。
但理清了上面的jar包作用,就会发现,可以通过 log4j2 -> slf4j -> log4j 的方式来实现。

需要的jar包,根据依赖关系分别是:

log4j-api-2.x.x.jar
    log4j-to-slf4j.jar
        slf4j-api-x.x.x.jar
            slf4j-log4j12-x.x.x.jar
                log4j-1.2.17.jar

slf4j

同时有日志输出和转接功能。
核心jar包是 slf4j-api-x.x.x.jar
因为一般slf4j 只作为桥接用,如果要搭配 slf4j 自带的简单日志输出,那么就加上 slf4j-simple.jar

log4j -> slf4j

将代码中的log4j日志桥接到 slf4j,需要如下jar包

log4j-over-slf4j-x.x.x.jar
    slf4j-api-x.x.x.jar

log4j2 -> slf4j

将代码中的log4j2日志桥接到 slf4j,需要如下jar包

log4j-api-2.x.x.jar
    log4j-to-slf4j-2.x.x.jar
        slf4j-api-x.x.x.jar

slf4j -> log4j

将slf4j日志,采用log4j实现进行输出,需要如下jar包

slf4j-api-x.x.x.jar
    slf4j-log4j12.jar
        log4j-1.2.17.jar

slf4j -> log4j2

将slf4j日志,采用log4j2实现进行输出,需要如下jar包

slf4j-api-x.x.x.jar
    log4j-slf4j-impl.jar
        log4j-api.jar
            log4j-core.jar

slf4j的代理绑定和输出组合起来,就实现了从一种日志框架,转到另一种日志实现框架的效果。
建议在这三种日志混用的情况下,采用如下方案

log4j -> log4j2
slf4j -> log4j2


================================结束======================================
看了一下,发现我的项目中的jar包既有log4j转slf4j,也有log4j转log4j2的jar包,一头大包。只能从头捋了

第一个想法就是配置文件的地方没有放对,这个时候需要将配置文件的路径打印出来
1项目正常的头应该是web.xml

 这个地方有个log4j的初始化

看了一下是这么写的就是指定了配置文件,然后再这个地方输出,发现文件的路径是正确的,这个地方虽然是正确的,会不会是其他地方将这个配置文件覆盖了呢?

 

 在tomcat的输出参数中添加

-Dlog4j.debug

查看相关加载参数,发现还是没有问题,但是不显示输出,嗝屁了。

再去翻看相关LOG4J的源码
LOG4J_拉着猪逛街的博客-优快云博客
就是说流程肯定是在这个地方进来

 调用的这个方法

 在这个地方打断点,然后发现没进来,卧槽,这是走哪去了
后来发现这个地方

 进到了这个Category,发现这个logger根本不是log4j里的,一看文件位置,这个jar包叫
log4j-1.2-api-2.7
这个包是不是很熟悉,就上面转换用的

 当时想,怎么是这叼东西,是不是豁然开朗了,干掉他就行了,包冲突不可怕,找不出来才尴尬,突然发现包管理工具的重要性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值