26. 日志

Spring Boot内部日志系统使用的是Commons Logging,但开放底层的日志实现,默认为会Java Util Logging, Log4J, Log4J2Logback提供配置。每种情况下都预先配置使用控制台输出,也可以使用可选的文件输出。

默认情况下,如果你使用'Starters',那么就会使用Logback记录日志。为了确保使用Java Util Logging, Commons Logging, Log4J或SLF4J的依赖库能够正常工作,相应的Logback路由也会包含进来。

如果上面的列表看起来令人困惑,不要担心,Java有很多可用的日志框架。通常,你不需要改变日志依赖,Spring Boot默认的就能很好的工作。

26.1. 日志格式

Spring Boot默认的日志输出格式如下:

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: [/*]

输出的节点(items)如下:

  1. 日期和时间 - 精确到毫秒,且易于排序。
  2. 日志级别 - ERROR, WARN, INFO, DEBUGTRACE
  3. Process ID。
  4. ---分隔符,用于区分实际日志信息开头。
  5. 线程名 - 包括在方括号中(控制台输出可能会被截断)。
  6. 日志名 - 通常是源class的类名(缩写)。
  7. 日志信息。

Logback没有FATAL级别,它会映射到ERROR

26.2. 控制台输出

默认的日志配置会在写日志消息时将它们回显到控制台,级别为ERROR, WARNINFO的消息会被记录。你可以在启动应用时,通过--debug标识开启控制台的DEBUG级别日志记录,也可以在application.properties中指定debug=true

$ java -jar myapp.jar --debug

当debug模式启用时,一系列核心loggers(内嵌容器,Hibernate,Spring Boot等)记录的日志会变多,但不会输出所有的信息。

相应地,你可以在启动应用时,通过--trace(或在application.properties设置trace=true)启用"trace"模式,该模式能够追踪核心loggers(内嵌容器,Hibernate生成的schema,Spring全部的portfolio)的所有日志信息。

26.2.1 Color-coded输出

如果你的终端支持ANSI,Spring Boot将使用彩色编码(color output)输出日志以增强可读性,你可以将spring.output.ansi.enabled设置为一个支持的值来覆盖默认设置。

彩色编码(Color coding)使用%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

26.3. 文件输出

默认情况下,Spring Boot只会将日志记录到控制台,而不写进日志文件,如果需要,你可以设置logging.filelogging.path属性(例如application.properties)。

下表展示如何组合使用logging.*

logging.file logging.path 示例 描述
(none) (none) 只记录到控制台
Specific file (none) my.log 写到特定的日志文件,名称可以是精确的位置或相对于当前目录
(none) Specific directory /var/log 写到特定目录下的spring.log里,名称可以是精确的位置或相对于当前目录

日志文件每达到10M就会被分割,跟控制台一样,默认记录ERROR, WARNINFO级别的信息。

26.4. 日志级别

所有Spring Boot支持的日志系统都可以在Spring Environment中设置级别(application.properties里也一样),设置格式为'logging.level.*=LEVEL',其中LEVELTRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF之一:

以下是application.properties示例:

logging.level.root=WARN
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

默认情况,Spring Boot会重新映射Thymeleaf的INFO信息到DEBUG级别,这能减少标准日志输出的噪声。查看LevelRemappingAppender可以按自己的配置设置映射。

26.5. 自定义日志配置

通过将相应的库添加到classpath可以激活各种日志系统,然后在classpath根目录下提供合适的配置文件可以进一步定制日志系统,配置文件也可以通过Spring Environmentlogging.config属性指定。

使用org.springframework.boot.logging.LoggingSystem系统属性可以强制Spring Boot使用指定的日志系统,该属性值需要是LoggingSystem实现类的全限定名,如果值为none,则彻底禁用Spring Boot的日志配置。

由于日志初始化早于ApplicationContext的创建,所以不可能通过@PropertySources指定的Spring @Configuration文件控制日志,系统属性和Spring Boot外部化配置可以正常工作。

以下文件会根据你选择的日志系统进行加载:

日志系统 定制配置
Logback logback-spring.xml,logback-spring.groovy,logback.xmllogback.groovy
Log4j log4j.propertieslog4j.xml
Log4j2 log4j2-spring.xmllog4j2.xml
JDK (Java Util Logging) logging.properties

如果可能的话,建议你使用-spring变种形式定义日志配置(例如,使用logback-spring.xml而不是logback.xml)。如果你使用标准的配置路径,Spring可能不能够完全控制日志初始化。

Java Util Logging从可执行jar运行时会导致一些已知的类加载问题,我们建议尽可能不使用它。

以下是从Spring Envrionment转换为System properties的一些有助于定制的配置属性:

Spring Environment System Property Comments
logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD 记录异常使用的关键字
logging.file LOG_FILE 如果指定就会在默认的日志配置中使用
logging.path LOG_PATH 如果指定就会在默认的日志配置中使用
logging.pattern.console CONSOLE_LOG_PATTERN 日志输出到控制台(stdout)时使用的模式(只支持默认的logback设置)
logging.pattern.file FILE_LOG_PATTERN 日志输出到文件时使用的模式(如果LOG_FILE启用,只支持默认的logback设置)
logging.pattern.level LOG_LEVEL_PATTERN 用来渲染日志级别的格式(默认%5p,只支持默认的logback设置)
PID PID 当前的处理进程(process)ID(能够找到,且还没有用作OS环境变量)

所有支持的日志系统在解析配置文件时都能获取系统属性的值,具体可以参考spring-boot.jar中的默认配置。

如果想在日志属性中使用占位符,你需要使用Spring Boot的语法,而不是底层框架的语法。尤其是使用Logback时,你需要使用:作为属性名和默认值的分隔符,而不是:-

通过覆盖LOG_LEVEL_PATTERN(Logback对应logging.pattern.level),你可以向日志中添加MDC和其他ad-hoc的内容。例如,将该值设置为logging.pattern.level=user:%X{user} %5p,则默认日志格式将包含一个"user"的MDC实体,如果存在的话,比如:

2015-09-30 12:30:04.031 user:juergen INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

26.6 Logback扩展

Spring Boot包含很多有用的Logback扩展,你可以在logback-spring.xml配置文件中使用它们。

你不能在标准的logback.xml配置文件中使用扩展,因为它加载的太早了,不过可以使用logback-spring.xml,或指定logging.config属性。

26.6.1 Profile-specific配置

<springProfile>标签可用于根据激活的Spring profiles,选择性的包含或排除配置片段。Profile片段可以放在<configuration>元素内的任何地方,使用name属性定义哪些profile接受该配置,多个profiles以逗号分隔。

<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>

26.6.2 Environment属性

<springProperty>标签允许你从Spring Environment读取属性,以便在Logback中使用。如果你想在logback配置获取application.properties中的属性值,该功能就很有用。该标签工作方式跟Logback标准<property>标签类似,但不是直接指定value值,你需要定义属性的source(来自Environment),也可以指定存储属性作用域的scope。如果Environment没有相应属性,你可以通过defaultValue设置默认值。

<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>

RelaxedPropertyResolver用于获取Environment属性,如果以中划线的方式指定sourcemy-property-name),则所有relaxed变体都会进行尝试(myPropertyNameMY_PROPERTY_NAME等)。