日志级别
日志级别:ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
- FATAL:表示需要立即被处理的系统级错误,一般情况下,一个进程的生命周期应该只记录一次该级别的日志,即该进程遇到了无法恢复的错误而退出时。
- ERROR:该级别的错误也需要马上被处理,当 ERROR 错误发生时会影响用户的正常访问,与 FATAL 比起来,FATAL 时服务器挂了,而 ERROR 属于服务器无法正常提供服务,但还在运行,需要马上被处理。因此,对于用户的操作不当,如请求参数错误等,是不应该记为 ERROR 日志的。
- WARN:该日志用于记录潜在的错误情形
- INFO:记录系统的正常运行状态,INFO 日志不宜大于 TRACE 日志的 10%
- DEBUG 和 TRACE:用于对系统的每一步运行状态进行精确记录
注意事项:当项目中的日志级别设置为 INFO 时,那么比它低级别的日志信息就看不到,如 TRACE、DEBUG 就不会显示。
日志框架
日志框架的分类:日志门面(日志的抽象层)和日志实现
- 日志门面:JCL、SLF4j、jboss-logging
- 日志实现:Log4j、 JUL(java.util.logging) Log4j2、 Logback
JCL、jboss-logging很久没有更新,不适合使用,log4j 由于输出性能问题,其作者重写了一个日志门面 Slf4j,且编写了基于 Slf4j 的日志实现 logback
常用框架的日志使用:
框架 | 日志 |
---|---|
Spring | JCL |
Spring Boot | Slf4j -> logback |
Hibernate3 | Slf4j |
Slf4j 的使用
Slf4j 官网:http://www.slf4j.org/
Slf4j 是日志门面,因此无论是代码打印日志还是 Lombok 注解形式打印日志,都要使用的 SLF4j 的 API,而不是日志框架的 API。这一条在阿里开发手册中也明确指出了:
Slf4j 的日志输出过程:
注意事项:每一个日志的实现框架都有自己的配置文件,在使用 Slf4j 以后,配置文件还是使用日志实现框架自己本身的配置文件
Slf4j 解决多框架日志不统一的问题:
如何将系统中所有的日志都统一到 slf4j :
- 将系统中其他日志框架先排除出去
- 用中间包来替换原有的日志框架
- 导入 slf4j 其他的实现
Spring Boot 统一日志管理
依赖引入
依赖引入:Spring Boot 默认的日志框架为 slf4j + logback,因此,除非是更换日志实现,否则不许要重新引入依赖
官方文档地址:
<!-- spring-boot-starter启动器中包含该依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<version>2.3.4.RELEASE</version>
<scope>compile</scope>
</dependency>
<!-- 如果需要切换日志实现为 log4j2 -->
<!-- 先排除 logback 的日志依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!-- 去掉springboot默认日志框架logback -->
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 再引入 log4j2 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
日志使用方式
- 方式一:在需要日志的类中添加如下代码 ```java import org.slf4j.Logger; import org.slf4j.LoggerFactory;
private final Logger logger= LoggerFactory.getLogger(DemoApplicationTests.class);
- 方式二:使用 lombok
```xml
<!-- 先引入 Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
// 使用:在需要日志的类上标注 @Slf4j 注解
@Slf4j
class DemoApplicationTests {
@Test
public void test(){
log.debug("输出DEBUG日志.......");
}
}
日志级别
Spring Boot 的默认日志级别为 INFO,但可以在配置文件中进行定制:logging.level.root=DEBUG 。上述是将所有的日志的级别都改成了 DEBUG,Spring Boot 还支持 package 级别的日志级别调整,格式为 logging.level.xxx=xxx
日志输出位置
Spring Boot 中日志默认输出到控制台,但提供了两个配置:
- logging.file.path:指定日志文件的路径
- logging.file.name:日志文件名,默认 spring.log
注意:官方文档说这两个属性不能同时配置,否则不生效,因此只需要配置一个即可,一般配置 logging.file.path 属性
日志输出格式
通过在配置文件中对日志输出格式进行配置:
- logging.pattern.console:控制台的输出格式
- logging.pattern.file:日志文件的输出格式 ``` logging.pattern.console=%d{yyyy/MM/dd-HH:mm:ss.SSS} [%thread] %-5level %logger- %msg%n logging.pattern.file=%d{yyyy/MM/dd-HH:mm} [%thread] %-5level %logger- %msg%n
%d——日志输出的日期时间 %thread——输出日志的进程名字,这在Web应用以及异步任务处理中很有用 %-5level——日志级别,并且使用5个字符靠左对齐 %logger- ——日志输出者的名字 %msg——日志消息 %n——平台的换行符
<a name="z3GSj"></a>
##### 自定义日志配置
Spring Boot 官方文档说明,根据不同的日志系统,可以按照如下的日志配置文件名就能够被正确加载,官方文档网址:[https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-custom-log-configuration](https://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#boot-features-custom-log-configuration)
1. **`Logback`**:logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
1. **`Log4j`**:log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
1. **`Log4j2`**:log4j2-spring.xml, log4j2.xml
1. **`JDK (Java Util Logging)`**:logging.properties
也可以通过 **logging.config = classpath:logging-config.xml 指定配置文件名**<br />Spring Boot官方推荐优先使用带有-spring的文件名作为你的日志配置。带 -spring 的文件不会被框架直接加载,而是会被 SpringBoot 解析加载,可以使用 profile 功能,对不同的环境进行不同的日志输出。
因此只需要在 `src/resources`文件夹下创建 `logback-spring.xml`即可,配置文件内容如下:
<?xml version=”1.0” encoding=”UTF-8”?>
<!--输出到控制台 ConsoleAppender-->
<appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
<!--展示格式 layout-->
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>${PATTERN}</pattern>
</layout>
<!--过滤器,只有过滤到指定级别的日志信息才会输出,如果level为ERROR,那么控制台只会输出ERROR日志-->
</appender>
<!--正常的日志文件,输出到文件中-->
<appender name="fileDEBUGLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Info 级别的日志,只是过滤 info 还是会输出 Error 日志,因为 Error 的级别高,
所以我们使用下面的策略,可以避免输出 Error 的日志-->
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!--过滤 Error-->
<level>Error</level>
<!--匹配到就禁止-->
<onMatch>DENY</onMatch>
<!--没有匹配到就允许-->
<onMismatch>ACCEPT</onMismatch>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logPath}/log_demo.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logPath}/log_demo_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<!--输出ERROR日志到指定的文件中-->
<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!--如果只是想要 Error 级别的日志,那么需要过滤一下,默认是 info 级别的,ThresholdFilter-->
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>Error</level>
</filter>
<!--日志名称,如果没有File 属性,那么只会使用FileNamePattern的文件路径规则
如果同时有<File>和<FileNamePattern>,那么当天日志是<File>,明天会自动把今天
的日志改名为今天的日期。即,<File> 的日志都是当天的。
-->
<File>${logPath}/error.log</File>
<!--滚动策略,按照时间滚动 TimeBasedRollingPolicy-->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径,定义了日志的切分方式——把每一天的日志归档到一个文件中,以防止日志填满整个磁盘空间-->
<FileNamePattern>${logPath}/error_%d{yyyy-MM-dd}.log</FileNamePattern>
<!--只保留最近90天的日志-->
<maxHistory>90</maxHistory>
<!--用来指定日志文件的上限大小,那么到了这个值,就会删除旧的日志-->
<!--<totalSizeCap>1GB</totalSizeCap>-->
</rollingPolicy>
<!--日志输出编码格式化-->
<encoder>
<charset>UTF-8</charset>
<pattern>${PATTERN}</pattern>
</encoder>
</appender>
<!--指定最基础的日志输出级别-->
<root level="DEBUG">
<!--appender将会添加到这个loger-->
<appender-ref ref="consoleLog"/>
<appender-ref ref="fileDEBUGLog"/>
<appender-ref ref="fileErrorLog"/>
</root>
<!-- 定义指定package的日志级别-->
<logger name="org.springframework" level="DEBUG"></logger>
<logger name="org.mybatis" level="DEBUG"></logger>
<logger name="java.sql.Connection" level="DEBUG"></logger>
<logger name="java.sql.Statement" level="DEBUG"></logger>
<logger name="java.sql.PreparedStatement" level="DEBUG"></logger>
<logger name="io.lettuce.*" level="INFO"></logger>
<logger name="io.netty.*" level="ERROR"></logger>
<logger name="com.rabbitmq.*" level="DEBUG"></logger>
<logger name="org.springframework.amqp.*" level="DEBUG"></logger>
<logger name="org.springframework.scheduling.*" level="DEBUG"></logger>
<!--定义com.xxx..xx..xx包下的日志信息不上传,直接输出到fileDEBUGLog和fileErrorLog这个两个appender中,日志级别为DEBUG-->
<logger name="com.xxx.xxx.xx" additivity="false" level="DEBUG">
<appender-ref ref="fileDEBUGLog"/>
<appender-ref ref="fileErrorLog"/>
</logger>
```
idea 查看依赖
在 idea 工具的 pom.xml 页面右键,选择 【Diagrams】菜单,然后 【show dependencies】:
- Spring Boot 中使用 spring-boot-starter-logging 来做日志管理
- Spring Boot 底层使用了 slf4j + logback 的方式进行日志记录
- Spring Boot 底层也导入了 slf4j 中间转换包