一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)
  3GhPEWWj90Of 2023年11月02日 53 0


今天来和大家聊聊Java日志体系,Java日志体系可以说是五花八门,眼花缭乱。

导致很多小伙伴因为日志标准库之间复杂的关系而感到烦恼,不知道统一系统的日志标准库需要依赖哪些jar包,百度一下所谓的博客,照着人家复制,却无法弄懂原理,甚至还有搞了半天项目因jar冲突跑不起来的,心态直接爆炸。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Apache

发展史

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

System.out和System.err

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



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Apache_02

缺点如下:

  • 产生大量的IO操作   同时在生产环境中 无法合理的控制是否需要输出
  • 输出的内容不能保存到文件
  • 只打印在控制台,打印完就过去了,也就是说除非你一直盯着程序跑
  • 无法定制化,且日志粒度不够细

Log4j

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



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Apache_03

后来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统一数据库访问层),让其他日志标准库去实现它的抽象接口,这样你的日志操作都是统一的接口。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Apache_04

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



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_开发语言_05

但是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更优秀。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_06

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



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Apache_07

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

后面巨佬Ceki提供了一系列的桥接包来帮助Slf4j接口与其他日志库建立关系,这种方式称为桥接设计模式。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_桥接_08

有了桥接包配合,其他的问题都迎刃而解,我们先看看有那些问题吧~



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_09

从上图可以看出,不同时期的项目使用的日志标准库不一样,我们以Slf4j接口作为划分线,考虑两个问题,一个是Slf4j之前的项目怎么统一日志标准,另一个是Slf4j之后的项目怎么统一日志标准。

先来看Slf4j之后的项目怎么统一日志标准,项目D、E都使用Slf4j接口,首先在代码层已经统一了,如果要做到日志标准统一也十分简单,直接替换日志标准库与对应的桥接包即可,就如下图所示



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_桥接_10

好家伙,Slf4j接口配合桥接包简直无敌了,灵活配置。。

再来看Slf4j之前的项目怎么统一日志标准,项目A、B、C都使用了不同的日志标准,所以它们的API不一样,如果要统一标准,首先就要改动代码,这样侵入太强了,难道就没有办法在不改代码的情况下,让A、B、C项目统一日志标准吗?

办法当然有,Slf4j接口能通过桥接包勾搭上具体的日志标准库,为什么日志标准库不能通过桥接包勾搭Slf4j接口呢?



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_java_11

你想把A、B、C项目都统一成Log4j日志输出,只需要做如下调整



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_12

是不是很简单,引入Slf4j与相关的桥接包,再引入具体的日志标准库,比如Log4j,就完成了3个项目的统一日志标准,对代码层是零入侵。

Logback

Ceki巨佬觉得市场上的日志标准库都是间接实现Slf4j接口,也就是说每次都需要配合桥接包,因此在2006年,Ceki巨佬基于Slf4j接口撸出了Logback日志标准库,做为Slf4j接口的默认实现,Logback也十分给力,在功能完整度和性能上超越了所有已有的日志标准库。

目前Java日志体系关系图如下



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_java_13

Log4j2

自从Logback出来后,可以说Slf4j+Logback组合如日中天,很冲击JCL+Log4j组合,Apache眼看有被Logback反超的势头。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_14

2012年,Apache直接推出新项目Log4j2不兼容Log4j),Log4j2全面借鉴Slf4j+Logback十分明显的抄袭嫌疑)。

因为Log4j2不仅仅具有Logback的所有特性,还做了分离设计,分为log4j-apilog4j-corelog4j-api是日志接口,log4j-core是日志标准库,并且Apache也为Log4j2提供了各种桥接包。。。


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



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_15

至于系统中用那套体系,各位自行选择,我个人偏向用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桥接包,去除无用的日志组件即可。



一文看懂 Java 那令人 X 疼的日志体系(文末送个书顺便)_Java_16

我没骗你们吧,引入jcl-over-slf4j.jarjul-to-slf4j.jar问题就解决了,十分简单~

小结

本文到此就结束了,以上,我通过Java日志发展史一步一步的带大家理清Java日志间的关系,并抛出问题以及解决问题,相信看完后,大家不会再因为日志标准库之间复杂的关系感到烦恼,同时也能知其所以然的统一日志标准。



《代码大全2(纪念版)》作为名家经典著作,是一本完整的软件构建手册,涵盖软件构建过程中的所有细节。

它从软件质量和编程思想等方面论述软件构建的各个主题,并详细论述主流的新技术、高屋建瓴的观点和通用的概念,还含有丰富而典型的程序示例。

本书所论述的技术不仅填补了初级与中高级编程技术之间的空白,同时还为程序员提供了一个有关编程技巧的信息来源。

《代码大全2(纪念版)》对经验丰富的程序员、技术带头人、自学的程序员及几乎不懂太多编程技巧的学生大有帮助。

无论是什么背景的读者,都可以通过阅读和领会本书,在更短的时间内更轻松地写出更好、更简洁和更优雅的程序。

【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  2Vtxr3XfwhHq   2024年05月17日   55   0   0 Java
  Tnh5bgG19sRf   2024年05月20日   110   0   0 Java
  8s1LUHPryisj   2024年05月17日   46   0   0 Java
  aRSRdgycpgWt   2024年05月17日   47   0   0 Java
3GhPEWWj90Of