Java日志系统概述SLF4J、log4j、JCL、Logback

java日志系统经常遇到SLF4j,JCL,logback,log4j2等等。一些人可能要晕了怎么选择,这里简单说下。

发展

这些都要从Java日志框架的元老log4j说起。java1.3之前打日志都是采用System.out.println(), System.err.println()等做法。
此时log4j诞生,定义了Logger、Appender、Level等概念,至今还在使用。可以说是一下子脱离了刀耕火种时代。
毕竟还不是java的标准,因此随着IT发展,开始有多种设计和实现

Java日志系统概述SLF4J、log4j、JCL、Logback

从上图可以看出,这个过程出了两个统一的接口,并有不同实现

SLF4j和JCL

JCL,Jakarta Commons Logging。

SLF4j和JCL对使用者封装了统一接口,进行解耦。两者定位一样,在不更改代码的基础上,随意切换日志系统。也各自拥有忠实的原生实现logback和log4j2。

SLF4j

SLF4j采用静态绑定机制
1.SLF4j为各个日志输出系统提供了适配库
2.SLF4j会加载org.slf4j.impl.StaticLoggerBinder作为输出日志的实现类(老版本)。新版本通过java SPI实现。自然而然地就能与具体的日志输出实现绑定起来。

JCL

JCL采用动态绑定机制
1.启动时,尝试寻找当前factory中名叫org.apache.commons.logging.Log配置属性的值
2.找不到,则寻找系统中属性中名叫org.apache.commons.logging.Log的值
3.依旧找不到,如果应用程序的classpath中有log4j,则使用相关的包装(wrapper)类(Log4JLogger)
4.还没找到的话,使用相关的包装类(Jdk14Logger)

log4j2与logback


log4j2比较新,比logback晚出来几年。也吸收了logback的有点,也有大量改进。在多线程环境下和使用异步日志时性能比较好
log4j2和logback各有优缺点

 

桥接与适配


因为理念和实现的差异性,不可避免的存在一些不兼容。另外不同的java库也依赖不同的日志输出服务,也有兼容性问题。因此两个门面在与实现进行组合时就需要一些桥接器和适配器。
完美情况下,应该是

Java日志系统概述SLF4J、log4j、JCL、Logback

这个是最理想的实现方案,然而现实是多样的。因为理念、设计思想、实现思路等各不相同。一定会出现兼容性问题。

适配器

系统jar包之间肯定存在统一接口与日志输出系统不兼容的

Java日志系统概述SLF4J、log4j、JCL、Logback

此时就需要在接口和日志输出系统之间,做一层适配

 

桥接器

由于历史遗留的jar包、日志输出实现选择等问题,肯定存在java服务直接使用日志输出系统。
比如当前系统要使用slf4j,但是依赖的某个jar使用了log4j。此时slf4j就收集不到这个jar的日志,怎么办?此时就需要桥接,简单说就是把日志重定向输出

Java日志系统概述SLF4J、log4j、JCL、Logback

桥接器自动把已经存在的日志输出系统实现类似屏蔽,对此java服务是无感知的