Spring Boot 中 Log4j2 日志配置指南
介绍如何在 Spring Boot 项目中配置 Log4j2。步骤包括排除默认 Logback 依赖、引入 Log4j2 与 Disruptor 依赖、配置 application.yml 加载自定义 XML,以及编写包含控制台、文件滚动、异步日志及错误分级的 log4j2.xml 配置。该方案支持动态更新、分布式追踪 ID 及日志自动清理,适用于高并发企业级应用。

介绍如何在 Spring Boot 项目中配置 Log4j2。步骤包括排除默认 Logback 依赖、引入 Log4j2 与 Disruptor 依赖、配置 application.yml 加载自定义 XML,以及编写包含控制台、文件滚动、异步日志及错误分级的 log4j2.xml 配置。该方案支持动态更新、分布式追踪 ID 及日志自动清理,适用于高并发企业级应用。

在现代企业级应用开发中,日志管理是系统运维和问题排查的重要组成部分。本文将详细介绍如何在 Spring Boot 项目中配置 Log4j2,包括完整的 log4j2.xml 配置文件和相关依赖设置。
Spring Boot 默认使用 Logback 作为日志框架,但在某些场景下我们更倾向于使用 Log4j2:
首先需要排除 Spring Boot 默认的 Logback 依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
然后添加 Log4j2 相关依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- 高性能异步日志库 -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.4</version>
</dependency>
在 application.yml 文件中指定日志配置文件:
logging:
config: classpath:log4j2.xml
这样配置可以让 Spring Boot 加载自定义的 Log4j2 配置文件。
<Properties>
<property name="LOG_HOME" value="./logs"/>
<property name="APP_CODE" value="file_log"/>
<property name="LOG_LEVEL_PATTERN" value="%-5p"/>
<property name="INSTANCE_INFO_PATTERN" value="${hostName} | ${sys:user.name}"/>
<property name="CODE_INFO_PATTERN" value="%pid:%F:%L"/>
<property name="LOG_DATEFORMAT_PATTERN" value="yyyy-MM-dd HH:mm:ss.SSS"/>
<property name="APP_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %X{TRACE_ID} | %t | ${CODE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
<property name="LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | %X{TRACE_ID} | ${LOG_LEVEL_PATTERN} | ${INSTANCE_INFO_PATTERN} | FEIA | FLEP-INAPP | %t | ${CODE_INFO_PATTERN} | %m%n"/>
<property name="ALERT_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} $${ctx:traceId:-} | ${INSTANCE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
</Properties>
这里定义了日志系统的各种属性,包括日志存储路径、日志级别格式、实例信息格式等。
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %t | %c:%L | [%X{seq}] - %m%n"/>
</Console>
Log4j2 支持多种滚动策略,以下是一些常用配置:
事件日志配置:
<RollingFile name="EventLogFile" fileName="${LOG_HOME}/event.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/event.log.%i">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/event.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
应用日志配置:
<RollingFile name="AppLogFile" fileName="${LOG_HOME}/app.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/app.log.%i">
<PatternLayout>
<Pattern>${APP_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/app.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
告警日志配置:
<RollingFile name="AlertLogFile" fileName="${LOG_HOME}/alert.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/alert.log.%i">
<thresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${ALERT_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/alert.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
错误日志配置:
<RollingFile name="ErrorLogFile" fileName="${LOG_HOME}/error.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/error.log.%i">
<thresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${APP_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/error.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="AppLogFile"/>
<AppenderRef ref="AlertLogFile"/>
<AppenderRef ref="ErrorLogFile"/>
</Root>
<AsyncLogger name="event" level="ALL" additivity="false">
<AppenderRef ref="EventLogFile"/>
</AsyncLogger>
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<logger name="com.cisdi.colmet.core.mapper" level="DEBUG"/>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="600">
<Properties>
<property name="LOG_HOME" value="./logs"/>
<property name="APP_CODE" value="file_log"/>
<property name="LOG_LEVEL_PATTERN" value="%-5p"/>
<property name="INSTANCE_INFO_PATTERN" value="${hostName} | ${sys:user.name}"/>
<property name="CODE_INFO_PATTERN" value="%pid:%F:%L"/>
<property name="LOG_DATEFORMAT_PATTERN" value="yyyy-MM-dd HH:mm:ss.SSS"/>
<property name="APP_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %X{TRACE_ID} | %t | ${CODE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
<property name="LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} | %X{TRACE_ID} | ${LOG_LEVEL_PATTERN} | ${INSTANCE_INFO_PATTERN} | FEIA | FLEP-INAPP | %t | ${CODE_INFO_PATTERN} | %m%n"/>
<property name="ALERT_LOG_PATTERN" value="%d{${LOG_DATEFORMAT_PATTERN}} $${ctx:traceId:-} | ${INSTANCE_INFO_PATTERN} | [%X{seq}] - %m%n"/>
</Properties>
<Appenders>
<Console name="Console" target="SYSTEM_OUT" follow="true">
<PatternLayout pattern="%d{${LOG_DATEFORMAT_PATTERN}} | ${LOG_LEVEL_PATTERN} | %t | %c:%L | [%X{seq}] - %m%n"/>
</Console>
<RollingFile name="EventLogFile" fileName="${LOG_HOME}/event.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/event.log.%i">
<PatternLayout>
<Pattern>${LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/event.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="AppLogFile" fileName="${LOG_HOME}/app.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/app.log.%i">
<PatternLayout>
<Pattern>${APP_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/app.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="AlertLogFile" fileName="${LOG_HOME}/alert.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/alert.log.%i">
<thresholdFilter level="warn" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${ALERT_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/alert.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
<RollingFile name="ErrorLogFile" fileName="${LOG_HOME}/error.log" immediateFlush="true" filePattern="${LOG_HOME}/%d{yyyyMMdd}/error.log.%i">
<thresholdFilter level="error" onMatch="ACCEPT" onMismatch="DENY"/>
<PatternLayout>
<Pattern>${APP_LOG_PATTERN}</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
<SizeBasedTriggeringPolicy size="50MB"/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${LOG_HOME}" maxDepth="2">
<IfFileName glob="*/error.log.*"/>
<IfLastModified age="30d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="AppLogFile"/>
<AppenderRef ref="AlertLogFile"/>
<AppenderRef ref="ErrorLogFile"/>
</Root>
<AsyncLogger name="event" level="ALL" additivity="false">
<AppenderRef ref="EventLogFile"/>
</AsyncLogger>
<logger name="com.apache.ibatis" level="TRACE"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<logger name="com.cisdi.colmet.core.mapper" level="DEBUG"/>
</Loggers>
</Configuration>
通过以上配置,我们可以构建一个功能完善、性能优异的 Log4j2 日志系统。这种配置不仅满足了日常开发和运维需求,还提供了高性能的异步日志记录能力。在实际项目中,可以根据具体需求调整日志级别、输出格式和文件策略,以达到最佳的监控和维护效果。
良好的日志配置是系统稳定运行和快速排错的重要保障,合理的日志管理策略能够显著提升系统的可维护性和可观测性。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
查找任何按下的键的javascript键代码、代码、位置和修饰符。 在线工具,Keycode 信息在线工具,online
JavaScript 字符串转义/反转义;Java 风格 \uXXXX(Native2Ascii)编码与解码。 在线工具,Escape 与 Native 编解码在线工具,online
使用 Prettier 在浏览器内格式化 JavaScript 或 HTML 片段。 在线工具,JavaScript / HTML 格式化在线工具,online
Terser 压缩、变量名混淆,或 javascript-obfuscator 高强度混淆(体积会增大)。 在线工具,JavaScript 压缩与混淆在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online