日志记录

Spring Boot 使用 Commons Logging 进行所有内部日志记录,但将底层日志实现保持开放。默认配置适用于 Java Util LoggingLog4j2Logback。在每种情况下,记录器都预先配置为使用控制台输出,并提供可选的文件输出。

默认情况下,如果您使用“Starters”,Logback 将用于日志记录。还包含适当的 Logback 路由以确保使用 Java Util Logging、Commons Logging、Log4J 或 SLF4J 的依赖库都能正常工作。

Java 有很多可用的日志框架。如果上面的列表看起来很混乱,请不要担心。通常,您不需要更改日志记录依赖项,Spring Boot 默认设置就可以正常工作。
当您将应用程序部署到 servlet 容器或应用程序服务器时,使用 Java Util Logging API 执行的日志记录不会路由到应用程序的日志中。这可以防止容器或已部署到其中的其他应用程序执行的日志记录出现在应用程序的日志中。

日志格式

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

2024-05-23T12:38:13.986Z  INFO 110098 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : Starting MyApplication using Java 17.0.11 with PID 110098 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2024-05-23T12:38:14.008Z  INFO 110098 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : No active profile set, falling back to 1 default profile: "default"
2024-05-23T12:38:18.678Z  INFO 110098 --- [myapp] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8080 (http)
2024-05-23T12:38:18.740Z  INFO 110098 --- [myapp] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-05-23T12:38:18.741Z  INFO 110098 --- [myapp] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.24]
2024-05-23T12:38:18.875Z  INFO 110098 --- [myapp] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-05-23T12:38:18.879Z  INFO 110098 --- [myapp] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4494 ms
2024-05-23T12:38:19.741Z  INFO 110098 --- [myapp] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8080 (http) with context path '/'
2024-05-23T12:38:19.804Z  INFO 110098 --- [myapp] [           main] o.s.b.d.f.logexample.MyApplication       : Started MyApplication in 7.527 seconds (process running for 8.82)

输出以下项目

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

  • 日志级别:ERRORWARNINFODEBUGTRACE

  • 进程 ID。

  • --- 分隔符,用于区分实际日志消息的开始。

  • 应用程序名称:用方括号括起来(默认情况下仅在设置了 spring.application.name 时才记录)

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

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

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

  • 日志消息。

Logback 没有 FATAL 级别。它映射到 ERROR
如果您有 spring.application.name 属性,但不想记录它,可以将 logging.include-application-name 设置为 false

控制台输出

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

$ java -jar myapp.jar --debug
您也可以在 application.properties 中指定 debug=true

启用调试模式时,会配置一些核心记录器(嵌入式容器、Hibernate 和 Spring Boot)以输出更多信息。启用调试模式不会将您的应用程序配置为以 DEBUG 级别记录所有消息。

或者,您可以通过在启动应用程序时使用 `--trace` 标志(或在 `application.properties` 中使用 `trace=true`)来启用“跟踪”模式。这样做会为选定的核心日志记录器(嵌入式容器、Hibernate 模式生成和整个 Spring 框架)启用跟踪日志记录。

彩色输出

如果您的终端支持 ANSI,则会使用彩色输出以提高可读性。您可以将 `spring.output.ansi.enabled` 设置为 支持的值 来覆盖自动检测。

颜色编码是通过使用 `%clr` 转换词来配置的。在最简单的形式中,转换器会根据日志级别对输出进行着色,如下例所示

%clr(%5p)

下表描述了日志级别到颜色的映射

级别 颜色

FATAL

红色

ERROR

红色

WARN

黄色

INFO

绿色

DEBUG

绿色

TRACE

绿色

或者,您可以通过将其作为转换选项提供来指定要使用的颜色或样式。例如,要使文本变为黄色,请使用以下设置

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

支持以下颜色和样式

  • 蓝色

  • 青色

  • 浅色

  • 绿色

  • 洋红色

  • 红色

  • 黄色

文件输出

默认情况下,Spring Boot 仅将日志记录到控制台,而不写入日志文件。如果您希望除了控制台输出之外还写入日志文件,则需要设置 `logging.file.name` 或 `logging.file.path` 属性(例如,在您的 `application.properties` 中)。

下表显示了如何将 `logging.*` 属性组合使用

表 1. 日志记录属性
logging.file.name logging.file.path 示例 描述

(无)

(无)

仅控制台日志记录。

特定文件

(无)

my.log

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

(无)

特定目录

/var/log

将 `spring.log` 写入指定的目录。名称可以是确切位置或相对于当前目录的相对位置。

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

日志记录属性独立于实际的日志记录基础设施。因此,Spring Boot 不会管理特定配置键(例如,Logback 的 `logback.configurationFile`)。

文件轮转

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

支持以下轮转策略属性

名称 描述

logging.logback.rollingpolicy.file-name-pattern

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

logging.logback.rollingpolicy.clean-history-on-start

应用程序启动时是否应进行日志存档清理。

logging.logback.rollingpolicy.max-file-size

日志文件在存档之前的最大大小。

logging.logback.rollingpolicy.total-size-cap

日志存档在被删除之前可以占用的最大大小。

logging.logback.rollingpolicy.max-history

要保留的存档日志文件的最大数量(默认为 7)。

日志级别

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

以下示例显示了 application.properties 中可能的日志设置

  • 属性

  • YAML

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

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

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

日志组

通常,能够将相关的日志记录器分组在一起以便可以同时配置它们非常有用。例如,您可能经常更改所有 Tomcat 相关日志记录器的日志级别,但您可能无法轻松记住顶级包。

