7.4.日志记录

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 执行的日志记录不会路由到应用程序的日志中。这可以防止容器或已部署到它的其他应用程序执行的日志记录出现在应用程序的日志中。

7.4.1日志格式

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

2023-06-22T12:08:05.861Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : Starting MyApplication using Java 17.0.7 with PID 22768 (/opt/apps/myapp.jar started by myuser in /opt/apps/)
2023-06-22T12:08:05.872Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : No active profile set, falling back to 1 default profile: "default"
2023-06-22T12:08:09.854Z  INFO 22768 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2023-06-22T12:08:09.892Z  INFO 22768 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2023-06-22T12:08:09.892Z  INFO 22768 --- [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.10]
2023-06-22T12:08:10.160Z  INFO 22768 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2023-06-22T12:08:10.162Z  INFO 22768 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4038 ms
2023-06-22T12:08:11.512Z  INFO 22768 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2023-06-22T12:08:11.534Z  INFO 22768 --- [           main] o.s.b.d.f.s.MyApplication                : Started MyApplication in 7.251 seconds (process running for 8.584)

输出以下内容:

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

  • 日志级别:ERRORWARNINFODEBUGTRACE

  • 进程标识。

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

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

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

  • 日志消息。

Logback 没有FATAL级别。它被映射到ERROR上。

7.4.2. 控制台输出

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

$ java -jar myapp.jar --debug

你也可以在你的application.properties配置debug=true.

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

或者,您可以通过使用--trace标志或在您的application.properties配置trace=true. 这样做可以为选择的核心记录器(嵌入式容器、Hibernate 模式生成和整个 Spring 产品组合)启用跟踪日志记录。

7.4.2.1. 颜色编码输出

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

使用%clr转换字配置颜色编码。在最简单的形式中,转换器根据日志级别为输出着色,如以下示例所示:

%clr(%5p)

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

等级颜色

FATAL

红色的

ERROR

红色的

WARN

黄色

INFO

绿色的

DEBUG

绿色的

TRACE

绿色的

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

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

支持以下颜色和样式:

  • blue

  • cyan

  • faint

  • green

  • magenta

  • red

  • yellow

7.4.3. 文件输出

默认情况下,Spring Boot 仅打印日志到控制台,不写入日志文件。如果您想在控制台输出之外写入日志文件,您需要设置一个logging.file.name或者logging.file.path属性(例如,在您的application.properties中).

下表显示了如何logging.*一起使用这些属性:

logging.file.name

logging.file.path

例子

描述

(无)

(无)

仅控制台日志记录。

具体文件

(无)

my.log

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

(无)

具体目录

/var/log

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

日志文件在达到 10 MB 时会轮换,并且与控制台输出一样,默认情况下会记录ERRORWARNINFO消息。

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

7.4.4. 文件轮换

如果您使用的是 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)。

7.4.5. 日志级别

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

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

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

也可以使用环境变量设置日志记录级别。例如,LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUG将设置org.springframework.webDEBUG。 上述方法仅适用于包级别的日志记录。由于宽松绑定总是将环境变量转换为小写,因此无法以这种方式为单个类配置日志记录。如果需要为类配置日志记录,可以使用SPRING_APPLICATION_JSON变量。

7.4.6. 日志组

能够将相关的记录器组合在一起通常很有用,以便可以同时配置它们。例如,您可能通常会更改所有与 Tomcat 相关的记录器的日志记录级别,但您不容易记住顶级包。

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

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

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

logging.level.tomcat=trace

Spring Boot 包括以下可开箱即用的预定义日志记录组:

名称日志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

7.4.7. 使用日志关闭挂钩

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

logging.register-shutdown-hook=false

7.4.8. 自定义日志配置

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

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

由于在创建ApplicationContext之前 初始化了日志记录,因此无法从Spring@Configuration文件中使用@PropertySources控制日志记录。更改日志系统或完全禁用它的唯一方法是通过系统属性。 根据您的日志记录系统,将加载以下文件:

对应日志框架定制

logback

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

log4j2

log4j2-spring.xml或者log4j2.xml

JDK(Java 实用程序日志记录)

logging.properties

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

Java Util Logging 存在已知的类加载问题,这些问题在从“可执行 jar”运行时会导致问题。如果可能,我们建议您在从“可执行 jar”运行时避免使用它。

为了帮助进行自定义,一些其他属性从 Spring 转移Environment到 System 属性,如下表所述:

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.pattern.file

FILE_LOG_PATTERN

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

logging.charset.file

FILE_LOG_CHARSET

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

logging.pattern.level

LOG_LEVEL_PATTERN

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

PID

PID

当前进程 ID(如果可能且尚未定义为 OS 环境变量时发现)。

如果使用 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,则默认日志格式包含“用户”的 MDC 条目(如果存在),如以下示例所示。

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

7.4.9. 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]]

7.4.9.1. 配置文件特定的配置

<springProfile>标签允许您根据活动的 Spring 配置文件选择性地包含或排除配置部分。<configuration>元素内的任何位置都支持配置文件部分。使用name属性来指定哪个配置文件接受配置。<springProfile>标签可以包含配置文件名称(例如staging)或配置文件表达式。配置文件表达式允许表达更复杂的配置文件逻辑,例如production & (eu-central | eu-west). 查看参考指南以获取更多详细信息。以下清单显示了三个示例配置文件:

<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.4.9.2. 环境属性

<springProperty>标签允许您公开 Spring Environment中的属性以在 Logback 中使用。如果您想在 Logback 配置中访问application.properties文件中的值,这样做会很有用。该标签的工作方式与 Logback 的标准<property>标签类似。但是,您可以指定属性的 source(来自Environment) ,而不是直接指定value。如果您需要将属性存储在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>

必须在 kebab case中指定source(例如my.property-name)。但是,可以使用宽松的规则将属性添加到Environment 中。

7.4.10. 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 框架参考指南以获取更多详细信息。以下清单显示了三个示例配置文件:

<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 初始化后加载的所有系统属性都可以从 SpringEnvironment获取。例如,您可以添加log4j2.skipJansi=falseapplication.properties文件中以便ConsoleAppender在 Windows 上使用 Jansi。

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

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

最后更新于