Spring Boot-日志
通过前面两章《Spring Boot-配置文件》、《Spring Boot-配置文件之特殊配置》,我们基本了解了Spring Boot配置相关的内容。如果大家发现有什么常用的内容遗漏,欢迎指正
这一章,我们来了解下在日常开发和生产发布中必不可少的一个环节日志。提起日志,我们脑海中可能会第一时间蹦出许多第三方日志组件,如:log4j、logback、log4j2等。废话不多说,我们开搞
2021-07-06 21:20:50.488 INFO 1203 --- [ restartedMain] com.summer.config.ConfigApplication : No active profile set, falling back to default profiles: default
上面的内容,是我在没有配置任何日志相关配置时,控制台打印出来的内容,我们先通过这段内容了解一下Spring Boot日志默认内容。
日志格式
- 时间:精确到毫秒
- 日志级别:ERROR、WARN、INFO、DEBUG or TRACE
- 进程ID:如 1203
- 分隔符:--- 标识实际日志的开始
- 线程名:[]的内容
- Logger名:通常使用源代码类名
- 日志内容:
日志级别
Spring Boot默认日志级别为:INFO。
我们可以通过几种方式来改变日志输出级别
- 在运行命令后加入--debug,如:java -jar demo.jar --debug
- 在application.yml中配置debug=true,该属性为true时,核心Logger会输出更多内容,但你自己写的代码,除非你打印了DEBUG级别的日志,否则内容并不会变多。
- 通过logging.level.*=LEVEL配置来修改日志输出级别。
logging.level:日志级别控制前缀,*为包名或Logger名
LEVEL:选项TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF
文件输出
Spring Boot默认配置时,日志只会输出到控制台,并不会记录到文件中,but,在生产环境中,通过日志是要记录到文件或者其他第三方存储中的。
若要增加文件输出,需要在application.yml中配置logging.file.name或者logging.path属性。
- logging.file.name: 可以是绝对路径,也可以是相对路径,如:logging.file.name=log.log
- logging.path: 设置目录,会在该目录下创建spring.log文件并写入日志,如:logging.path=/var/log
日志文件会在10Mb大小时截断,产生新的日志。
自定义输出格式
在Spring Boot中可以通过application.yml配置如下参数控制输出格式:
- logging.pattern.console: 控制输出到控制台的格式
- logging.pattern.file: 控制输出到文件的格式
彩色输出
如果你的终端支持ANSI,设置彩色输出会让日志更具可读性。通过在application.yml中设置spring.output.ansi.enabled参数来支持。
- NEVER: 禁用ANSI-colored输出(默认项)
- DETECT: 会检查终端是否支持ANSI,是的话就采用彩色输出(推荐项)
- ALWAYS: 总是使用ANSI-colored格式输出,若终端不支持的时候,会有很多干扰信息,不推荐使用
以下内容是开启彩色输出后的日志内容:
2021-07-06 22:07:01.698 INFO(绿色) 1509 --- [ restartedMain] com.summer.log.LogApplication : Started LogApplication in 1.3 seconds (JVM running for 2.084)
2021-07-06 22:07:01.700 WARN(棕色) 1509 --- [ restartedMain] com.summer.log.LogApplication : this is warn log
2021-07-06 22:07:01.701 ERROR(红色) 1509 --- [ restartedMain] com.summer.log.LogApplication : this is error log
日志组
将相关记录器组合在一起以便可以同时配置,这通常很有用。例如,您可以更改所有 Tomcat 相关记录器的日志记录级别,但您无法轻松记住顶层的包名。
为了解决这个问题,Spring Boot 允许您在 Spring Environment 中定义日志记录组。例如,以下通过将tomcat 组添加到 application.yml 来定义tomcat 组:
logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
定义后,可以使用一行配置来更改组中所有记录器的级别:
logging.level.tomcat=TRACE
Spring Boot 包含以下预定义的日志记录组,可以直接使用:
名称 | 日志记录器 |
web |
|
sql |
|
使用log4j2
Spring Boot2.x默认使用logback作为日志输出组件,当然,我们也可以使用其他日志组件替代,如:log4j2
- 先排除 Logback
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
- 引入log4j2
<!--log4j2 依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
- log4j2.xml配置
<?xml version="1.0" encoding="UTF-8"?>
<!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration后面的status,这个用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,你会看到log4j2内部各种详细输出-->
<!--monitorInterval:Log4j能够自动检测修改配置 文件和重新配置本身,设置间隔秒数-->
<configuration status="WARN" monitorInterval="30">
<!--先定义所有的appender-->
<appenders>
<!--这个输出控制台的配置-->
<console name="Console" target="SYSTEM_OUT">
<!--输出日志的格式-->
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
</console>
<!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,这个也挺有用的,适合临时测试用-->
<File name="log" fileName="log/test.log" append="false">
<PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
</File>
<!-- 这个会打印出所有的info及以下级别的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档-->
<RollingFile name="RollingFileInfo" fileName="${sys:user.home}/logs/info.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/info-%d{yyyy-MM-dd}-%i.log">
<!--控制台只输出level及以上级别的信息(onMatch),其他的直接拒绝(onMismatch)-->
<ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
<RollingFile name="RollingFileWarn" fileName="${sys:user.home}/logs/warn.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/warn-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
<!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 -->
<DefaultRolloverStrategy max="20"/>
</RollingFile>
<RollingFile name="RollingFileError" fileName="${sys:user.home}/logs/error.log"
filePattern="${sys:user.home}/logs/${date:yyyy-MM}/error-%d{yyyy-MM-dd}-%i.log">
<ThresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
<Policies>
<TimeBasedTriggeringPolicy/>
<SizeBasedTriggeringPolicy size="100 MB"/>
</Policies>
</RollingFile>
</appenders>
<!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
<loggers>
<!--过滤掉spring和mybatis的一些无用的DEBUG信息-->
<logger name="org.springframework" level="INFO"/>
<logger name="org.mybatis" level="INFO"/>
<root level="all">
<appender-ref ref="Console"/>
<appender-ref ref="RollingFileInfo"/>
<appender-ref ref="RollingFileWarn"/>
<appender-ref ref="RollingFileError"/>
</root>
</loggers>
</configuration>
使用logback
logback作为Spring Boot默认的日志框架,使用起来那就相当方便了。一般情况下,通过yaml配置就能满足基本需求。
代码如下:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.18</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
配置文件
logging:
level:
root: info
com.zimug.boot.launch.controller: debug
file:
path: ./log
name: springboot-learning.log
max-size: 10MB
max-history: 10
pattern:
console: '%red(%d{yyyy-MM-dd HH:mm:ss}) %green([%thread]) %highlight(%-5level) %boldMagenta(%logger{10}) - %cyan(%msg%n)'
file: '%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level [%thread] %logger : %msg%n'
测试代码:
@Slf4j
@RestController
@RequestMapping("/log")
public class LogController {
@GetMapping("{logname}")
public String getLogname(@PathVariable("logname") String logname) {
log.debug("这是使用logback打印的日志:{}-{}", logname, LocalDate.now());
log.info("这是使用logback打印的日志:{}-{}", logname, LocalDate.now());
log.warn("这是使用logback打印的日志:{}-{}", logname, LocalDate.now());
log.error("这是使用logback打印的日志:{}-{}", logname, LocalDate.now());
return logname;
}
}
测试结果:
2021-08-04 15:08:32 [http-nio-8080-exec-2] INFO c.s.l.w.LogController - 这是使用logback打印的日志:test-2021-08-04
2021-08-04 15:08:32 [http-nio-8080-exec-2] WARN c.s.l.w.LogController - 这是使用logback打印的日志:test-2021-08-04
2021-08-04 15:08:32 [http-nio-8080-exec-2] ERROR c.s.l.w.LogController - 这是使用logback打印的日志:test-2021-08-04
伙伴们,行动起来,加油!!!
> 源码地址:
Spring Boot Learning: 学习springboot中的各个组件,编写示例工程
运行spring-boot-log(log4j2)和spring-boot-log-logback(logback)工程。