搜索 K
Appearance
博客正在加载中...
Appearance
不自己造轮子
在前面我们介绍了什么是日志,以及日志的重要性,一般项目中都会用到,并介绍了 print 大法的缺点,怎么解决呢?我们可以自定义一个工具类,专门用于处理日志,取代 sout。这样有几个优点
总之就是很多,工作中也几乎是必用的技术。 很可惜,在早期,Java 是没有提供相关的功能的。当时大部分人都是用 Java 的打印语句:System.out 和 System.err。 这应该是最早的日志记录方式吧,但是不灵活也不可配置,要么就是全部打印,要么就是全部不打印,没有一个统一的日志级别 直到 Java1.4 才有了相关的功能;在这之前,业内已经有不少成熟的日志框架了,几乎很少会用到 Java 提供的日志功能了。
Log4j,全程是 Log for Java,意指 Java 用的日志框架。官网:Apache Log4j
4 是和 for 谐音,在英语中不少这样的谐音。例如 P2P 中,2 是指 to,P2P 全称 Peer to Peer
在 1996 年初,E.U.SEMPER(欧洲安全电子市场)项目决定编写自己的跟踪 API,最后该 API 演变为 Log4j,Log4j 日志软件包一经推出就备受欢迎,当然这里必须要提到一个人,就是 Log4j 的主要贡献者:Ceki Gülcü (巨佬,划重点,要考的)
后来 Log4j 成为了 Apache 基金会项目中的一员,同时 Log4j 的火爆,让 Log4j 一度成为业内日志标杆。(据说 Apache 基金会还曾经建议 Sun 引入 Log4j 到 java 的标准库中,但是 sun 拒绝了)
2002 年 2 月 Java1.4 发布,Sun 竟然推出了自己的日志库 Java Util Logging(难道这就是之前 sun 拒绝 Log4j 的原因?),其实很多日志的实现思想也都是仿照 Log4j,毕竟 Log4j 先出来很多年了,已经很成熟了此时,这两个日志工具打架,显然 Log4j 是更胜一筹..........
目前日志框架有很多个,如果用户想要切换的话,会非常麻烦,因为各个框架的设计和实现都不同;
能不能做一个抽象层?应用程序通过抽象层的 API 来生成日志,具体底层用什么日志框架,应用程序不用关心;当想要更换日志框架的时候,可以在不用改动代码(或者改动较少代码)的情况下完成切换,让应用程序更灵活。
笔者注:类似 JDBC,一统数据库访问层;只提供了一种抽象,具体的实现靠各个数据库厂商实现的抽象。
JUL 刚出来不久,2002 年 8 月 Apache 又推出了日志接口 Jakarta Commons Logging,也就是日志抽象层,当然也提供了一个默认实现 Simple Log,这野心很大,想一统日志抽象,让日志产品去实现它的抽象,这样只要你的日志代码依赖的是 JCL 的接口,你就可以很方便的在 Log4j 和 JUL 之间做切换,当时日志领域大概是这样的结构,当然也还是方便理解的,也很优雅
虽然听上去不错,但 JCL 用起来似乎并不是那么好,很多人认为引用它后造成的问题比解决的问题还多…………
例如有人是这样说的:Tapestry Central: So long, commons-logging, hello SLF4J (需科学上网)
I'm finally taking a bit to do something I've wanted to do for a long time: get away from commons-logging and switch over to SLF4J.
Commons-logging has a justified reputation for causing more problems than it solves.
Ceki Gülcü 觉得 JCL 不好用,于 2005 年也推出了一个接口方式,叫 Slf4j(Simple Logging Facade for Java)。事实证明,这个接口要比 JCL 在很多地方更优秀
但是由于 Slf4j 出来的较晚,而且还只是一个日志接口,所以之前已经出现的日志产品,如 JUL 和 Log4j 都是没有实现这个接口的。那怎么办呢?之前出现的日志产品就不能使用该接口了吗?可以的, 于是大佬 Ceki Gülcü 撸出了桥接包,也就是这种类似适配器模式
应用
↓
Slf4j
↓
桥接包
↓
日志产品也就是说,应用程序通过引用桥接包,可以使用 SLF4J 接口,至于底层用什么日志框架,应用程序不用关心
此时的桥接包就是分了两种场景
Java 应用用的日志接口(如 JCL)Java 应用用的日志产品(如 Log4j, JUL)当然,桥接包不仅这么简单,这里不展开来说,具体可以参考本文的末尾。
Logback 是由 log4j 创始人设计的又一个开源日志组件,2011 年 11 月 3 日,Logback 1.0 版本发布。
由于有了之前设计 Log4j 的经验,Logback 的性能能好,并且实现了 SLF4J 的接口,而且大佬还专门写了一篇文章:Reasons to prefer logback
小结下:
但 Logback 用起来速度快,效率最高,SLFJ4+Logback 成为了很多人的最爱, 大有超越 Apache Common Logging + Log4j 之势。 目前的日志框架,架构图大致如下:

Apache 于 2012 年推出了新项目 Log4j 2, (完全不兼容 Log4j1.x 的版本),并且 Log4j2 几乎涵盖了 Logback 的特性(Logback 是开源的,也不算抄袭?😂 )
并且,Log4j2 也搞了一个新的接口设计,分化成 log4j-api 和 log4j-core,这个 log4j-api 也是日志接口,log4j-core 才是日志产品。。。
现在我们可有了 3 个日志接口,以及 4 个日志产品。。。
听起来可能稍微有点乱,但只要知道他们的历史,还是挺利于理解的。
有这么多接口规范和框架,我们应该如何在系统中使用呢?
Optional 和 runtime scopeOptional 是为了依赖不会被传递,比如别的人引用你这个 jar,就会被迫使用不想用的日志依赖scope 设置为 runtime,是可以保证日志的产品的依赖只有在运行时需要,编译时不需要,这样,开发人员就不会在编写代码的过程中使用到日志产品的 API 了 java - Java 日志系统历史从入门到崩溃_个人文章 - SegmentFault 思否 :强推,写的很简单易懂,关于桥接包的描述很棒
一个著名的日志系统是怎么设计出来的?:介绍了设计思路,提到了正交性,涨知识了