大家好,我是头发还很多的阿星
明天来和大家聊聊 Java
日志体系,Java
日志体系能够说是形形色色,目迷五色。
导致很小多搭档因为日志规范库之间简单的关系而感到懊恼,不晓得对立零碎的日志规范库须要依赖哪些 jar
包,百度一下所谓的博客,照着人家复制,却无奈弄懂原理,甚至还有搞了半天我的项目因 jar
抵触跑不起来的,心态间接爆炸。
咳咳,淡定淡定,别慌,阿星带你们弄懂其中的原理,只有你静下心,跟着本文来,再给个 一键三连,你就能得心应手的更改日志规范库,对立日志输入。
发展史
咱们要正确的配置好日志,让 jar
互相失效,就要先理清关系,理清关系就得从它的发展史下手。
System.out 和 System.err
2001
年以前,Java
是没有日志库的,打印日志全凭 System.out
和System.err
,我人都傻了,非常离谱。
毛病如下:
- 产生大量的 IO 操作 同时在生产环境中 无奈正当的管制是否须要输入
- 输入的内容不能保留到文件
- 只打印在控制台,打印完就过来了,也就是说除非你始终盯着程序跑
- 无奈定制化,且日志粒度不够细
Log4j
此时名为 Ceki
的巨佬站进去,说你这个不好用,我这个好用,接着在 2001
年掏出了 Log4j
,用起来也的确比System
系列香,Log4j
一度成为业内日志规范。
起初 Log4j
成为 Apache
我的项目,Ceki
也退出 Apache
组织(据说 Apache
还已经倡议 Sun
引入 Log4j
到Java
的规范库中,但 Sun
回绝了)。
JUL(Java Util Logging)
原来 Sun
也有本人的盘算,不就一个日志嘛,我本人也搞一个,2002
年 2
月JDK1.4
公布,Sun
推出了本人的日志规范库 JUL(Java Util Logging)
,其实是照着Log4j
抄的,而且还没抄好,还是在 JDK1.5
当前性能和可用性才有所晋升。
因为在 JUL
进去以前,Log4j
就曾经成为一项成熟的技术,使得 Log4j
在抉择上占据了肯定的劣势。
JCL(Jakarta Commons Logging)
当初市面上有两款 Java
日志规范库,别离是 Log4j
与JUL
,此时 Apache
组织非常有想法,想对立形象日志标准接口标准(就像 JDBC
对立数据库拜访层),让其余日志规范库去实现它的形象接口,这样你的日志操作都是对立的接口。
于是 JUL
刚进去不久,2002
年 8
月Apache
推出了 JCL(Jakarta Commons Logging)
,也就是日志形象层,反对运行时动静加载日志组件的实现,当然也提供一个默认实现Simple Log
( 在ClassLoader
中进行查找,如果能找到 Log4j
则默认应用 log4j
实现,如果没有则应用 JUL
实现,再没有则应用JCL
外部提供的 Simple Log
实现)。
然而 JUL
有三个毛病
- 效率较低
- 容易引发凌乱
- 应用了自定义 ClassLoader 的程序中,应用 JCL 会引发内存泄露
总之就是问题也挺多~
Slf4j(Simple Logging Facade for Java)
2006
年巨佬 Ceki
(Log4j
的作者)因为一些起因来到了 Apache
组织,之后 Ceki
感觉 JCL
不好用,本人撸了一套新的日志标准接口标准 Slf4j(Simple Logging Facade for Java)
,也能够称为日志门面,很显著Slf4j
是对标 JCL
,前面也证实了Slf4j
比JCL
更优良。
因为 Slf4j
进去的较晚,光有一个接口,没有实现的日志库也很蛋疼,如 JUL
和Log4j
都是没有实现 Slf4j
,就算开发者想用Slf4j
也用不了。
这时候巨佬 Ceki
发话了,Sum
和 Apache
这两个组织不来实现我的接口没关系,我来实现就好了,只有魔法能力战胜魔法。
前面巨佬 Ceki
提供了一系列的桥接包来帮忙 Slf4j
接口与其余日志库建设关系,这种形式称为桥接设计模式。
有了桥接包配合,其余的问题都迎刃而解,咱们先看看有那些问题吧~
从上图能够看出,不同期间的我的项目应用的日志规范库不一样,咱们以 Slf4j
接口作为划分线,思考两个问题,一个是 Slf4j
之前的我的项目怎么对立日志规范,另一个是 Slf4j
之后的我的项目怎么对立日志规范。
先来看 Slf4j
之后的我的项目怎么对立日志规范,我的项目 D、E
都应用 Slf4j
接口,首先在代码层曾经对立了,如果要做到日志规范对立也非常简略,间接替换日志规范库与对应的桥接包即可,就如下图所示
好家伙,Slf4j
接口配合桥接包几乎无敌了,灵便配置。。
再来看 Slf4j
之前的我的项目怎么对立日志规范,我的项目 A、B、C
都应用了不同的日志规范,所以它们的 API
不一样,如果要统一标准,首先就要改变代码,这样侵入太强了,难道就没有方法在不改代码的状况下,让 A、B、C
我的项目对立日志规范吗?
方法当然有,Slf4j
接口能通过桥接包勾结上具体的日志规范库,为什么日志规范库不能通过桥接包勾结 Slf4j
接口呢?
阿星想把 A、B、C
我的项目都对立成 Log4j
日志输入,只须要做如下调整
是不是很简略,引入 Slf4j
与相干的桥接包,再引入具体的日志规范库,比方 Log4j
,就实现了3
个我的项目的对立日志规范,对代码层是零入侵。
Logback
Ceki
巨佬感觉市场上的日志规范库都是间接实现 Slf4j
接口,也就是说每次都须要配合桥接包,因而在 2006
年,Ceki
巨佬基于 Slf4j
接口撸出了 Logback
日志规范库,做为 Slf4j
接口的默认实现,Logback
也非常给力,在性能残缺度和性能上超过了所有已有的日志规范库。
目前 Java
日志体系关系图如下
Log4j2
自从 Logback
进去后,能够说 Slf4j+Logback
组合如日中天,很冲击 JCL+Log4j
组合,Apache
眼看有被 Logback
反超的势头。
于 2012
年,Apache
间接推出新我的项目 Log4j2
( 不兼容 Log4j
),Log4j2
全面借鉴 Slf4j+Logback
( 非常显著的剽窃嫌疑)。
因为 Log4j2
不仅仅具备 Logback
的所有个性,还做了拆散设计,分为 log4j-api
和log4j-core
,log4j-api
是日志接口,log4j-core
是日志规范库,并且 Apache
也为 Log4j2
提供了各种桥接包。。。
到目前为止 Java
日志体系被划分为两大阵营,别离是 Apache
营垒和 Ceki
营垒,如下图所示
至于零碎中用那套体系,各位自行抉择,阿星集体偏差用 Ceki
提供的 Slf4j
那套
Slf4j 的桥接包介绍
置信大家都对桥接包都有了基本概念,这里阿星列举下与 Slf4j
配合应用的桥接包
Slf4j
转向某个日志规范库
-
slf4j-jdk14.jar
Slf4j
到JUL
的桥梁
-
slf4j-log4j12.jar
Slf4j
到Log4j
的桥梁
-
log4j-slf4j-impl.jar
Slf4j
到Log4j2
的桥梁
-
slf4j-jcl.jar
Slf4j
到JCL
的桥梁
某个理论日志框架转向Slf4j
-
jul-to-slf4j.jar
JUL
到Slf4j
的桥梁
-
log4j-over-slf4j.jar
Log4j
到Slf4j
的桥梁
-
jcl-over-slf4j.jar
JCL
到Slf4j
的桥梁
小小实际
从事 Java
开发的搭档们都分明,Spring
框架外部应用 JCL
做日志输入规范,可是我的项目应用 Slf4j + Logback
做日志输入规范,问题来了,怎样才能让我的项目内的 Spring
放弃对立日志输入规范呢?
其实非常简单,只须要引入正确的 Slf4j
桥接包,去除无用的日志组件即可。
阿星没骗你们吧,引入 jcl-over-slf4j.jar
或jul-to-slf4j.jar
问题就解决了,非常简略~
小结
本文到此就完结了,以上,阿星通过 Java
日志发展史一步一步的带大家理清 Java
日志间的关系,并抛出问题以及解决问题,置信看完后,大家不会再因为日志规范库之间简单的关系感到懊恼,同时也能 知其所以然 的对立日志规范。
对于我
这里是阿星,一个酷爱技术的 Java 程序猿,公众号 「程序猿阿星」</span> 里将会定期分享操作系统、计算机网络、Java、分布式、数据库等精品原创文章,2021,与您在 Be Better 的路上独特成长!
非常感谢各位小哥哥小姐姐们能看到这里,原创不易,文章有帮忙能够关注、点个赞、分享与评论,都是反对(莫要白嫖)!
愿你我都能奔赴在各自想去的路上,咱们下篇文章见