Logging

Spring Boot为所有内部日志记录使用 Commons Logging,但会保留底层日志实现的开放性。提供了{apiref-openjdk}/java.logging/java/util/logging/package-summary.html[Java Util Logging]、 Log4j2Logback的默认配置。在每种情况下,预先配置记录器以使用控制台输出,也可以选择使用文件输出。 默认情况下,如果你使用"`Starters`",则Logback用于日志记录。还包括了适当的Logback路由,以确保使用Java Util Logging、Commons Logging、Log4J或SLF4J的依赖库可以正常工作。

Java 可用很多日志记录框架。如果上述清单看起来很混乱,别担心。通常,您无需更改您的日志记录依赖关系,而且 Spring Boot 默认设置即可正常工作。

当您将应用程序部署到 servlet 容器或应用程序服务器时,使用 Java Util Logging API 执行的日志记录不会路由到应用程序的日志中。这会阻止由容器或已部署到容器的其他应用程序执行的日志记录出现在应用程序的日志中。

Log Format

Spring Boot 的默认日志输出类似于以下示例:

Unresolved include directive in modules/ROOT/pages/features/logging.adoc - include::ROOT:partial$logging/logging-format.txt[]

将输出以下项目:

  • 日期和时间:毫秒精度,且易于排序。

  • 日志级别:\“1\”、“2\”、“3\”、“4\”或\“5\”。

  • Process ID.

  • \“6\”分隔符,以区别实际日志消息的开头。

  • 应用程序名称:用方括号括起(仅在设置 configprop:spring.application.name[] 时默认记录)

  • 线程名称:用方括号括起(控制台输出时可能截断)。

  • 相关性 ID:如果启用了跟踪(上面示例中未显示)

  • 记录器名称:这通常是源类名(通常是缩写)。

  • The log message.

Logback 没有\“7\”级别。它映射为\“8\”。

如果您有一个 configprop:spring.application.name[] 属性但不想将其记录,您可以将 configprop:logging.include-application-name[] 设置为\“9\”。

Console Output

默认日志配置会将消息在写入时回显到控制台。默认情况下,记录 @“11”- 级别、@“12”- 级别和 @“13”- 级别消息。您还可以通过使用 @“14” 标志启动应用程序来启用 @“10” 模式。

$ java -jar myapp.jar --debug

您还可以在 @“16” 中指定 @“15”。

当启用调试模式时,选择核心记录器(嵌入式容器、Hibernate 和 Spring Boot)配置为输出更多信息。启用调试模式不会配置您的应用程序,使其记录所有 @“17” 级别的消息。

或者,您还可以通过使用 @“20” 标志(或在 @“22” 中使用 @“21”)启动应用程序来启用 @“19” 模式。这样做会为选择的核心记录器(嵌入式容器、Hibernate 模式生成和整个 Spring 产品组合)启用跟踪日志记录。

Color-coded Output

如果您的终端支持 ANSI,将使用彩色输出以帮助提高可读性。您可以将 @“23” 设置为 @“24”,以覆盖自动检测。

使用 @“25” 转换词来配置颜色编码。在最简单的形式中,转换器根据日志级别对输出着色,如下例所示:

%clr(%5p)

以下表格介绍了日志级别到颜色的映射:

Level Color

FATAL

Red

ERROR

Red

WARN

Yellow

INFO

Green

DEBUG

Green

TRACE

Green

或者,您可以通过在转换中提供一个选项来指定应该使用的颜色或样式。例如,若要将文本变为黄色,请使用以下设置:

%clr(%d{yyyy-MM-dd'T'HH:mm:ss.SSSXXX}){yellow}

支持以下颜色和样式:

  • blue

  • cyan

  • faint

  • green

  • magenta

  • red

  • yellow

File Output

默认情况下,Spring Boot 只记录到控制台而不写入日志文件。如果您想在控制台输出之外写入日志文件,则需要设置一个 configprop:logging.file.name[] 或 configprop:logging.file.path[] 属性(例如,在 application.properties 中)。

以下表格展示了 logging.* 属性如何一起使用:

Table 1. Logging properties
configprop:logging.file.name[] configprop:logging.file.path[] Example Description

(none)

(none)

Console only logging.

Specific file

(none)

my.log

