关于java:5分钟搞定混乱的Java日志体系

42次阅读

共计 3372 个字符,预计需要花费 9 分钟才能阅读完成。

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

明天来和大家聊聊 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 的路上独特成长!

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

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

正文完
 0