1.背景
在现在这个服务化横行的时代,我们会对接很多的服务方,但是每个服务方的开发人员都会有一个自己用的习惯的日志实现,其中包括(Logback、Log4j1、Log4j2、JCL、J.U.L),在我们开发过程中就需要整合所有对接的业务方的日志输出。
2.遇到的问题
由于引入不同服务方,导致自己项目中日志的冲突,在各种日志JAR的冲突中总是尝试的去排除一些JAR包,来让项目跑起来,但是我们可能并不了解其中的原理,下面就是自己在开发中遇到的这种问题,进行一次总结。
3.日志分类
1.Java Util Log(简称JUL)
是JDK 中自带的log功能。但是其实项目中用到的很少。主要有以下3点原因:
1.JUL从JDK1.4 才开始加入(2002年),当时各种第三方log lib已经被广泛使用了
2.JUL早期存在性能问题,到JDK1.5上才有了不错的进步,但现在和Logback/Log4j2相比还是有所不如
3.JUL的功能不如Logback/Log4j2等完善,比如Output Handler就没有Logback/Log4j2的丰富,有时候需要自己来继承定制,又比如默认没有从ClassPath里加载配置文件的功能
2.Log4j 1
Log4j 是在 Logback 出现之前被广泛使用的 Log Lib,Log4j 在设计上非常优秀,对后续的 Java Log 框架有长久而深远的影响。但是性能没有Log4j2和Logback 的性能好,所以在Log4j2和Logback出来以后使用在逐渐减少。
3.Commons Logging(简称JCL)
JCL 是一个Log Facade,只提供 Log API,不提供实现,然后有 Adapter 来使用 Log4j 或者 JUL 作为Log Implementation。这个相当于是一个标准,在程序中大家记录日志都使用 JCL 的接口,在运行的时候可以根据我们个人的喜好去选择真正的日志输出,如果配置了Log4j ,就会走Log4j ,什么都没有配置的话,默认就走JUL了。
这样接口和实现做了良好的分离,在统一的JCL之下,不改变任何代码,就可以通过配置就换用功能更强大,或者性能更好的日志库实现。
4.SLF4J/Logback
slf4j(The Simple Logging Facade for Java)其实跟JCL 一样,是一个Log Facade接口,而Logback 就相当于与log4j,是slf4j的实现。Logback 相对于log4j提供了性能更好的实现,异步 logger,Filter等更多的特性。
5.Log4j2
Log4j2 也做了 Facade/Implementation 分离的设计,分成了 log4j-api 和 log4j-core。
但其实Log4j2和Log4j没有太大的关系,而且 并不兼容,设计上很大程度上模仿了 SLF4J/Logback,性能上也获得了很大的提升。
3.使用
到目前我们了解的有了三个流行的Log 接口(jcl,slf4j,log4j-api)和四个流行的Log实现(jul,log4j,logback,log4j-core)
在项目中我们如何去整合这些日志呢?
1. 使用SLF4J承接不同的日志框架-把不同的日志输出转换成SLF4J的实现方式(日志框架—>SLF4J)下面是官方图片
当项目中引用了多种日志时,可以统一适配到SLF4J,通过使用SLF4J或者第三方提供的日志适配器适配到SLF4J,然后我们可以在应用中采用统一的一个日志框架来进行日志系统的实现,从而达到了日志的统一。
适配器名称 | 原日志框架 | 提供方 | 实现方式 |
jcl-over-slf4j | apache commons-logging | slf4j | jcl-over-slf4j重写了commons-logging的Log和LogFactory类,做了不同的实现 |
jul-to-slf4j | java jdk-logging | slf4j | jul-to-slf4j 下有 SLF4JBridgeHandler实现,系统启动的时候调用SLF4JBridgeHandler.removeHandlersForRootLogger();删除所有的Logger,然后调用SLF4JBridgeHandler.install();装载上SLF4J |
log4j-over-slf4j | apache log4j 1 | slf4j | log4j-over-slf4j 重写了log4j 1 的Logger和LogFactory类,做了不同的实现 |
log4j-to-slf4j | apache Log4j 2 | Log4j 2 | log4j-to-slf4j 使用OSGI SPI的形式为org.apache.logging.log4j.spi.Provider提供了SLF4J的实现 |
2. SLF4J对接不同的日志框架实现(SLF4J—>日志框架)下面是官方图片
SLF4J适配不同的日志实现,是通过不同的适配器实现的。
适配器名称 | 目标实现日志框架 | 提供方 |
slf4j-jdk14 | jdk-logging J.U.L | SLF4J |
logback-classic | Logback | Logback |
slf4j-jcl | apache commons-logging | SLF4J |
slf4j-log4j12 | log4j 1 | SLF4J |
log4j-slf4j-impl | log4j 2 | Log4j 2 |
4.总结
在开发过程中,我们可以通过SLF4J作为中间桥梁,来打通和统一日志的输出。