前言
首先要感谢一下读者朋友们的支持,你们每一个的赞都是对陈某最大的肯定,陈某也会一如既往的加油,奥利给!!!
言归正传,上一篇文章写了Spring Boot的默认日志框架Logback的基本配置,有兴趣的可以看看:Spring Boot第三弹,一文带你搞懂日志如何配置?。
今天就来介绍一下Spring Boot如何无感的切换日志框架?
Spring Boot 版本
本文基于的Spring Boot的版本是2.3.4.RELEASE
。
什么是日志门面?
前面介绍的日志框架都是基于日志门面SLF4j
即简单日志门面(Simple Logging Facade for Java),SLF4j并不是一个真正的日志实现,而是一个抽象层,它允许你在后台使用任意一个日志实现。
使用了slf4j后,对于应用程序来说,无论底层的日志框架如何变,应用程序不需要修改任意一行代码,就可以直接上线了。
如果对SLF4j比较感兴趣的可以去官网看看:SLF4j官网
如何做到无感知切换?
SLF4j是日志门面,无论什么日志框架都是基于SLF4j的API实现,因此无论是代码打印日志还是Lombok注解形式打印日志,都要使用的SLF4j的API,而不是日志框架的API,这样才能解耦,做到无感知。因为最终切换的框架只是对于SLF4j的实现,并不是切换SLF4j。
其实这一条在阿里开发手册中也是明确指出了,如下:
如何切换?
Spring Boot默认是Logback
日志框架,如果需要切换到其他的日志框架应该如何做?
首先我们先看官网的一张图,一切都在图中,如下:
SLF4j只是一个门面,共有两大特性。一是静态绑定、二是桥接。
什么是静态绑定?:我们以log4j
为例。首先我们的application中会使用slf4j的api进行日志记录。我们引入适配层的jar包slf4j-log412.jar
及底层日志框架实现log4j.jar
。简单的说适配层做的事情就是把slf4j
的api转化成log4j
的api。通过这样的方式来屏蔽底层框架实现细节。
什么是桥接?:比如你的application中使用了slf4j
,并绑定了logback
。但是项目中引入了一个A.jar
,A.jar
使用的日志框架是log4j
。那么有没有方法让slf4j
来接管这个A.jar
包中使用log4j
输出的日志呢?这就用到了桥接包。你只需要引入log4j-over-slf4j.jar
并删除log4j.jar
就可以实现slf4j
对A.jar
中log4j
的接管.听起来有些不可思议。你可能会想如果删除log4j.jar
那A.jar
不会报编译错误嘛?答案是不会。因为log4j-over-slf4j.jar
实现了log4j
几乎所有public
的API
。但关键方法都被改写了。不再是简单的输出日志,而是将日志输出指令委托给slf4j
。
下面就以log4j2
为例,切换Spring Boot的日志框架为Log4j2
。
引入依赖
Spring Boot 默认是Logback日志框架,如果想要切换log4j2
肯定是要将Logback
的依赖移除,只需要排除web
模块中的日志启动器
即可,如下:
1 2 3 4 5 6 7 8 9 10 11 12
| <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-logging</artifactId> </exclusion> </exclusions> </dependency>
|
排除了默认的logback依赖,肯定是需要引入log4j2
的依赖,其实log4j2
为了与Spring Boot适配也做了个启动器,不需要在引入其他的jar包了,只需要添加如下依赖即可:
1 2 3 4 5
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
|
指定配置文件
Spring Boot官方文档已经给出了默认两个log4j2的配置的名称,分别为:log4j2-spring.xml
, log4j2.xml
,但是建议使用log4j2-spring.xml
,因为Spring Boot会做一些扩展,行吧,就整这个放在src/resources
文件夹下即可。
另外上篇文章也说过,如果不使用默认的配置名称,则需要在application.properties
指定配置文件,如下:
1
| logging.config=classpath:logging-config.xml
|
日志如何配置?
其实log4j2
的一些配置和logback很相似,这里就不再一一介绍,有兴趣的可以去官网查查,直接贴出一些即用的配置,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97
| <?xml version="1.0" encoding="UTF-8"?>
<configuration monitorInterval="5">
<Properties> <property name="LOG_PATTERN" value="%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" /> <property name="FILE_PATH" value="更换为你的日志路径" /> <property name="FILE_NAME" value="更换为你的项目名" /> </Properties>
<appenders>
<console name="Console" target="SYSTEM_OUT"> <PatternLayout pattern="${LOG_PATTERN}"/> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> </console>
<File name="Filelog" fileName="${FILE_PATH}/test.log" append="false"> <PatternLayout pattern="${LOG_PATTERN}"/> </File>
<RollingFile name="RollingFileInfo" fileName="${FILE_PATH}/info.log" filePattern="${FILE_PATH}/${FILE_NAME}-INFO-%d{yyyy-MM-dd}_%i.log.gz"> <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="15"/> </RollingFile>
<RollingFile name="RollingFileWarn" fileName="${FILE_PATH}/warn.log" filePattern="${FILE_PATH}/${FILE_NAME}-WARN-%d{yyyy-MM-dd}_%i.log.gz"> <ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="15"/> </RollingFile>
<RollingFile name="RollingFileError" fileName="${FILE_PATH}/error.log" filePattern="${FILE_PATH}/${FILE_NAME}-ERROR-%d{yyyy-MM-dd}_%i.log.gz"> <ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/> <PatternLayout pattern="${LOG_PATTERN}"/> <Policies> <TimeBasedTriggeringPolicy interval="1"/> <SizeBasedTriggeringPolicy size="10MB"/> </Policies> <DefaultRolloverStrategy max="15"/> </RollingFile>
</appenders>
<loggers>
<logger name="org.mybatis" level="info" additivity="false"> <AppenderRef ref="Console"/> </logger> <Logger name="org.springframework" level="info" additivity="false"> <AppenderRef ref="Console"/> </Logger>
<root level="info"> <appender-ref ref="Console"/> <appender-ref ref="Filelog"/> <appender-ref ref="RollingFileInfo"/> <appender-ref ref="RollingFileWarn"/> <appender-ref ref="RollingFileError"/> </root> </loggers> </configuration>
|
上面的配置中如果需要使用的话,需要改掉全局变量中的日志路径和项目名称,如下部分:
1 2
| <property name="FILE_PATH" value="更换为你的日志路径" /> <property name="FILE_NAME" value="更换为你的项目名" />
|
总结
本篇文章介绍了Spring Boot如何切换日志框架以及SLF4j一些内容,如果有所收点点在看关注分享一波,谢谢!!!
作者的上个Mybatis
专栏已经结束了,作者特意将全部文章整理成册,关注公众号【码猿技术专栏】回复关键词Mybatis进阶
即可领取此册。