Spring Boot2(013):日志
Spring Boot2系列文章可以通过这里进行回顾:SpringBoot2(001):入门介绍、官网参考和博客汇总
本文主要针对 SpringBoot 应用的日志记录进行介绍,包括如何定制日志格式、日志文件、日志配置、选用哪些日志框架实现等,主要参考官方文档:26. Logging ,目录结构如下:
SpringBoot 使用 Commons Logging 作为内置的日志实现,但保留了低层的日志实现。 Java Util Logging, Log4J2, 和 Logback 都提供了默认配置。在每种情况下,日志记录器都预先配置为使用控制台作为输出,和可选的日志文件输出。
如果使用了 Starters ,默认情况下会使用 Logback 进行日志记录。恰当的 Logback 路由也会被包含进来,以确保使用 Java Util Logging, Commons Logging, Log4J, 或 SLF4J 的依赖包都能正常工作。
注:Java 有很多可用的 logging 框架。开发者并不需要对着上述的日志框架列表感到困惑。总体上来说,开发者并不需要修改日志依赖,SpringBoot 的默认配置会处理得很好。
1、日志格式 Log Format
默认的日志输出就像下面这个样子:
2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
输出内容项如下:
- 日期和时间:精确到毫秒,便于分类
- 日志级别:ERROR, WARN, INFO, DEBUG, 或者 TRACE
- 处理ID(Process ID)
- --- 分隔符,区分实际日志的开始。
- 线程名称:[] 包起来(可能被控制台输出截断)
- Logger名称:通常是打印日志的源类名称(通常是缩写限定名)
- 日志信息
Logback 并没有 FATAL 级别的日志,对应的是 ERROR 。
2、控制台输出 Console Output
默认日志配置在写入消息时将消息回显到控制台,默认输出 ERROR, WARN, 和 INFO 级别的日志消息。开发者可以通过在启动应用时增加 --flag(flag 表示日志级别,例如 --debug ) 参数来开启 debug 模式。
$ java -jar myapp.jar --debug
注:也可以通过在 application.properties 中配置 debug=true 来开启 debug 级别。
当启用 debug 模式时,一组核心 loggers (嵌入式容器、Hibernate, 和 Spring Boot)将会被配置以输出更多信息。开启 debug 模式并不意味着会配置应用的所有日志消息输出为 DEBUG 级别。
另外,开发者还可以通过 --trace 标志(或者在 application.properties 配置 trace=true)来开启 trace 模式。这样做会为一系列核心 loggers(嵌入式容器,Hibernate 模式生成,和整个 Spring 组合)开启 trace 日志记录。
2.1、彩色编码输出
如果开发者的终端支持 ANSI,彩色输出可以用来帮助提升可读性。开发者可以设置 spring.output.ansi.enabled 到一个 支持的值 以便支持默认的自动检测。彩色编码通过使用 %clr 转换字进行配置。最简单的形式是,转换器根据日志级别为输出着色,如下:
%clr(%5p)
下表描述了日志级别及对应的彩色映射关系:
Level | Color |
FATAL | Red |
ERROR | Red |
WARN | Yellow |
INFO | Green |
DEBUG | Green |
TRACE | Green |
或者,开发者可以通过提供应该要使用的颜色或样式作为转换的选项。例如,为了使文本输出为黄色,使用如下的设置:
%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}
如下颜色和样式都是支持的:
- blue
- cyan
- faint
- green
- magenta
- red
- yellow
3、文件输出
默认情况下,SpringBoot 只会记录日志到控制台,并不会写到日志文件去。开发者如果除了控制台输出之外还想写入日志文件,需要设置 logging.file 或者 logging.path 属性(例如在 application.properties 中)。
如下示例展示了 logging.* 可以怎样被一起使用:
logging.file | logging.path | Example | Description |
(none) | (none) | Console only logging. | |
Specific file | (none) | my.log | Writes to the specified log file. Names can be an exact location or relative to the current directory. |
(none) | Specific directory | /var/log | Writes spring.log to the specified directory. Names can be an exact location or relative to the current directory. |
日志文件到达 10MB 时会滚动生成新的,并且日志文件也像控制台输出一样,默认情况下会记录 ERROR, WARN, 和 INFO 级别的日志。文件大小限制可以通过 logging.file.max-size 属性进行修改。先前的日志文件会被永久归档保存,除非指定了 logging.file.max-history 进行限制。
注:日志系统会在应用生命周期的早期进行初始化。因此,在通过 @PropertySource 注解加载的属性文件中会找不到日志属性。
注:日志属性独立于实际的日志基础框架。因此,特定的配置键(例如 Logback 中的 logback.configurationFile )并不会被 SpringBoot 进行管理。
4、日志级别
所有支持的日志系统都可以在 Spring 的 Environment 中通过使用 logging.level.<logger-name>=<level> 来设置日志级别,其中 level 可以是 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, 或者 OFF 中的任意一个。root logger 可以通过 logging.level.root 进行设置。
下面的例子展示了 application.properties 中潜在的日志设置:
- logging.level.root=WARN
- logging.level.org.springframework.web=DEBUG
- logging.level.org.hibernate=ERROR
5、日志分组
能够将相关的日志记录器分组在一起,这样就可以同时对它们进行配置,这通常很有用。例如,开发者通常可能会更改所有 Tomcat 相关的日志记录器的日志级别,但是记住 tomcat 的顶级包通常不容易。
为了处理这种情况,SpringBoot 允许在 Spring Environment 中定义日志分组。如下就是在 application.properties 中添加了一个 tomcat 分组:
logging.group.tomcat=org.apache.catalina, org.apache.coyote, org.apache.tomcat
一旦定义好了,开发者就可以通过一行配置来修改分组里面的所有日志记录器的日志级别
logging.level.tomcat=TRACE
SpringBoot 包含了如下预定义的日志分组,可以开箱即用:
Name | Loggers |
web | org.springframework.core.codec, org.springframework.http, org.springframework.web |
sql | org.springframework.jdbc.core, org.hibernate.SQL |
6、定制日志配置
可以通过在 classpath 包含不同的引用包来激活不同的日志系统,还可以通过在 根 classpath 或者 Spring Environment 的属性 logging.config 指定的路径中提供合适的配置文件来进一步定制日志配置。
开发者可以通过系统属性 org.springframework.boot.logging.LoggingSystem 来强制指定使用特定的日志系统。这个属性值应该使用日志系统实现类的全限定名。开发者可以将值设置为 none 来完全关闭 SpringBoot 的日志配置。
注:由于日志会在 ApplicationContext 创建前进行初始化,不可能通过 Spring 的 @Configuration 文件中的 @PropertySources 来控制日志配置。
取决于日志系统,以下配置文件将会被加载:
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 |
注:可以的话,建议开发者使用 -spring 后缀的日志配置(例如使用 logback-spring.xml 而不是 logback.xml )。如果使用标准配置路径,Spring 不能完全控制日志初始化。
注:从 'executable jar' 运行时,Java Util Logging 有一些已知的会导致问题的 classloading issues 。建议开发者从 'executable jar' 运行时尽可能避免它。
为了方便定制日志,其他一些属性会从 Spring Environment 转移到系统属性 System properties,如下表描述:
Spring Environment | System Property | Comments |
logging.exception-conversion-word | LOG_EXCEPTION_CONVERSION_WORD | The conversion word used when logging exceptions. |
logging.file | LOG_FILE | If defined, it is used in the default log configuration. |
logging.file.max-size | LOG_FILE_MAX_SIZE | Maximum log file size (if LOG_FILE enabled). (Only supported with the default Logback setup.) |
logging.file.max-history | LOG_FILE_MAX_HISTORY | Maximum number of archive log files to keep (if LOG_FILE enabled). (Only supported with the default Logback setup.) |
logging.path | LOG_PATH | If defined, it is used in the default log configuration. |
logging.pattern.console | CONSOLE_LOG_PATTERN | The log pattern to use on the console (stdout). (Only supported with the default Logback setup.) |
logging.pattern.dateformat | LOG_DATEFORMAT_PATTERN | Appender pattern for log date format. (Only supported with the default Logback setup.) |
logging.pattern.file | FILE_LOG_PATTERN | The log pattern to use in a file (if LOG_FILE is enabled). (Only supported with the default Logback setup.) |
logging.pattern.level | LOG_LEVEL_PATTERN | The format to use when rendering the log level (default %5p). (Only supported with the default Logback setup.) |
PID | PID | The current process ID (discovered if possible and when not already defined as an OS environment variable). |
所有支持的日志系统在解析配置文件的时候都可以访问系统属性。具体参考 spring-boot.jar 中的默认配置:
建议:如果希望在日志属性中使用占位符,应该使用 Spring Boot的语法,而不是底层框架的语法。值得注意的是,如果开发者使用了 Logback ,应该使用 : 作为属性名和默认值的分隔符,而不是 :- 。
建议:仅通过覆盖 LOG_LEVEL_PATTERN (或 Logback 的 logging.pattern.level ),开发者可以将 MDC 和其他特别内容添加到日志记录行中。例如,使用 logging.pattern.level=user:%X{user} %5p ,则默认的日志记录格式中会包含有 "user" 的 MDC 条目(如果存在的话),如下所示:
2015-09-30 12:30:04.031 user:someone INFO 22174 --- [ nio-8080-exec-0] demo.Controller Handling authenticated request
7、Logback 扩展
Spring Boot 提供了一系列 Logback 扩展用于进行高级配置。开发者可以在 logback-spring.xml 配置文件中使用这些扩展。
注:因为标准的 logback.xml 会过早加载,所以用不了扩展。开发者需要确保使用的是 logback-spring.xml 或者 定义了 logging.config 属性。
警告: Logback 扩展不能和 Logback’s configuration scanning 一起使用。如果开发者这样做,修改日志配置文件可能会导致类似如下记录的错误:
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]
7.1、Profile-specific Configuration
<springProfile> 标签允许开发者根据激活的 Spring profiles 来选择包含或排除部分配置。配置部分被包含在 <configuration> 元素中。使用 name 属性来指定哪个 profile 需要使用哪些配置。<springProfile> 标签允许使用简单的 profile name (例如 staging),也支持 profile 表达式。profile expression 允许更加复杂的表示逻辑,例如 production & (eu-central | eu-west) 。详情参考: reference guide 。下述列表描述了3种样例:
<springProfile name="staging"> <!-- configuration to be enabled when the "staging" profile is active --> </springProfile> <springProfile name="dev | staging"> <!-- configuration to be enabled when the "dev" or "staging" profiles are active --> </springProfile> <springProfile name="!production"> <!-- configuration to be enabled when the "production" profile is not active --> </springProfile>
7.2 环境属性 Environment Properties
<springProperty> 标签允许从 Spring Environment 公开属性给 Logback 使用。如果开发者想要在 Logback 配置中访问 application.properties 文件中的属性值的话,这样做确实会很有用。这个标签和 Logback 的标准标签 <property> 工作方式类似。然而,开发者指定属性来源(从 Environment ),而不是直接指定值。如果开发者需要将改属性值存储在除本地范围之外的其他地方,则可以使用 scope 属性。如果需要指定 a fallback value(在 Environment 中没有设置该属性的情况下使用),可以使用 defaultValue 属性。下面这个例子展示了如何公开属性以便供 Logback 使用:
<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>
注:source 必须使用横杆的方式进行指定(例如: my.property-name )。然而,添加到 Environment 中的属性是可以使用宽松的规则绑定。
8、参考
- 官方文档:26. Logging