[TOC]
简介
Spring Boot 内部使用的日志框架为Commons Logging,但是 Commons Logging 的内部具体实现可以由用户自行指定。
默认已提供了对 Java Utils Logging,Log4J2 和 Logback 日志库的相关配置。
无论选择以上哪一个日记库,Spring Boot 都预置了将日志输出到控制台以及可选的文件上。
如果项目配置使用起步依赖(Starters),那么默认情况下,Spring Boot 使用的日记记录库为 Logback。
因此,本文主要介绍在 Spring Boot 中使用 Logback 进行日志记录。
依赖导入
前面已经介绍过,Spring Boot 默认使用的日志框架为 Apache Commons Logging。
在 Spring 4.x(也即 Spring Boot 1.x)时,我们需要手动进行依赖导入。
但是在 Spring 5.x(也即 Spring Boot 2.x)时,该依赖由 Spring Framework 模块 spring-jcl 提供。
当我们项目使用各种起步依赖(Starter)时,spring-jcl 模块包含在 spring-boot-starter-logging 中,理论上我们需要手动导入该依赖,如下所示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
但实际上我们无需手动导入该起步依赖,因为几乎每一个起步依赖(比如:spring-boot-starter,spring-boot-starter-web...)都内置了 spring-boot-starter-logging。
因此,当我们使用起步依赖创建 Spring Boot 项目时,日志功能开箱即可用。
且日记框架内部默认实现采用 Logback。
日志内容简介
-
日志格式:默认情况下,当我们运行程序时,控制台会输出如下日志信息:
Spring Boot logging日志格式默认涵盖 7 个字段,分别为:
-
日期和时间:精确到毫秒且易于排序。
配置时可通过占位符%msg或%m进行引用。 -
日志级别(Log Level):总共包含 5 种日志级别:ERROR,WARN,INFO,DEBUG,TRACE。
配置时可通过%p进行引用。
注:日志级别具体排序(由低到高)如下:TRACE < DEBUG < INFO < WARN < ERROR < FATAL。且默认的日志输出级别为 INFO,低于 INFO 级别的日志信息不会输出,也即此时就只会输出 INFO,WARN,ERROR 和 FATAL 信息,而不会输出 TRACE 和 DEBUG 日志信息。 -
进程ID:可通过 Mapped Diagnostic Context (MDC) 功能绑定将 进程ID 信息绑定到当前线程上,等待后续日志记录时使用。
注:MDC 运行在应用启动过程中,添加相关诊断信息到当前线程上,方便后续日志记录时进行使用。 - 分隔符(---):标识真实日志的起始位置。
-
线程名:方括号([])内部的内容(控制台输出可能会被截断)。
可通过%thread或%t进行引用。 -
日志记录者:通常为日志打印的源码类名(类名通常会被进行缩略/简写)。
可通过%logger进行引用。 -
日志信息:可通过
%mgs或%m进行引用。
-
日期和时间:精确到毫秒且易于排序。
-
日志默认配置:下面简单介绍下 Spring Boot 中,对 Logback 的默认配置:
前文提及,Spring Boot 默认采用 Logback 作为日志记录库,支持控制台和文件日记记录,其中,控制台日志记录默认配置文件为:
org\springframework\boot\logging\logback\console-appender.xml,其内容大致如下:<included> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> ... <encoder> <pattern>${CONSOLE_LOG_PATTERN}</pattern> ... </encoder> </appender> </included>可以看到,Logback 默认的控制台日志输出格式为
CONSOLE_LOG_PATTERN,该属性定义在文件:org\springframework\boot\logging\logback\defaults.xml:<included> <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" /> ... <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" /> <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(${LOGGED_APPLICATION_NAME:-}[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/> ... </included>所以控制台默认的输出格式为:
%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd'T'HH:mm:ss.SSSXXX}}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr(${LOGGED_APPLICATION_NAME:-}[%15.15t]){faint} %clr(${LOG_CORRELATION_PATTERN:-}){faint}%clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}像
%clr这些操作符主要用于进行颜色设置,去除这些修饰符后,主要的日志配置格式如下:%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX} %p ${PID:-} %t %logger :%m%n%wEx同理,文件日志功能配置与控制台日志大同小异,其默认配置文件为:
org\springframework\boot\logging\logback\file-appender.xml
基础用法
-
日志打印:在项目中具体使用日志进行打印的方法如下:
@RestController @RequestMapping("logging") public class LogController { private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping("/") public String index() { logger.trace("A TRACE Message"); logger.debug("A DEBUG Message"); logger.info("An INFO Message"); logger.warn("A WARN Message"); logger.error("An ERROR Message"); return "logging page"; } }注:Logback 没有 FATAL 级别,它被映射到 ERROR 级别。
此时运行项目,然后请求
curl localhost:8080/logging/,可以在控制台观察到如下日志信息:logger前文已经讲过,Spring Boot 默认使用的日志级别为 INFO,因此 TRACE 和 DEBUG 日志信息不会得到输出。
而如果想输出其他级别的日志,就需要更改日志级别,其方法有很多,比如:
-
输出 DEBUG 日志:只需启动 DEBUG 模式,启动方法有如下几种方法:
-
使用 --debug 标识:启动项目时,加入该标识即可:
# SpringBootDemos-1.0-SNAPSHOT.jar 是项目生成对应的 jar 包 $ java -jar target/SpringBootDemos-1.0-SNAPSHOT.jar --debug注:生成可执行 jar 包的方法可查看 附录
-
配置文件:在
application.properties配置文件中启动 DEBUG 模式:debug=true
注:使能 DEBUG 模式 就可以在控制台中看到 DEBUG 级别日志信息,但是自己的应用并未配置为 DEBUG 模式,也就是说即使使能了 DEBUG 模式,自己应用内输出的 DEBUG 信息还是不会打印到控制台。如果想让应用也能输出 DEBUG 日志,可以通过配置
logging.level.root=debug... -
-
输出 TRACE 日志:使用
--trace标识或者配置文件中配置trace=true。-
项目日志级别更改:通过在配置文件中配置如下内容:
# 项目的日志级别设置为 WARN(根 logger) logging.level.root=warn # org.springframework.web 包日志级别(包 looger) logging.level.org.springframework.web=debug # com.yn 包日志级别(此时项目该包下的所有日志就都会打印输出) logging.level.com.yn=trace -
使用日志配置文件:可以通过在
classpath路径下提供一个自定义的日志配置文件logback-spring.xml,对日志级别进行设置,如下所示:<!-- resources/logback-spring.xml --> <logger name="org.springframework" level="INFO" /> <logger name="com.yn" level="INFO" />更多具体配置内容,请参考下文:自定义日志配置:Logback 配置文件
还有其他一些设置日志级别的方法,这里就不展开阐述了。
更多内容可参考:Log Levels,zero-configuration-logging
-
简化调用:实际开发中,我们还可以使用 Lombok 来简化日志记录,如下代码所示:
@RestController @RequestMapping("logging") @Slf4j // 其他还有:@Log @CommonsLog @Log4j @Log4j2 @XSlf4j public class LogController { // private Logger logger = LoggerFactory.getLogger(this.getClass()); @GetMapping("/") public String index() { // @Slf4j 会自动注入一个名为 log 的日志记录实例 log.trace("A TRACE Message"); log.debug("A DEBUG Message"); log.info("An INFO Message"); log.warn("A WARN Message"); log.error("An ERROR Message"); return "logging page"; } }注:SLF4J 表示:Simple Logging Facade For Java。它是对所有 Java 的日志记录框架的一个门面装饰,定义了统一的日志抽象接口。
-
生成日志文件:默认情况下,Spring Boot 只会将日志输出到控制台中,不会写入到文件。但我们可以通过配置
logging.file.name或logging.file.path开启日志文件记录功能:# application.properties # 设置日志文件路径(默认生成的日志文件名为:spring.log) logging.file.path=/var/log # 设置日志文件名 # 相对路径 logging.file.name=my.log # 绝对路径 logging.file.name=/var/log/my.log注:
logging.file.path和logging.file.name如果同时进行配置,则只有logging.file.name生效。日志文件每达到 10 MB 就会发生滚动,重新生成一个新的日志文件。日志文件的切割尺寸可通过
logging.file.max-size进行设置。# 设置日志文件大小 logging.file.max-size=10MB默认情况下,Spring Boot 只会保留最近 7 天内生成的日志文件,可通过
logging.file.max-history配置日志保留时间。# 日志保留时间 logging.file.max-history=10日志归档文件总大小可通过属性
logging.file.total-size-cap进行设置,当日志归档超过设置的阈值时,备份的日志会被删除。在应用每次启动时,如果想强制清理日志归档文件,可以通过配置
logging.file.clean-history-on-start属性。
自定义日志配置:Logback 配置文件
Spring Boot 支持多种不同的日志系统实现,可以通过导入相应的依赖库从而在运行时激活对应的日志系统,并且可以通过在classpath或logging.config属性指定一个配置文件,实现自定义系统日志配置。
对于不同的日志系统,Spring Boot 会默认加载的日志配置文件如下表所示:
| Logging System | Customization |
|---|---|
| Logback |
logback-spring.xml,logback-spring.groovy,logback.xml或logback.groovy
|
| Log4j2 |
log4j2-spring.xml或log4j2.xml
|
| JDK (Java Util Logging) | logging.properties |
注:Spring Boot 建议我们使用带有-spring后缀的作为日志配置文件名称(即相较于使用logback.xml,更建议使用logback-spring.xml)。
如果使用标准配置路径,Spring 无法完全控制日志初始化过程(因为logback.xml的加载时间非常早,导致一些扩展功能无法在其内进行配置,而此时使用logback-spring.xml 即可解决这个问题)。
我们主要关注的是 Logback 的配置文件内容。
要对 Logback 添加配置文件,只需创建resources/logback-spring.xml,然后对该文件进行配置即可,其基本配置内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<contextName>logback</contextName>
<!-- 创建一个属性/变量-->
<property name="LOGS" value="./logs"/>
<!-- 控制台输出配置 -->
<appender name="Console"
class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>
%black(%d{ISO8601}) %highlight(%-5level) [%blue(%t)] %yellow(%C{1.}): %msg%n%throwable
</Pattern>
</layout>
</appender>
<!-- 输出到文件 -->
<appender name="RollingFile"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/spring-boot-logger.log</file>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</encoder>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily and when the file reaches 10 MegaBytes -->
<fileNamePattern>${LOGS}/archived/spring-boot-logger-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
</appender>
<!-- 根logger,项目日志配置 -->
<root level="info">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</root>
<!-- 为包 com.yn 创建一个日志实例 -->
<logger name="com.yn" level="trace" additivity="false">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</logger>
</configuration>
注:日志配置文件路径也可以在application.properties中进行指定:
logging.config=classpath:logback-spring.xml
简单对上述 logback-spring.xml 的配置内容进行一些介绍:
-
<configuration>:配置文件起始块标签,其内我们配置了以下 3 个属性:-
scan:默认值为true,表示当日志配置文件发生改变时,重新加载该文件。 -
scanPeriod:检测日志配置文件是否被更改的时间间隔。默认时间单位为毫秒,默认扫描间隔为 1 分钟。
注:scanPeriod属性只有在scan=true时,才会生效。 -
debug:当此属性设为true时,则会打印 logback 内部日志信息,实时显示 logback 运行状态。该属性默认值为false。
-
<contextName>:该标签用于为 logger 实例设置上下文名称。其默认值为default。可以通过%contextName来打印日志上下文名称。
注:可以通过<contextName>来对不同的应用设置各自的名称,这样就可以在同一个日志文件中区分不同应用的日志信息。<property>:该标签用于创建一个变量,后续该配置文件可以通过${property.name}方式引用该变量。-
<<appender>>:该标签用于配置日志输出节点,其有两个属性:name和class。其中:-
name:用于设置输出节点名称(可设置任意名称) -
class:用于指定输出策略。常用的输出到控制台与输出到文件的class如上述配置所示。
-
<root>:该标签用于创建一个根logger,配置项目日志输出级别(相当于属性loging.level.root)。
其内部通过标签<appender-ref>引用了我们前面创建的日志输出节点配置。<logger>:该标签用于为某个包,或者具体某个类创建一个日志记录实例。
注:其中addtivity表示是否向上级 logger 传递打印信息,默认为true。
更多 Logback 配置文件内容,请参考:A Guide To Logback
多环境日志配置
可以通过在日志配置文件中使用标签<springProfile>来创建不同的环境日志配置。
比如,我们可以通过定义生产环境prod,测试环境test和开发环境dev来实现不同的日志输出,如下所示:
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
...
<!-- 测试环境+开发环境. 多个使用逗号隔开. -->
<springProfile name="test,dev">
<logger name="com.yn.logging" level="debug"/>
</springProfile>
<!-- 生产环境. -->
<springProfile name="prod">
<root level="info">
<appender-ref ref="RollingFile"/>
<appender-ref ref="Console"/>
</root>
<logger name="com.yn.logging" level="ERROR"/>
</springProfile>
</configuration>
然后,启动服务的时候,设置相应环境的 profile 即可。
比如,可以直接通过命令指定运行环境 profile,如下:
# 运行在开发环境
$ java -jar xxx.jar --spring.profiles.active=dev
Spring Boot 多环境配置内容,可参考:Spring Boot - 多环境配置
其他
-
Spring 环境变量获取:在 Logback 日志配置文件中,可以通过标签
<springProperty>来获取 Spring 环境变量(即application.properties中定义的属性),如下所示:<!-- logback-spring.xml --> <springProperty scope="context" name="fluentHost" source="myapp.fluentd.host" defaultValue="localhost"/> <appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender"> <remoteHost>${fluentHost}</remoteHost> ... </appender><springProperty>标签功能类似于 Logback 的标注标签<property>,但是它有 4 个属性,分别如下:-
name:变量名 -
scope:指定变量存储环境上下文(默认为local) -
source:指定要获取的 Spring 环境属性名 -
defaultValue:如果获取不到属性,使用该默认值
-
-
日志颜色控制:如果你的终端支持 ANSI,那么可以通过设置颜色文字增加可读性。
-
可以通过配置
spring.output.ansi.enabled属性来覆盖默认的自动检测,其可选值如下所示:# application.properties # 开启颜色输出 spring.output.ansi.enabled=always # 自动检测开启颜色输出 spring.output.ansi.enabled=detect # 关闭颜色输出 spring.output.ansi.enabled=never -
如果终端支持 ANSI,则可以通过
%clr来配置文字颜色。最简单的配置方式如下:
%clr(%5p)此时不同的日志级别会默认采用不同的颜色进行区分,具体如下表所示:
Level Color FATAL红色 ERROR红色 WARN黄色 INFO绿色 DEBUG绿色 TRACE绿色 当然,我们也可以对不同的日志级别设置别的颜色,支持设置的颜色有如下可选值:
-
blue:蓝色 -
cyan:青色 -
faint:浅灰色 -
green:绿色 -
magenta:品红色 -
red:红色 -
yellow:黄色
比如,将日期文字设置为黄色,其配置如下:
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow} -
举个例子:假设我们要对日志级别进行区分,比如对于
INFO和WARN日志,将INFO日志相关信息(日志级别+类名)设置为绿色,将WARN日志相关信息设置为黄色,方便我们进行区分,则可如下进行配置:<!-- resources/logback-spring.xml --> <?xml version="1.0" encoding="UTF-8"?> <configuration> <!-- 导入 defaaults.xml,使能 %clr 等功能 --> <include resource="org/springframework/boot/logging/logback/defaults.xml"/> <!-- 通用日志格式 --> <property name="STDOUT_LOG_PATTERN_GENERAL" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSSXXX}){faint} %clr(%5p) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n%wEx" /> <!-- info 日志格式 --> <property name="STDOUT_LOG_PATTERN_INFO" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSSXXX}){faint} %clr(%5p){green} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){green} %clr(:){faint} %highlight(%m%n%wEx)" /> <!-- warn 日志格式 --> <property name="STDOUT_LOG_PATTERN_WARN" value="%clr(%d{yyyy-MM-dd HH:mm:ss.SSSXXX}){faint} %clr(%5p){yellow} %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){yellow} %clr(:){faint} %highlight(%m%n%wEx)" /> <appender name="STDOUT_GENERAL" class="ch.qos.logback.core.ConsoleAppender"> <!-- 过滤器:去除 INFO 日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>DENY</onMatch> <!-- NEUTRAL:表示对不匹配的情况不做任何操作,允许其他级别的日志继续传递到下一个过滤器或最终的输出 --> <onMismatch>NEUTRAL</onMismatch> </filter> <!-- 过滤器:去除 WARN 日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>DENY</onMatch> <onMismatch>NEUTRAL</onMismatch> </filter> <encoder> <pattern>${STDOUT_LOG_PATTERN_GENERAL}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="STDOUT_INFO" class="ch.qos.logback.core.ConsoleAppender"> <!-- 过滤器:只输出 INFO 日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>${STDOUT_LOG_PATTERN_INFO}</pattern> <charset>UTF-8</charset> </encoder> </appender> <appender name="STDOUT_WARN" class="ch.qos.logback.core.ConsoleAppender"> <!-- 过滤器:只输出 WARN 日志 --> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>WARN</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern>${STDOUT_LOG_PATTERN_WARN}</pattern> <charset>UTF-8</charset> </encoder> </appender> <!-- Root logger configuration --> <root level="INFO"> <appender-ref ref="STDOUT_GENERAL"/> <appender-ref ref="STDOUT_INFO"/> <appender-ref ref="STDOUT_WARN"/> </root> </configuration>过滤的模式均采用 Spring Boot 的默认格式,因此稍显冗长,但实际上着色部分就是通过
%clr(%p){color}改变日志级别颜色,%clr(%logger){color}更改类名颜色,以及%highlight(%m%n%wEx)设置日志信息默认级别颜色。 -
-
日志分组:应用中可能存在多个相关的日志实例(logger),那么此时通过 日志分组 功能就可以同时对这些日志实例进行配置。
比如,如果我们想更改所有 Tomcat 相关日志配置,那么就可以通过将其打包进一个日志组中,如下所示:
# application.properties # tomcat 日志组 logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat然后对该组进行配置即可,比如,更改 tomcat 组的日志级别:
logging.level.tomcat=TRACESpring Boot 默认预置了以下几个日志组,可以直接使用,如下表所示:
Name Loggers web org.springframework.core.codec,org.springframework.http,org.springframework.web,org.springframework.boot.actuate.endpoint.web,org.springframework.boot.web.servlet.ServletContextInitializerBeanssql org.springframework.jdbc.core,org.hibernate.SQL,org.jooq.tools.LoggerListener
附录
-
Lombok 安装:步骤如下:
-
首先导入 Lombok 依赖:
<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.12</version> <scope>provided</scope> </dependency> 接着为 idea 安装 Lombok 插件,消除代码错误显示:File - Settings - Plugins - 搜索 Lombok - install,安装完成后重启即可。
开启 annotation processing:File - Settings - Build,Execution,Deployment - Compiler - Annotation Processors,右侧勾选 Enable annotation processing,最后点击 OK 完成配置。
-
-
生成可执行 jar 包:在
pom.xml中做如下配置:<build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>然后执行:
mvn clean package打包生成可执行 jar 包。


