如题所说,后端应用(非spring boot项目)一般用到了不少jar包,好比spring系列、mybatis、hibernate、各种链接数据库的客户端的jar包。可能这个jar包用的是logback、那个用的是log4j、那个又是log4j2,java
这时候,怎么才能保证各jar包的日志都能输出,且能以统一的格式输出呢?git
为何要强调非spring boot项目,可参考第四节。github
来源:https://juejin.im/post/5a7c5d575188254e76179c0fspring
Java中的日志框架分以下几种:数据库
1.Log4j
Apache Log4j是一个基于Java的日志记录工具。它是由Ceki Gülcü独创的,如今则是Apache软件基金会的一个项目。apache
2.Log4j 2
Apache Log4j 2是apache开发的一款Log4j的升级产品。编程
3.Commons Logging
Apache基金会所属的项目,是一套Java日志接口,以前叫Jakarta Commons Logging,后改名为Commons Logging。后端
Slf4j
相似于Commons Logging,是一套简易Java日志门面,自己并没有日志的实现。(Simple Logging Facade for Java,缩写Slf4j)。api
5.Logback
一套日志组件的实现(slf4j阵营)。mybatis
6.Jul
(Java Util Logging)自Java1.4以来的官方日志实现。
上面这几个框架,又分为了两类:一类是接口,包括了slf4j、commons logging;剩下的几个是具体实现,包括了jul、logback、log4j、log4j2。
如今,讲究针对接口编程,而不是针对具体实现,方便移植。而如今最通用的就是slf4j。就我待过的几家公司来讲,全都都用的是slf4j做为日志门面,具体的实现通常直接采用默认的logback。
下面就具体讲讲,怎么将其余框架五花八门的日志一统为slf4j。
咱们先分析下。
假设有个jar采用了JUL,即java自带的日志系统。咱们要怎么才能将其适配到slf4j去呢?
在JUL的logger的方法被调用时,由于Logger所在的包位于java.util,默认就被加载了,不太方便以假乱真。
想要覆盖其实现,我能想到的是,经过aop切面,直接将参数传给slf4j的api,不调用原来的日志实现。
再来,假设有个jar采用了log4j,即写日志用的是org.apache.log4j.Logger,该类是来源于log4j的相关jar包,那么,
我能够排除掉log4j相关的jar包,代码里报错了,对吧?那我再建一个相同package名、相同类名的class。在这个假的
class里,我去调用slf4j的api。
那么,这些功能须要我本身去写吗?不须要!slf4j已经给咱们提供了从各种日志框架九九归一到slf4j的转换包。
源日志框架 | 目标日志框架 | 所需转换用jar包 | maven(这里缺了version字段,请参考下一节) | 备注 |
jul | slf4j | jul-to-slf4j |
<dependency> |
须要排除掉原有依赖。 |
Commons Logging | slf4j | jcl-over-slf4j |
<dependency> |
须要排除掉原有依赖。 |
log4j | slf4j | log4j-over-slf4j |
<dependency> |
须要排除掉原有依赖。 |
log4j2 | slf4j | log4j-to-slf4j |
<dependency> |
须要排除掉原有依赖。 注意这里使用的为 log4j-to-slf4j |
这里给一张slf4j官方手册里的,也是漏了log4j2的。
在spring boot中,其实根本不须要以上的麻烦工做,只须要引用如下组件:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>1.5.9.RELEASE</version>
</dependency>
咱们看看这个组件里,包含了什么:
能够看到,log4j、jul、jcl(即commons-logging)的转换包都有了。
那么,在非spring boot项目中,咱们只要去mvnrepository.com查询:spring-boot-starter-logging.
而后,选择对应的版本,就能够在下图看到该组件依赖的包:
怎么样,应该是个比较简单的办法吧?
这一篇里面,咱们还只讲了如何将各日志框架统一到slf4j来。
可是slf4j只是个门面,具体的实现呢(好比log4j等)又被咱们排除掉了。
那么slf4j没有实现,也是不能完成输出日志的任务的。
因此咱们还须要一个实现。这份留到下篇仔细讲。
代码路径:
https://github.com/cctvckl/logtest
这里演示下效果:
下面是统一后的:
其中jul为何日志未统一,等有时间了我再看看。这两天时间有点紧,要开发需求。。。