为了帮助解决这个问题,Spring Boot 允许您在 Spring Environment 中定义日志组。例如,您可以通过将以下内容添加到您的 application.properties 中来定义一个名为“tomcat”的组。

  • 属性

  • YAML

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

定义完成后,您可以使用一行代码更改组中所有记录器的级别。

  • 属性

  • YAML

logging.level.tomcat=trace
logging:
  level:
    tomcat: "trace"

Spring Boot 包含以下预定义的日志组,可以直接使用。

名称 记录器

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

使用日志关闭钩子

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

  • 属性

  • YAML

logging.register-shutdown-hook=false
logging:
  register-shutdown-hook: false

自定义日志配置

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

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

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

根据您的日志系统,将加载以下文件

日志系统 自定义

Logback

logback-spring.xmllogback-spring.groovylogback.xmllogback.groovy

Log4j2

log4j2-spring.xmllog4j2.xml

JDK(Java Util Logging)

logging.properties

如果可能,我们建议您使用日志配置的-spring变体(例如,logback-spring.xml而不是logback.xml)。如果您使用标准配置位置,Spring 无法完全控制日志初始化。
Java Util Logging 存在已知的类加载问题,这些问题会导致从“可执行 jar”运行时出现问题。我们建议您在从“可执行 jar”运行时尽可能避免使用它。

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

Spring 环境 系统属性 注释

logging.exception-conversion-word

LOG_EXCEPTION_CONVERSION_WORD

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

logging.file.name

LOG_FILE

如果定义,它将用于默认日志配置。

logging.file.path

LOG_PATH

如果定义,它将用于默认日志配置。

logging.pattern.console

CONSOLE_LOG_PATTERN

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

logging.pattern.dateformat

LOG_DATEFORMAT_PATTERN

日志日期格式的附加器模式。

logging.charset.console

CONSOLE_LOG_CHARSET

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

logging.threshold.console

CONSOLE_LOG_THRESHOLD

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

logging.pattern.file

FILE_LOG_PATTERN

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

logging.charset.file

FILE_LOG_CHARSET

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

logging.threshold.file

FILE_LOG_THRESHOLD

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

logging.pattern.level

LOG_LEVEL_PATTERN

渲染日志级别时使用的格式(默认值为 %5p)。

PID

PID

当前进程 ID(如果可能,则在未定义为操作系统环境变量时发现)。

如果您使用 Logback,则还会传递以下属性

Spring 环境 系统属性 注释

logging.logback.rollingpolicy.file-name-pattern

LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN

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

logging.logback.rollingpolicy.clean-history-on-start

LOGBACK_ROLLINGPOLICY_CLEAN_HISTORY_ON_START

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

logging.logback.rollingpolicy.max-file-size

LOGBACK_ROLLINGPOLICY_MAX_FILE_SIZE

最大日志文件大小。

logging.logback.rollingpolicy.total-size-cap

LOGBACK_ROLLINGPOLICY_TOTAL_SIZE_CAP

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

logging.logback.rollingpolicy.max-history

LOGBACK_ROLLINGPOLICY_MAX_HISTORY

要保留的归档日志文件的最大数量。

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

如果您想在日志记录属性中使用占位符,则应使用 Spring Boot 的语法,而不是底层框架的语法。值得注意的是,如果您使用 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 扩展

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

由于标准的 logback.xml 配置文件加载得太早,因此您无法在其中使用扩展。您需要使用 logback-spring.xml 或定义 logging.config 属性。
扩展不能与 Logback 的 配置扫描 一起使用。如果您尝试这样做,对配置文件进行更改会导致类似于以下内容的错误被记录
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]]

特定于配置文件的配置

<springProfile> 标签允许您根据活动的 Spring 配置文件有选择地包含或排除配置部分。配置文件部分支持在 <configuration> 元素中的任何位置使用。使用 name 属性指定接受配置的配置文件。<springProfile> 标签可以包含配置文件名称(例如 staging)或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑,例如 production & (eu-central | eu-west)。有关更多详细信息,请查看 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>

环境属性

<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 必须以 kebab 形式指定(例如 my.property-name)。但是,可以使用宽松规则将属性添加到 Environment 中。

Log4j2 扩展

Spring Boot 包含许多 Log4j2 扩展,可以帮助您进行高级配置。您可以在任何 log4j2-spring.xml 配置文件中使用这些扩展。

由于标准的 log4j2.xml 配置文件加载过早,因此您无法在其中使用扩展。您需要使用 log4j2-spring.xml 或定义 logging.config 属性。
这些扩展取代了 Log4J 提供的 Spring Boot 支持。您应该确保不要在您的构建中包含 org.apache.logging.log4j:log4j-spring-boot 模块。

特定于配置文件的配置

<SpringProfile> 标签允许您根据活动的 Spring 配置文件有选择地包含或排除配置部分。配置文件部分支持在 <Configuration> 元素中的任何位置使用。使用 name 属性指定哪个配置文件接受配置。<SpringProfile> 标签可以包含配置文件名称(例如 staging)或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑,例如 production & (eu-central | eu-west)。有关更多详细信息,请查看 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>

环境属性查找

如果您想在 Log4j2 配置中引用来自 Spring Environment 的属性,可以使用以 spring: 为前缀的 查找。如果您想在 Log4j2 配置中访问 application.properties 文件中的值,这样做会很有用。

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

<Properties>
	<Property name="applicationName">${spring:spring.application.name}</Property>
</Properties>
查找键应以连字符分隔的格式指定(例如 my.property-name)。

Log4j2 系统属性

Log4j2 支持许多 系统属性,可用于配置各种项目。例如,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 可用之前使用的。