写入指定日志文件。名称可以是精确位置,也可以相对于当前目录。

(none)

Specific directory

/var/log

spring.log 写入指定目录。名称可以是精确位置,也可以相对于当前目录。

日志文件在达到 10 MB 时轮转,并且与控制台输出一样,默认记录 ERROR 级、WARN 级和 INFO 级消息。

日志记录属性与实际的记录基础设施无关。因此,具体的配置密钥(例如 Logback 的 logback.configurationFile)不由 Spring Boot 管理。

File Rotation

如果您使用的是 Logback,可以使用 application.propertiesapplication.yaml 文件微调日志轮转设置。对于所有其他日志记录系统,您需要自己直接配置轮转设置(例如,如果您使用 Log4j2,则可以添加 log4j2.xmllog4j2-spring.xml 文件)。

支持以下轮转策略属性:

Name Description

configprop:logging.logback.rollingpolicy.file-name-pattern[]

用于创建日志存档的文件名模式。

configprop:logging.logback.rollingpolicy.clean-history-on-start[]

当应用程序启动时,是否应该清理日志存档。

configprop:logging.logback.rollingpolicy.max-file-size[]

归档前日志文件的大小上限。

configprop:logging.logback.rollingpolicy.total-size-cap[]

删除前日志存档能占用的最大大小。

configprop:logging.logback.rollingpolicy.max-history[]

要保留的存档日志文件数上限(默认为 7)。

Log Levels

所有支持的日志记录系统都能在 Spring Environment 中设置记录器级别(例如,在 application.properties 中),使用 logging.level.<logger-name>=<level>,其中 level 是 TRACE、DEBUG、INFO、WARN、ERROR、FATAL 或 OFF 之一。root 记录器可以使用 logging.level.root 进行配置。

以下示例展示了 application.properties 中的潜在日志记录设置:

logging:
  level:
    root: "warn"
    org.springframework.web: "debug"
    org.hibernate: "error"

也可以使用环境变量设置日志记录级别。例如,LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUGorg.springframework.web 设置为 DEBUG

上述方法仅适用于包级别日志。由于松散绑定始终将环境变量转换为小写,因此无法配置此方法中单个类的日志记录。如果您需要配置类的日志记录,可以使用 the SPRING_APPLICATION_JSON 变量。

Log Groups

通常将相关的日志记录器组合在一起很有用,这样可以同时对其进行配置。例如,您可能经常更改 all Tomcat 相关日志记录器的日志级别,但您无法轻易记住顶级包。

为了帮助解决此问题,Spring Boot 允许您在 Spring Environment 中定义日志记录组。例如,以下是通过将其添加到 application.properties 中来定义 “tomcat” 组的方式:

logging:
  group:
    tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"

定义后,您可以使用单行更改组中所有日志记录器的级别:

logging:
  level:
    tomcat: "trace"

Spring 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.ServletContextInitializerBeans

sql

org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

Using a Log Shutdown Hook

为了在应用程序终止时释放日志记录资源,提供了一个关闭钩子,该钩子将在 JVM 退出后触发日志系统清理。除非您的应用程序作为 war 文件部署,否则此关闭钩子会自动注册。如果您的应用程序具有复杂的上下文层次结构,则关闭钩子可能无法满足您的需求。在发生这种情况时,请禁用关闭钩子并研究底层日志系统直接提供的选项。例如,Logback 提供 context selectors,允许在自己的上下文中创建每个 Logger。您可以使用 configprop:logging.register-shutdown-hook[] 属性来禁用关闭钩子。将它设置为 false 将禁用注册。您可以在 application.propertiesapplication.yaml 文件中设置属性:

logging:
  register-shutdown-hook: false

Custom Log Configuration

可以通过在类路径中包含适当的库来激活各种日志记录系统,并且可以通过在类路径的根目录或以下 Spring Environment 属性指定的位置提供合适的配置文件来进一步自定义:configprop:logging.config[]。

您可以通过使用 org.springframework.boot.logging.LoggingSystem 系统属性强制 Spring Boot 使用特定的日志记录系统。该值应该是 LoggingSystem 实现的完全限定的类名称。您还可以使用值 none 完全禁用 Spring Boot 的日志记录配置。

