目录
三、Spring Boot集成日志
1. 日志框架
是否还在使用System.out.println(“”)打印程序运行时状态及关键数据?
这样是否会显得不够专业?
此时日志框架应运而生,将所有的打印信息写成一个文件,即为日志框架
为了不使日志框架过于简陋,实现了以下功能:
-
异步模式
-
自动归档
……
为避免换上新的日志框架使得要重新修改代码的相关API,此时可想到JDBC—-数据库驱动的模式,写统一的接口层:日志门面(日志的一个抽象层)
在项目中导入具体的日志实现就可以;之前的日志框架都是先的是日志抽象层
常见日志框架
JUL、JCL、Jboss-logging、logback、log4j、log4j2、slf4j
日志门面 (日志的抽象层) | 日志实现 |
---|---|
Log4j JUL(java.util.logging) Log4j2 Logback |
左边选一个门面(抽象层)、右边限一个实现
日志门面:SLF4j
日志实现:logback
Spring Boot底层是Spring框架,Spring框架默认是JCL
Spring Boot选用SLF4j和logback
2. SLf4j使用
2.1 如何在系统中使用SLf4j
开发的时候,日志记录方法的调用:不应该直接调用日志的实现类,而是调用日志抽象层的方法
给系统导入 slf4j 的 jar 包和 logback 的实现 jar 包
如下为调用示例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger(HelloWorld.class);
logger.info("Hello World");
}
}
图示:
每一个日志的实现框架都有自己的配置文件,使用SLF4j以后,配置文件还是做成日志实现框架的配置文件
2.2 遗留问题
a系统(slf4j + logback),依赖Spring,hibernate、Mybatis框架,而且这些框架的日志框架各不相同
统一日志记录,即使是别的框架,如何统一使用slf4j进行输出?
- 将系统中其他日志框架排除
- 用中间包来替换原有的日志框架
- 使用SLF4j其他的实现
3. Spring Boot与日志关系
每个Spring Boot都有如下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.4.0</version>
<scope>compile</scope>
</dependency>
Spring Boot使用他它来做日志功能
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.4.0</version>
<scope>compile</scope>
</dependency>
Spring Boot底层依赖关系
总结
-
Spring Boot底层使用SLF4j + logback的方式进行日志记录
-
Spring Boot也把其他的日志都替换成了SLF4j
-
中间替换包
-
如果我们要引入其他框架,一定要把这个框架的默认日志依赖移除掉
如Spring框架使用commons.logging,SpringBoot底层移除掉这个日志依赖
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <exclusions> <exclusion> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> </exclusion> </exclusions> </dependency>
Spring Boot能自动适配所有的日志,而且底层使用slf4J + logback的方式记录日志,引入其他框架的时候,只需要将这个框架的依赖排除掉
4. 日志使用
4.1 默认配置
Spring Boot默认帮我们配置好了日志
其使用如下:
//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
void contextLoads() {
//日志的级别
//由低到高
//可以调整输出的日志级别,日志指挥在这个级别以后的高级别生效
logger.trace("这是trance日志...");
logger.debug("这是debug日志...");
//Spring Boot默认给我们使用的是info级别的
logger.info("这是info日志...");
logger.warn("这是warn日志...");
logger.error("这是error日志...");
}
可看到只输出info,warn,error级别的日志
由于SpringBoot默认输出上述三个级别的日志,故要输出info和debug级别的日志需要在配置文件中设置:
logging.level.com.why.springboot=trace
”com.why.springboot“ 表示设置日志级别的文件路径
此时只会在控制台输出
要想输出到文件中需要设置配置文件
#第一种方法
#当前项目木下生成springboot.log日志
#不指定路径在当前项目下生成,还可以指定完整的路径
#logging.file.name=springboot.log
#第二种方法
#在当前磁盘的根路径下,创建spring文件夹和里面的log文件夹,使用spring.log作为默认文件
logging.file.path=/spring/log/spring.log
上述两种方法选用一种即可
设置日志消息输出格式
日志输出格式:
%d表示日期时间
%thread表示线程名
%-5level:级别从左显示5个字符宽度
%logger{50} 表示logger名字最长为50个字符,否则安装据点分割
%msg:日志消息
%n是换行符
-
设置控制台输出格式
#指定控制台输出日志的格式 格式:日期 时间 级别 消息 logging.pattern.console=%d{yyyy-MM-dd HH:mm:SSS} [%thread] %-5level %logger{50} - %msg%n
-
设置文件输出格式
#指定文件中日志的输出格式 logging.pattern.file=%d{yyyy-MM-dd HH:mm:SSS} === [%thread] === %-5level === %logger{50} === %msg%n
4.2 自定义日志配置
给类路径下放上每个日志框架自己的配置文件即可,此时就不使用默认配置了
Logging System | Customization |
---|---|
Logback | logback-spring.xml , logback-spring.groovy , logback.xml or logback.groovy |
Log4j2 | log4j2-spring.xml or log4j2.xml |
JDK (Java Util Logging) | logging.properties |
使用什么框架则加入什么样的配置文件,对照上表
logback.xml:直接被日志框架识别
logback-spring.xml:日志框架不直接加载配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能
<springProfile name="staging">
<!-- configuration to be enabled when the "staging" profile is active -->
可以指定某段配置只在某个环境下生效
</springProfile>
使用示例:
<layout class="ch.qos.logback.classic.PatternLayout">
<!-- 开发环境输出格式-->
<springProfile name="dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
</springProfile>
<!-- 非开发环境配置-->
<springProfile name="!dev">
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
</springProfile>
</layout>
如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误
no applicable action for [springProfile]
5. 切换日志框架
5.1 log4j日志框架的使用
-
pom.xml文件添加如下依赖
<!-- 导入slf4j-log4j12的依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency>
-
创建log4j.properties文件配置log4j相关的信息
### set log levels ### log4j.rootLogger = debug , stdout , D , E ### 输出到控制台 ### log4j.appender.stdout = org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target = System.out log4j.appender.stdout.layout = org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} ====== %5p %c{ 1 }:%L - %m%n #### 输出到日志文件 ### #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender #log4j.appender.D.File = logs/log.log #log4j.appender.D.Append = true #log4j.appender.D.Threshold = DEBUG ## 输出DEBUG级别以上的日志 #log4j.appender.D.layout = org.apache.log4j.PatternLayout #log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n # #### 保存异常信息到单独文件 ### #log4j.appender.D = org.apache.log4j.DailyRollingFileAppender #log4j.appender.D.File = logs/error.log ## 异常日志文件名 #log4j.appender.D.Append = true #log4j.appender.D.Threshold = ERROR ## 只输出ERROR级别以上的日志!!! #log4j.appender.D.layout = org.apache.log4j.PatternLayout #log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
5.2 logback切换log4j示例
-
首先排除logback和log4j-to-slf4j的依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <!-- 排除logback和log4j-to-slf4j--> <exclusions> <exclusion> <artifactId>logback-classic</artifactId> <groupId>ch.qos.logback</groupId> </exclusion> <exclusion> <artifactId>log4j-to-slf4j</artifactId> <groupId>org.apache.logging.log4j</groupId> </exclusion> </exclusions> </dependency>
或者使用IDEA的依赖关系图排除
在pom.xml文件中右击进行如下操作,打开依赖图
找到logback和log4j-to-slf4j这两个依赖,右击Excute排除
-
添加log4j的依赖
<!-- 导入slf4j-log4j12的依赖--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency>
-
配置log4j的配置文件
-
运行,控制台打印如下信息
成功
这中方法是不推荐的,因为logback比log4j框架更为优秀,此处只是介绍框架转换原理
logging切换为log4j2
-
排除starter-logging的依赖
<exclusions> <exclusion> <artifactId>spring-boot-starter-logging</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions>
-
添加log4j2的依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-log4j2</artifactId> </dependency>
-
此时就可在类路径下像以前一样编写log4j2的配置文件