参考:
视频:bilibili雷丰阳《SpringBoot—权威教程》日志篇。
文章:https://www.cnblogs.com/Latiny/p/10974300.html
一、什么是日志框架:
· 一套能实现日志输出的工具包;
· 能够描述系统运行状态的所有时间都可以算作日志。
· 比如:用户登录退出、接口超时、数据库崩溃、HelloWorld。
二、日志框架的能力
· 定制输出目标、格式
· 携带上下文信息
· 运行时选择性输出
· 灵活配置
· 优异性能
三、常见日志框架
JCL(Jakarta Commons Logging)、JUL(Java Util Logging)、Log4j(4=four=for)、Log4j2、jboss-logging、Logback、SLF4J(The Simple Logging Facade for Java)
四、日志框架分类
什么叫“日志门面”,什么叫日志实现?日志门面就是抽象接口,我们编码实际上就是面向抽象接口编程,方法调用用的就是这些抽象接口,而日志实现就是抽象接口调用的实际进行日志记录和管理的底层代码,关系解释:
开发调用 -> 日志门面 -> 日志实现
SpringBoot目前针对日志框架开发的组合方式是SLF4J + Logback
五、日志门面SLF4J
实际上SLF4J只是一套实现日志功能的API,只是一个抽象接口,我们调用这个接口而程序运行时SLF4J会自动找到对应的日志实现来操作所有与日志相关的功能。但是SLF4J是如何调用像Log4j、Logback这样的日志框架实现工具包的呢?查询SLF4J官网得到如下关系图:
上图给出了SLF4JAPI和当前某些日志实现的调用关系图,从左到右依次解释:
1)
application应用程序中若只导入slf4j-api.jar包,那么这个应用程序将不能实现日志功能,因为没有日志实现代码。
2)
appilication应用程序中导入slf4j-api.jar与logback-classic.jar和logback-core.jar包,可以实现日志功能并且SLF4J可以直接调用logback的相关函数完成日志功能
3)
应用程序导入slf4j-api.jar,若想实现调用log4j完成日志功能则除了导入log4j.jar包以外还需要导入一个适配层的slf4j-log4j12.jar包,这是因为slf4j不能直接调用log4j,适配器层slf4j-log4j12.jar包达到一个对上对接slf4j、对下对接log4j的中转调离功能,看起来就像一个适配器一样,把两个不能互相调用的jar包协同工作起来。
4)同理,SLF4J如果想调用java.util.logging也不可以直接调用,依然需要适配层jar包slf4j-jdk14.jar
以上就给出了一个比较关键的信息,当应用程序需要用到SLF4J作为日志门面API的时候,和不同的日志实现进行组合一定要查询官网的图解,看看日志实现Jar包可不可以直接被SLF4Japi直接调用,如果不能,再导入一个适配器层jar包用于上下对接。
六、多日志框架如何做到统一接口?
在实际项目中因为业务逻辑复杂,为了代码易于管理而采用多框架的现象已经非常普遍,比如SSM、SSH等等、Spring框架依赖Commons.logging,没有commons-logging.jar程序就会报错,同样的道理,Hibernate框架依赖Jboss-logging,commons-logging.jar由JCL接口调用输出日志,Hibernate调用Jboss接口也会输日志,而SLF4J也会输出日志,这样一个应用程序有多个日志框架都会生成一份自己的日志,重复且不易管理,这时就需要统一抽象接口,只让一个日志实现框架输出日志就足够了,例如SLF4J,如何实现?如下图所示,这是一个SpringBoot应用程序的Pom.xml依赖包关系图,图片太大我只截取其中有关日志框架的部分:
我的SpringBoot当前版本是2.2.6,现在slf4j已经使用logback和log4j两个日志实现框架了,查看1.x版本的SpringBoot会发现也会有commons-logging的包,如下:
在SpringBoot1.x版本中,slf4j为了统一抽象接口,加入了jcl-over-slf4j、logj-over-slf4j这样的桥接工具,让原本是jcl接口调用commons-logging的日志输出重定向到了SLF4J,然后通过SLF4J这个接口完成日志输出,这样就实现了统一的日志管理。简单给出一个示意图:
一个依赖commons-logging.jar作为日志输出的框架调用日志实现的过程是这样的:
那么在加入桥接器jcl-over-slf4j.jar后的过程就是这样的:
为了实现这样的效果,一定要用jcl-over-slf4j.jar把commons-logging.jar 覆盖,因为jcl-over-slf4j.jar本身就包括了commons-logging.jar并且重写了里面的方法!
代码如下所示:
SpringBoot1.x对覆盖这种的操作是在pom.xml文件里表现的:
现在的2.x版本已经把这段代码去掉了 因为2.x的版本不需要有依赖commons-logging.jar的组件了,因此没有<exclusions>标签