由于日志是在创建 ApplicationContext 时初始化的,因此无法在 Spring @Configuration 文件中从 @PropertySources 控制日志记录。更改日志记录系统或完全禁用它的唯一方法是通过系统属性。

根据您的日志记录系统,加载以下文件:

Logging System Customization

Logback

logback-spring.xml, logback-spring.groovy, logback.xml, 或 logback.groovy

Log4j2

log4j2-spring.xml or log4j2.xml

JDK (Java Util Logging)

logging.properties

如果可能,我们建议您为您的日志记录配置使用 -spring 变体(例如,使用 logback-spring.xml 而不用 logback.xml)。如果您使用标准配置位置,Spring 无法完全控制日志初始化。

Java Util Logging 存在已知的类加载问题,当从“可执行 jar”运行时会导致问题。如果您从“可执行 jar”运行,我们建议您在可以的情况下避免它。

为了帮助自定义,一些其他属性从 Spring Environment 传输到系统属性。这允许日志系统配置使用这些属性。例如,在 application.propertiesLOGGING_FILE_NAME 中将 logging.file.name 设置为环境变量将导致设置 LOG_FILE 系统属性。下表描述了传输的属性:

Spring Environment System Property Comments

configprop:logging.exception-conversion-word[]

LOG_EXCEPTION_CONVERSION_WORD

记录异常时使用的转换词。

configprop:logging.file.name[]

LOG_FILE

如果定义,则在默认日志配置中使用它。

configprop:logging.file.path[]

LOG_PATH

如果定义,则在默认日志配置中使用它。

configprop:logging.pattern.console[]

CONSOLE_LOG_PATTERN

在控制台(stdout)上使用的日志模式。

configprop:logging.pattern.dateformat[]

LOG_DATEFORMAT_PATTERN

日志日期格式的附加程序模式。

configprop:logging.charset.console[]

CONSOLE_LOG_CHARSET

用于控制台日志记录的字符集。

configprop:logging.threshold.console[]

CONSOLE_LOG_THRESHOLD

用于控制台日志记录的日志级别阈值。

configprop:logging.pattern.file[]

FILE_LOG_PATTERN

在文件中使用的日志模式(如果 LOG_FILE 已启用)。

configprop:logging.charset.file[]

FILE_LOG_CHARSET

用于文件日志记录的字符集(如果 LOG_FILE 已启用)。

configprop:logging.threshold.file[]

FILE_LOG_THRESHOLD

用于文件日志记录的日志级别阈值。

configprop:logging.pattern.level[]

LOG_LEVEL_PATTERN

呈现日志级别时要使用的格式(默认“%5p”)。

PID

PID

当前进程 ID(如果可能并且尚未将其定义为操作系统环境变量,则确定该 ID)。

如果你使用 Logback,还将转移以下属性:

Spring Environment System Property Comments

configprop:logging.logback.rollingpolicy.file-name-pattern[]

LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN

换行的日志文件名模式(默认 ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz)。

configprop:logging.logback.rollingpolicy.clean-history-on-start[]

LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START

在启动时是否清理归档日志文件。

configprop:logging.logback.rollingpolicy.max-file-size[]

LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE

Maximum log file size.

configprop:logging.logback.rollingpolicy.total-size-cap[]

LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP

要保留的日志备份的总大小。

configprop:logging.logback.rollingpolicy.max-history[]

LOGBACK_ROLLINGPOLICY_MAX_HISTORY

要保留的归档日志文件数目。

所有受支持的日志记录系统在解析它们的配置文件时都可以查阅系统属性。有关示例,请参见 spring-boot.jar 中的默认配置:

  • {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/logback/defaults.xml[Logback]

  • {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/log4j2/log4j2.xml[Log4j 2]

  • {code-spring-boot}/spring-boot-project/spring-boot/src/main/resources/org/springframework/boot/logging/java/logging-file.properties[Java Util logging]

如果你想在日志记录属性中使用占位符,你应仅使用 Spring Boot’s syntax 而不是底层框架的语法。尤其值得注意的是,如果你使用 Logback,你应使用 : 作为属性名称及其默认值之间的分隔符,而不能使用 :-

你可以通过仅覆盖 LOG_LEVEL_PATTERN (或使用 Logback 覆盖 logging.pattern.level)向日志行添加 MDC 和其他临时的内容。例如,如果你使用 logging.pattern.level=user:%X{user} %5p,则如果存在,默认日志格式将包含“user”的 MDC 条目,如下例所示。

2019-08-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller
Handling authenticated request

Logback Extensions

Spring Boot 包含了多个 Logback 扩展,可以帮助进行高级配置。你可以在 logback-spring.xml 配置文件中使用这些扩展。

因为标准 logback.xml 配置文件加载过早,所以你不能在其中使用扩展。你需要使用 logback-spring.xml 或定义一个 configprop:logging.config[] 属性。

扩展不能与 Logback 的 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]]

