java log4j logback jcl_java日志框架

接口规范:

  • commons-logging (Jakarta Commons Logging 、jcl ),它会默认去找log4j和jul(java.util.log包 jdk1.4之后)
  • slf4j ( Simple Logging Facade For Java),logback直接实现了这个接口
  • jboss-logging

接口实现的框架:

  • log4j 一个完整的日志框架,可以直接使用
  • logback 实现了 上面的slf4j接口
  • jul jdk1.4以后 java.util.log下提供的日志实现
  • log4j2
  • slf4j-nop
  • slf4j-simple
  • 别的我也不知道了

使用接口的好处,不要让项目太依赖一个日志框架

官网提供了一张图清晰的描述了这个过程

1abce20079b3dcfa44db64e1f180a17b.png

slf4j-api的maven地址

<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->

注意这里是没有具体实现的!

当我们直接使用

private 

2238f5a96ec56316d2feaeb03de3fadf.png

说明要加入一个具体的实现类,具体怎么加,就看上面那张图就好了。

注意,logback是默认实现slf4j接口的,所以它不需要适配器!(图中只有两层)

比如,我想使用logback,对应的maven

<!-- 这样一个就好了,会自动引入logback-core包,具体的logback包自己上网查下哈 -->        

在比如,我想使用log4j,log4j没有实现slf4j接口,所以需要一个适配器

<!-- 适配器 -->

(版本自己注意,我随便网上抄的)

可以看看这个适配器的包做了啥,看看包结构

9cd00544c34c3c064d4c63f125010e94.png

实现了`StaticLoggerbinder`这个类哦,注意这里引入多个实现类的时候会报错。

bed3f54f42f098dda230fb11b8bd1aad.png

看下这个适配包做了啥吧,可以自己debug做一下

它的总体思路就是

90710f5253acb97e9ef36999f643b2cb.png

在Log4jLoggerFactory中,使用log4j中的org.apache.log4j.LogManager获取了log4j的日志对象了。(就是org.slf4j:slf4j-log4j这个包,调用了log4j:log4j这个包的内容了)

包装一下,返回这个适配器,之后我就可以在这个适配器中调用log4j的方法了。

2ea90a9a167bb4a6b07ad49b50bf7b7b.png

还有一种桥接包,使用的情况:

我现在的项目使用了某个日志框架,我想使用slf4j,提供反转的在作用。

注意和上面的正向适配过程的区别,上面的是我还没开始做项目,我决定使用slf4j + log4j 来写代码。

但是在旧的项目中,已经存在了大量的使用log4j的代码,这是没有办法改变的。

官网也有一个图。

15c22cff4fc191333cf1877a27747b1e.png

举个例子

0ff4692f1fda6f28ea454e70a9745a17.png

我首先要做的引入jar包,同时将原来的log4j的包移除。(可以看出来,这个log4j-over-slf4j包相当于欺骗了slf4j,原来的代码中调用了log4j:log4j包中的,现在变成调用了org.slf4j:log4j-over-slf4j中的了

<!--         https://mvnrepository.com/artifact/ch.qos.logback/logback-classic-->
        

可以debug看下它究竟干了啥

c5224e93c9678e433918a853a10c40c7.png

现在原来log4j的代码都执行到log4j-over-slf4j中了。

秘密就在于这里的new Logger(),这个Logger也是这个包的中 的,它继承了一个类 Catagory

这个类在初始化的时候

3f5f2e2dfd99d5867dfa07fa5bd24a7b.png

其实就已经设置好了slf4j的实现对象。slf4jLogger 对象,其实就是logback包里面的了。

这里说下LoggerFactory.getLogger(name)这个原理,这个是slf4j-api.jar里面的方法,它的本质就是引入 import org.slf4j.impl.StaticLoggerBinder;
我们知道实现了slf4j的包都会有这个对象,那么随后
里面这句代码很重要:
StaticLoggerBinder. getSingleton().getLoggerFactory();
这句代码让流程从 slf4j-api包 --> slf4j的实现包 (可能是桥接包或者直接实现的logback包)
return iLoggerFactory.getLogger(name);
得到的对象就是logback包里的啦

347a67aac9403bf23a2eb3d5acaf574e.png

此后我们在调用的时候,调用其实就是这里面Catagory属性中的上slf4j中的东西了。

这里要注意,我们将原来log4j代码全部交给log4j-over-slf4j执行了,其实就是移交给slf4j-api执行了,这个api要寻找实现类,如果这个时候我们在使用slf4j-log4j12作为实现,那么可以会造成踢皮球的现场导致栈溢出,具体的原因可以看看最下方的参考链接。

比如 log.trace()的时候。

b1fa8fcd20a27cead47dabd7799582d2.png

e5f3caeacb285bb49b5f7e37597ad2a1.png

92e848ba0047641dbceb878c42225c7f.png

可以看出来,这个logger其实就是logback包中的log了。

总结一下:

  1. 两类桥接包,一种给新项目使用,一种给旧项目使用。
  2. 通常使用的接口只有commons-logging 和 slf4j,commons-logging经常和log4j使用,slf4j经常和logback使用。
  3. 答案都在源码里。

参考链接:

log4j-over-slf4j与slf4j-log4j12共存stack overflow异常分析

SpringBoot日志框架的选择及使用原理_爆发的~小宇宙的博客-CSDN博客_springboot 日志框架

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值