在 Spring Boot 3.5.3 中,要將默認的 Logback 替換為 Log4j2,需要以下步驟:
1. 添加 Log4j2 依賴
在?pom.xml
中排除默認的 Logback 依賴并添加 Log4j2 依賴:
<dependencies><!-- 排除默認的 Logback --><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 Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-log4j2</artifactId></dependency><!-- 可選:日志配置刷新支持 --><dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-liquibase</artifactId></dependency>
</dependencies>
2. 創建 Log4j2 配置文件
在?src/main/resources
目錄下創建?log4j2.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30"><Appenders><!-- 控制臺輸出 --><Console name="Console" target="SYSTEM_OUT"><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/></Console><!-- 文件輸出 --><RollingFile name="File" fileName="logs/application.log"filePattern="logs/application-%d{yyyy-MM-dd}-%i.log"><PatternLayout><Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern></PatternLayout><Policies><!-- 每天滾動 --><TimeBasedTriggeringPolicy /><!-- 文件大小達到100MB時滾動 --><SizeBasedTriggeringPolicy size="100 MB"/></Policies><!-- 保留最近7天的日志 --><DefaultRolloverStrategy max="7"/></RollingFile><!-- 異步日志配置 --><Async name="Async" bufferSize="262144"><AppenderRef ref="File"/></Async></Appenders><Loggers><!-- Spring Boot 核心日志 --><Logger name="org.springframework" level="INFO"/><Logger name="org.apache" level="WARN"/><!-- Hibernate 日志 --><Logger name="org.hibernate.SQL" level="DEBUG" additivity="false"><AppenderRef ref="Console"/></Logger><Logger name="org.hibernate.type.descriptor.sql" level="TRACE" additivity="false"><AppenderRef ref="Console"/></Logger><!-- 自定義包日志級別 --><Logger name="com.myapp" level="DEBUG"/><!-- Root 日志設置 --><Root level="INFO"><AppenderRef ref="Console"/><AppenderRef ref="Async"/> <!-- 使用異步文件輸出 --></Root></Loggers>
</Configuration>
3. 添加 application.yml 配置
在?application.yml
中添加 Log4j2 相關配置:
spring:application:name: my-applicationlogging:config: classpath:log4j2.xmllevel:root: infoorg.springframework.web: debugcom.myapp.service: trace# 啟用日志配置熱更新log4j2:watch: trueshutdown-hook: disableshutdown-timeout: 30
4. 添加日志工具類
創建日志工具類以簡化使用:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;public class LogUtil {private LogUtil() {}public static Logger getLogger() {// 獲取調用此方法的上層類名return LogManager.getLogger(Thread.currentThread().getStackTrace()[2].getClassName());}// 方法入參日志(使用MDC添加上下文信息)public static void logMethodEntry(Object... params) {Logger logger = getLogger();if(logger.isTraceEnabled()) {String methodName = Thread.currentThread().getStackTrace()[2].getMethodName();logger.trace("Entering: {} with params: {}", methodName, params);}}
}
5. 高級功能配置
5.1 日志脫敏配置
添加敏感信息脫敏配置類:
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.pattern.ConverterKeys;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;@Plugin(name = "SafeConverter", category = "Converter")
@ConverterKeys({"safe"})
public class SafeConverter extends LogEventPatternConverter {// 敏感信息正則匹配private static final String SENSITIVE_PATTERN = "\\b(?:password|passwd|pwd|secret|token|key|card|ccn|phone|tel|id)\\b[^=]*=\\s*['\"]?([^'\",\\s]+)";protected SafeConverter() {super("safe", "safe");}public static SafeConverter newInstance(String[] options) {return new SafeConverter();}@Overridepublic void format(LogEvent event, StringBuilder toAppendTo) {String message = event.getMessage().getFormattedMessage();toAppendTo.append(message.replaceAll(SENSITIVE_PATTERN, "$1=***"));}
}
在?log4j2.xml
中使用:
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %safe{%msg}%n"/>
5.2 日志指標監控
添加 Log4j2 指標采集:
import io.micrometer.core.instrument.MeterRegistry;
import org.apache.logging.log4j.LogManager;
import org.springframework.context.annotation.Configuration;import javax.annotation.PostConstruct;@Configuration
public class LogMetricsConfig {private final MeterRegistry meterRegistry;public LogMetricsConfig(MeterRegistry meterRegistry) {this.meterRegistry = meterRegistry;}@PostConstructpublic void init() {// 采集ERROR級別的日志計數meterRegistry.gauge("log.error.count", LogManager.getRootLogger(), logger -> logger instanceof org.apache.logging.log4j.core.Logger ? ((org.apache.logging.log4j.core.Logger) logger).getCount().get() : 0);}
}
5.3 日志集中式管理
添加 Logstash 或 ELK 支持:
<!-- pom.xml 添加依賴 -->
<dependency><groupId>net.logstash.logback</groupId><artifactId>logstash-logback-encoder</artifactId><version>7.3</version>
</dependency>
配置 Logstash Appender:
<Appenders><!-- Logstash TCP 輸出 --><LogstashTcpSocket name="Logstash" host="logstash.mycompany.com" port="5000"><JsonLayout compact="true" eventEol="true"><KeyValuePair key="appName" value="${spring:spring.application.name}"/><KeyValuePair key="environment" value="${spring:spring.profiles.active}"/></JsonLayout></LogstashTcpSocket>
</Appenders><Loggers><Root level="INFO"><AppenderRef ref="Logstash"/></Root>
</Loggers>
6. Spring Boot 配置類
添加日志相關的配置管理:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.springframework.boot.context.event.ApplicationStartedEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;import java.net.URI;@Configuration
public class LogConfig {/*** 應用啟動后重新加載日志配置*/@EventListener(ApplicationStartedEvent.class)public void reloadLogConfig() {LoggerContext context = (LoggerContext) LogManager.getContext(false);context.setConfigLocation(URI.create("classpath:log4j2.xml"));context.reconfigure();}
}
7. 日志性能優化
7.1 異步日志配置優化
<!-- log4j2.xml -->
<AsyncLogger name="com.myapp" level="debug" additivity="false"><AppenderRef ref="Console"/><AppenderRef ref="File"/><!-- 隊列大小 --><AsyncQueueSize>262144</AsyncQueueSize><!-- 等待策略 --><AsyncWaitStrategy type="Block"/>
</AsyncLogger>
7.2 日志開關控制器
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.LoggerContext;
import org.apache.logging.log4j.core.config.Configurator;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogController {@GetMapping("/log/level")public String changeLogLevel(String logger, String level) {LoggerContext context = (LoggerContext) LogManager.getContext(false);// 設置特定日志級別if ("root".equalsIgnoreCase(logger)) {Configurator.setRootLevel(Level.valueOf(level));} else {Configurator.setLevel(logger, Level.valueOf(level));}context.reconfigure();return "Log level updated: " + logger + " -> " + level;}
}
8. 驗證日志配置
創建測試控制器驗證日志輸出:
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class LogTestController {private static final Logger logger = LogManager.getLogger(LogTestController.class);@GetMapping("/test/log")public String testLog() {logger.trace("This is a TRACE message");logger.debug("This is a DEBUG message");logger.info("This is an INFO message");logger.warn("This is a WARN message");logger.error("This is an ERROR message");return "Log messages generated!";}
}
訪問?http://localhost:8080/test/log
后,檢查控制臺和日志文件驗證輸出。
配置總結
功能 | 配置位置 | 說明 |
---|---|---|
基礎配置 | log4j2.xml | 定義日志格式、輸出目的地等 |
級別控制 | application.yml | 設置不同包的日志級別 |
熱更新 | logging.log4j2.watch | 配置自動檢測配置變化 |
異步日志 | Async Appender | 提高日志性能 |
日志脫敏 | SafeConverter | 保護敏感信息 |
日志監控 | Micrometer | 采集日志指標 |
遠程日志 | LogstashTcpSocket | 集成ELK棧 |
此配置提供了:
靈活的日志級別控制
高性能的異步日志處理
敏感信息保護
監控和管理功能