Profile-specific Configuration

<springProfile> 标记允许您基于活动 Spring 配置文件任选包含或排除配置部分。可以在 <configuration> 元素中的任何位置支持配置文件部分。使用 name 属性指定接受配置的配置文件。<springProfile> 标记可以包含一个配置文件名(比如 staging)或一个配置文件表达式。一个配置文件表达式允许表达更复杂的配置文件逻辑,比如 production & (eu-central | eu-west))。查看 {url-spring-framework-docs}/core/beans/environment.html#beans-definition-profiles-java[Spring Framework 参考指南] 来获得更多详情。下列清单显示了三个示例配置文件:

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

Environment Properties

<springProperty> 标记允许您公开 Spring Environment 的属性以供 Logback 使用。如果您希望在 Logback 配置中访问 application.properties 文件中的值,这样做非常有用。该标记的工作方式与 Logback 的标准 <property> 标记类似。不过,您不需要指定直接 value,而要指定该属性的 source(来自 Environment)。如果您需要在 local 作用域之外存储某个属性,可以使用 scope 属性。如果您需要一个回退值(以防属性未在 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 中。

Log4j2 Extensions

Spring Boot 包含了许多可以用来提供高级配置的 Log4j2 扩展。您可以在任何 log4j2-spring.xml 配置文件中使用这些扩展。

因为标准的 log4j2.xml 配置文件过早加载,所以您不能在其中使用扩展。您需要使用 log4j2-spring.xml 或者定义一个 configprop:logging.config[] 属性。

这些扩展取代了 Log4J 提供的 Spring Boot support 。您应该确保不将 org.apache.logging.log4j:log4j-spring-boot 模块包含在您的版本中。

Profile-specific Configuration

<SpringProfile> 标记允许您基于活动 Spring 配置文件任选包含或排除配置部分。可以在 <Configuration> 元素中的任何位置支持配置文件部分。使用 name 属性指定接受配置的配置文件。<SpringProfile> 标记可以包含一个配置文件名(比如 staging)或一个配置文件表达式。一个配置文件表达式允许表达更复杂的配置文件逻辑,比如 production & (eu-central | eu-west))。查看 {url-spring-framework-docs}/core/beans/environment.html#beans-definition-profiles-java[Spring Framework 参考指南] 来获得更多详情。下列清单显示了三个示例配置文件:

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

Environment Properties Lookup

如果您希望在 Log4j2 配置中引用 Spring Environment 中的属性,可以使用 spring: 前缀的 lookups 。如果您希望在 Log4j2 配置中访问 application.properties 文件中的值,这样做非常有用。

下列示例展示了如何设置一个名为 applicationName 的 Log4j2 属性,它从 Spring Environment 中读取 spring.application.name

<Properties>
	<Property name="applicationName">${spring:spring.application.name}</Property>
</Properties>

查找键应该以短横线字符形式指定(比如 my.property-name)。

Log4j2 System Properties

Log4j2 支持许多 System Properties ,它们可以用来配置各种项目。例如, log4j2.skipJansi 系统属性可以用来配置 ConsoleAppender 是否将尝试在 Windows 上使用 Jansi 输出流。

可以在 Log4j2 初始化后加载的所有系统属性都可以从 Spring Environment 中获取。例如,您可以将 log4j2.skipJansi=false 添加到您的 application.properties 文件中,以让 ConsoleAppender 在 Windows 上使用 Jansi。

Spring Environment 仅在系统属性和操作系统环境变量中不包含正在加载的值时才被考虑。

在 Log4j2 早期初始化期间加载的系统属性无法引用 Spring Environment 。例如,Log4j2 用于允许选择默认 Log4j2 实现的属性在 Spring Environment 可用之前使用。