大家好,我是头发还很多的阿星

明天来和大家聊聊Java日志体系,Java日志体系能够说是形形色色,目迷五色。

导致很小多搭档因为日志规范库之间简单的关系而感到懊恼,不晓得对立零碎的日志规范库须要依赖哪些jar包,百度一下所谓的博客,照着人家复制,却无奈弄懂原理,甚至还有搞了半天我的项目因jar抵触跑不起来的,心态间接爆炸。

咳咳,淡定淡定,别慌,阿星带你们弄懂其中的原理,只有你静下心,跟着本文来,再给个一键三连,你就能得心应手的更改日志规范库,对立日志输入。

发展史

咱们要正确的配置好日志,让jar互相失效,就要先理清关系,理清关系就得从它的发展史下手。

System.out和System.err

2001年以前,Java是没有日志库的,打印日志全凭System.outSystem.err,我人都傻了,非常离谱。

毛病如下:

  • 产生大量的IO操作 同时在生产环境中 无奈正当的管制是否须要输入
  • 输入的内容不能保留到文件
  • 只打印在控制台,打印完就过来了,也就是说除非你始终盯着程序跑
  • 无奈定制化,且日志粒度不够细

Log4j

此时名为Ceki的巨佬站进去,说你这个不好用,我这个好用,接着在2001年掏出了Log4j,用起来也的确比System系列香,Log4j一度成为业内日志规范。

起初Log4j成为Apache我的项目,Ceki也退出Apache组织(据说Apache还已经倡议Sun引入Log4jJava的规范库中,但Sun回绝了)。

JUL(Java Util Logging)

原来Sun也有本人的盘算,不就一个日志嘛,我本人也搞一个,20022JDK1.4公布,Sun推出了本人的日志规范库JUL(Java Util Logging),其实是照着Log4j抄的,而且还没抄好,还是在JDK1.5当前性能和可用性才有所晋升。

因为在JUL进去以前,Log4j就曾经成为一项成熟的技术,使得Log4j在抉择上占据了肯定的劣势。

JCL(Jakarta Commons Logging)

当初市面上有两款Java日志规范库,别离是Log4jJUL,此时Apache组织非常有想法,想对立形象日志标准接口标准(就像JDBC对立数据库拜访层),让其余日志规范库去实现它的形象接口,这样你的日志操作都是对立的接口。

于是JUL刚进去不久,20028Apache推出了JCL(Jakarta Commons Logging),也就是日志形象层,反对运行时动静加载日志组件的实现,当然也提供一个默认实现Simple LogClassLoader中进行查找,如果能找到Log4j则默认应用log4j实现,如果没有则应用JUL 实现,再没有则应用JCL外部提供的Simple Log实现)。

然而JUL有三个毛病

  1. 效率较低
  2. 容易引发凌乱
  3. 应用了自定义ClassLoader的程序中,应用JCL会引发内存泄露

总之就是问题也挺多~

Slf4j(Simple Logging Facade for Java)

2006年巨佬CekiLog4j的作者)因为一些起因来到了Apache组织,之后Ceki感觉JCL不好用,本人撸了一套新的日志标准接口标准Slf4j(Simple Logging Facade for Java),也能够称为日志门面,很显著Slf4j是对标JCL,前面也证实了Slf4jJCL更优良。

因为Slf4j进去的较晚,光有一个接口,没有实现的日志库也很蛋疼,如JULLog4j都是没有实现Slf4j,就算开发者想用Slf4j也用不了。

这时候巨佬Ceki发话了,SumApache这两个组织不来实现我的接口没关系,我来实现就好了,只有魔法能力战胜魔法。

前面巨佬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-apilog4j-corelog4j-api是日志接口,log4j-core是日志规范库,并且Apache也为Log4j2提供了各种桥接包。。。

到目前为止Java日志体系被划分为两大阵营,别离是Apache营垒和Ceki营垒,如下图所示

至于零碎中用那套体系,各位自行抉择,阿星集体偏差用Ceki提供的Slf4j那套

Slf4j的桥接包介绍

置信大家都对桥接包都有了基本概念,这里阿星列举下与Slf4j配合应用的桥接包

Slf4j转向某个日志规范库

  • slf4j-jdk14.jar

    • Slf4jJUL的桥梁
  • slf4j-log4j12.jar

    • Slf4jLog4j的桥梁
  • log4j-slf4j-impl.jar

    • Slf4jLog4j2的桥梁
  • slf4j-jcl.jar

    • Slf4jJCL的桥梁

某个理论日志框架转向Slf4j

  • jul-to-slf4j.jar

    • JULSlf4j的桥梁
  • log4j-over-slf4j.jar

    • Log4jSlf4j的桥梁
  • jcl-over-slf4j.jar

    • JCLSlf4j的桥梁

小小实际

从事Java开发的搭档们都分明,Spring框架外部应用JCL做日志输入规范,可是我的项目应用Slf4j + Logback做日志输入规范,问题来了,怎样才能让我的项目内的Spring放弃对立日志输入规范呢?

其实非常简单,只须要引入正确的Slf4j桥接包,去除无用的日志组件即可。

阿星没骗你们吧,引入jcl-over-slf4j.jarjul-to-slf4j.jar问题就解决了,非常简略~

小结

本文到此就完结了,以上,阿星通过Java日志发展史一步一步的带大家理清Java日志间的关系,并抛出问题以及解决问题,置信看完后,大家不会再因为日志规范库之间简单的关系感到懊恼,同时也能知其所以然的对立日志规范。

对于我

这里是阿星,一个酷爱技术的Java程序猿,公众号 「程序猿阿星」</span> 里将会定期分享操作系统、计算机网络、Java、分布式、数据库等精品原创文章,2021,与您在 Be Better 的路上独特成长!

非常感谢各位小哥哥小姐姐们能看到这里,原创不易,文章有帮忙能够关注、点个赞、分享与评论,都是反对(莫要白嫖)!

愿你我都能奔赴在各自想去的路上,咱们下篇文章见