20220516 Core Features - 4. Logging

前言

文档地址

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

4.1. 日志格式

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

2019-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2019-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2019-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

输出以下项目:

  • 日期和时间:毫秒精度,易于排序
  • 日志级别:ERRORWARNINFODEBUGTRACE
  • 进程 ID
  • 用于区分实际日志消息开始的分隔符 ---
  • 线程名称:括在方括号中(可能会被截断以用于控制台输出)
  • 记录器名称:这通常是源类名称(通常缩写)
  • 日志消息

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

4.2. 控制台输出

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

你也可以在 application.properties 中指定 debug=true

颜色编码输出

如果您的终端支持 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 - 黄色

4.3. 文件输出

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

日志记录属性:

logging.file.name logging.file.path 示例 描述
(没有) (没有) 仅控制台记录。
特定文件 (没有) my.log 写入指定的日志文件。名称可以是确切位置,也可以是相对于当前目录的位置
(没有) 具体目录 /var/log 写入指定目录下的 spring.log 。名称可以是确切位置,也可以是相对于当前目录的位置

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

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

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 )

4.5. 日志级别

所有支持的日志系统可以在 Spring Environment 设置日志级别(例如,通过 application.properties ),通过使用 logging.level.<logger-name>=<level> ,其中 levelTRACEDEBUGINFOWARNERRORFATALOFF 之一。root Logger 可以通过使用 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 变量

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

4.7. 使用日志关闭挂钩

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

logging.register-shutdown-hook=false

4.8. 自定义日志配置

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

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

-Dorg.springframework.boot.logging.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 Util Logging) logging.properties

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

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

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

Spring Environment System Property 备注
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 记录日期格式的 Appender 模式
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 Environment System Property 备注
logging.logback.rollingpolicy.file-name-pattern LOGBACK_ROLLINGPOLICY_FILE_NAME_PATTERN 翻转日志文件名的模式(默认 ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz
logging.file.clean-history-on-start LOG_FILE_CLEAN_HISTORY_ON_START 是否在启动时清除存档日志文件
logging.file.max-size LOG_FILE_MAX_SIZE 最大日志文件大小
logging.file.total-size-cap LOG_FILE_TOTAL_SIZE_CAP 要保留的日志备份的总大小
logging.file.max-history LOG_FILE_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

参考:在SpringBoot项目中添加logback的MDC

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

4.9.1. 特定于 profile 的配置

使用 <springProfile> 标签,您可以根据激活的 Spring Profiles 选择包括或排除配置部分。 profile 部分在 <configuration> 标签内的任何位置都受支持。使用 name 属性指定哪个 profile 接受配置。<springProfile> 标签可包含一个简单的 profile 的名称(例如staging)或 profile 表达式。profile 表达式允许表达更复杂的 profile 逻辑,例如 production & (eu-central | eu-west )。有关更多详细信息,请参阅参考指南。以下清单显示了三个示例 profile :

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

4.9.2. Environment 属性

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

参考:Spring Boot 日志原理

参考源码:使用 org.springframework.boot.context.logging.LoggingApplicationListener 监听器监听多个事件:

ApplicationStartingEvent.class,
ApplicationEnvironmentPreparedEvent.class, 
ApplicationPreparedEvent.class, 
ContextClosedEvent.class,
ApplicationFailedEvent.class

在触发 ApplicationStartingEvent 事件时,初始化日志系统,参考 org.springframework.boot.logging.LoggingSystem#get(java.lang.ClassLoader)

posted @ 2022-06-08 07:50  流星<。)#)))≦  阅读(30)  评论(0编辑  收藏  举报