牛角突围 SpringBoot3.x:日志特性
日志在编码中至关重要,就像开发过程中的“指南针”,帮助开发者追踪程序状态、排查问题和监控系统性能。今天,我们来了解一下 Spring Boot 的日志特性。
Spring Boot 使用通用日志(Commons Logging)来处理内部日志记录,并支持多种底层日志框架,包括 Java Util Logging、Log4j2 和 Logback,且都提供了默认配置。
默认情况下,Spring Boot 使用 Logback 作为日志框架,预设日志记录器将日志输出到控制台,并记录 ERROR、WARN 和 INFO 级别的消息。
快速配置日志
Log Levels - 日志级别
所有支持的日志系统都可以在Spring环境中(例如,在application.properties文件中)通过使用logging.level.<logger-name>=<level>来设置日志级别,其中level可以是TRACE、DEBUG、INFO、WARN、ERROR、FATAL或者OFF。
File Output - 文件输出
默认情况下,Spring Boot 仅向控制台输出日志,而不写入日志文件。如果您希望在控制台输出之外还写入日志文件,则需要设置logging.file.name或logging.file.path属性(例如,在您的application.properties文件中)。如果同时设置了这两个属性,logging.file.path将被忽略,只使用logging.file.name。
Log Pattern 日志输出格式
File Rotation - 日志轮转
在Spring Boot应用中,如果使用Logback作为日志框架,可以通过application.properties或application.yml文件对日志轮转(log rotation)进行微调。对于其他日志系统(例如Log4j2),则需要直接配置相应的设置文件(如log4j2.xml或log4j2-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)。
Log Groups - 日志分组
你可以在 application.properties 或 application.yml 中定义自己的日志分组。例如:
logging:
group:
tomcat: org.apache.catalina,org.apache.coyote,org.apache.tomcat
定义分组后,可以通过一个统一配置设置该组内所有 logger 的日志级别:
logging:
level:
tomcat: trace
Spring Boot 还内置了以下预定义分组,可直接使用:
日志分组能统一管理相关日志器,提升配置的一致性和维护效率。
Custom Log Configuration - 自定义日志配置
通过在类路径中包含适当的库,可以激活各种日志系统。还可以通过在类路径的根目录下,或者在由以下 Spring 环境属性指定的位置提供一个合适的配置文件来进一步自定义日志系统:logging.config。
也可以通过使用
org.springframework.boot.logging.LoggingSystem 系统属性来强制 Spring Boot 使用特定的日志系统,该属性的值应该是 LoggingSystem 实现类的全限定类名。
由于日志系统在 ApplicationContext 创建之前就已初始化,因此无法通过 Spring @Configuration 文件中的 @PropertySources 来控制日志。更改日志系统或完全禁用日志系统的唯一方法是使用系统属性。
根据不同的日志系统,会加载以下文件:
Spring Boot 对 Logback 和 Log4j2 进行了扩展,支持使用 profile 和 Environment Properties 配置。推荐使用 logback-spring.xml 或 log4j2-spring.xml 进行配置。
Logback 示例配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOGS" value="./logs" />
<!-- 从 Spring 配置中获取应用程序名称,并将其设置为 application.name 属性 -->
<springProperty name="application.name" source="spring.application.name" />
<!-- 开发环境配置 -->
<springProfile name="development">
<!-- 控制台输出日志 -->
<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<!-- 设置日志输出格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</layout>
</appender>
<!-- 设置日志级别为 info,并将日志输出到控制台 -->
<root level="info">
<appender-ref ref="Console" />
</root>
</springProfile>
<springProfile name="production">
<appender name="RollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOGS}/%{application.name}.log</file>
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</Pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOGS}/archived/${application.name}-%d{yyyy-MM-dd}.log</fileNamePattern>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="RollingFile" />
</root>
</springProfile>
</configuration>
使用log4j2
- 排除 Logback 依赖:
- 添加 Log4j2 相关依赖:
- Log4j2 示例配置
<?xml version="1.0" encoding="UTF-8"?>
<configuration status="WARN">
<!-- 日志文件目录 -->
<Properties>
<Property name="LOGS">./logs</Property>
<Property name="applicationName">${spring:spring.application.name}</Property>
</Properties>
<Appenders>
<!-- 控制台输出 -->
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<!-- 文件输出 -->
<RollingFile name="FileAppender"
fileName="${LOGS}/${applicationName}.log"
filePattern="${LOGS}/${applicationName}-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="10MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- 开发环境 -->
<SpringProfile name="development,default">
<Root level="info">
<AppenderRef ref="Console" />
</Root>
<Logger name="org.niujiao" level="debug" additivity="false">
<AppenderRef ref="Console" />
</Logger>
</SpringProfile>
<!-- 生产环境 -->
<SpringProfile name="production">
<Root level="error">
<AppenderRef ref="Console" />
<AppenderRef ref="FileAppender" />
</Root>
<Logger name="org.niujiao" level="info" additivity="false">
<AppenderRef ref="FileAppender" />
</Logger>
</SpringProfile>
</Loggers>
</configuration>
控制台颜色编码输出配置
Spring Boot 支持在控制台输出中使用颜色编码,以提高日志可读性。
如果你的终端支持 ANSI,Spring Boot 默认会启用颜色输出。你也可以通过设置
spring.output.ansi.enabled 属性来手动启用或禁用颜色输出。
application.yaml
spring:
output:
ansi:
enabled: ALWAYS
可选值
- ALWAYS: 总是启用颜色输出。
- NEVER: 禁用颜色输出。
- DETECT: 根据终端是否支持 ANSI 自动检测(默认值)。
Structured Logging - 日志结构化
结构化日志是一种将日志信息以预定义、易于机器解析的格式输出的技术。Spring Boot 支持结构化日志,并内置支持以下格式:
- Elastic Common Schema (ECS):Elasticsearch 使用的标准日志格式。
- Graylog Extended Log Format (GELF):Graylog 日志管理系统使用的格式。
- Logstash:Logstash 日志收集器使用的格式。
启用结构化日志
要启用结构化日志,可以通过以下属性配置控制台或文件输出的格式:
- 控制台输出:logging.structured.format.console 设置为所需格式的 ID。
- 文件输出:logging.structured.format.file 设置为所需格式的 ID。
示例配置:
logging.structured.format.console=ecs
logging.structured.format.file=gelf
通过结构化日志,日志变得更加一致,易于解析,并能无缝集成到现代的日志和监控系统中。
如果你觉得这篇文章对你有启发,欢迎点赞、收藏、转发
如文中有理解不当或疏漏之处,也欢迎留言指正,共同进步 ,持续分享更多 Spring 源码剖析、实战技巧与架构实践,欢迎关注!