SpringBoot項(xiàng)目使用Log4j2+SLF4J構(gòu)建日志的方法步驟
1、添加項(xiàng)目依賴
確保的pom.xml中包含Spring Boot Starter Log4j2的依賴,同時(shí)排除默認(rèn)的Logback
<dependencies>
<!-- Spring Boot Log4j2 Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除掉默認(rèn)的 logback 依賴 -->
<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-log4j2</artifactId>
</dependency>
</dependencies>2、創(chuàng)建TraceId過濾器
這個(gè)Filter負(fù)責(zé)在請求開始時(shí)生成TraceId并放入上下文,在請求結(jié)束后清理
import org.apache.logging.log4j.ThreadContext;
import org.springframework.stereotype.Component;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
@Component
public class TraceIdFilter implements Filter {
// 你可以自定義請求頭中TraceId的名字
private static final String TRACE_ID_HEADER = "X-Trace-Id";
// 這是TraceId在Log4j2 ThreadContext中存儲的key
private static final String TRACE_ID_KEY = "traceId";
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
// 嘗試從請求頭中獲取TraceId,如果沒有則生成一個(gè)
String traceId = httpRequest.getHeader(TRACE_ID_HEADER);
if (traceId == null || traceId.isEmpty()) {
// 生成唯一ID,這里使用UUID,你可以根據(jù)需要調(diào)整
traceId = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
// 將TraceId放入Log4j2的ThreadContext,這樣日志就能自動(dòng)打印了
ThreadContext.put(TRACE_ID_KEY, traceId);
// 可選:將TraceId設(shè)置到響應(yīng)頭,方便前端或下游服務(wù)追蹤
httpResponse.setHeader(TRACE_ID_HEADER, traceId);
try {
chain.doFilter(request, response); // 繼續(xù)執(zhí)行請求鏈
} finally {
// 請求處理完畢,務(wù)必清理ThreadContext,避免內(nèi)存泄漏和數(shù)據(jù)污染
ThreadContext.remove(TRACE_ID_KEY);
}
}
}3、配置Log4j2以輸出TraceId
修改src/main/resources/log4j2.xml配置文件,在日志輸出模式(Pattern)中加入TraceId
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- 控制臺輸出配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 設(shè)置日志輸出格式 -->
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level [%X{traceId}] %logger{36} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console" />
</Root>
</Loggers>
</Configuration>關(guān)鍵說明:
格式中的
%X{traceId}就是一個(gè)占位符,它會自動(dòng)從Log4j2的ThreadContext中讀取key為"traceId"的值 。如果不存在,則該處輸出為空。
4、在代碼中記錄日志
現(xiàn)在可以在代碼中正常使用SLF4J記錄日志,TraceId會自動(dòng)出現(xiàn)在日志中。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
private static final Logger logger = LoggerFactory.getLogger(DemoController.class);
@GetMapping("/test")
public String testEndpoint() {
logger.info("收到請求"); // 日志會自動(dòng)包含traceId
// ... 你的業(yè)務(wù)邏輯
return "請求完成";
}
}5、日志掛載位置
在Spring Boot項(xiàng)目中,設(shè)置日志的掛載位置主要有兩種思路:一種是通過應(yīng)用的配置文件(如application.properties或application.yml)進(jìn)行快速設(shè)置,另一種是通過自定義的日志配置文件(如logback-spring.xml或log4j2-spring.xml)實(shí)現(xiàn)更精細(xì)的控制。
| 配置方式 | 核心參數(shù) | 作用 | 示例 |
|---|---|---|---|
| 配置文件 (application.properties/yml) | logging.file.name | 設(shè)置完整的日志文件路徑和文件名。 | logging.file.name=/var/log/myapp/app.log |
logging.file.path | 設(shè)置日志文件的目錄,Spring Boot會自動(dòng)在該目錄下生成名為spring.log的文件。 | logging.file.path=/var/log/myapp | |
logging.config | 指定自定義日志配置文件的位置。 | logging.config=classpath:logback-spring.xml | |
| 自定義配置 (logback-spring.xml) | LOG_FILE 或 LOG_PATH | 在XML配置文件中,使用Spring Boot預(yù)定義的系統(tǒng)屬性來動(dòng)態(tài)引用在application.properties中設(shè)置的日志路徑或文件。 | <file>${LOG_FILE}</file> |
5.1 通過應(yīng)用配置文件設(shè)置
這是最簡單直接的方法,適合大多數(shù)常規(guī)需求。
指定完整路徑和文件名:
使用 logging.file.name 可以精確控制日志文件的存儲位置和名稱。
# application.properties 示例 logging.file.name=/var/log/your-app/application.log
# application.yml 示例
logging:
file:
name: /var/log/your-app/application.log僅指定目錄:
使用 logging.file.path,Spring Boot會在該目錄下創(chuàng)建固定的spring.log文件。
# application.properties 示例 logging.file.path=/var/log/your-app
5.2 通過自定義日志配置文件設(shè)置
當(dāng)有復(fù)雜需求時(shí)(如按天歸檔、按文件大小分割、對不同級別日志進(jìn)行過濾等),建議使用自定義日志配置文件。
創(chuàng)建配置文件:在 src/main/resources 目錄下創(chuàng)建 logback-spring.xml(如果使用Logback)或 log4j2-spring.xml(如果使用Log4j2)。
在配置文件中引用外部路徑:在XML配置中,可以使用 ${LOG_FILE} 或 ${LOG_PATH} 來獲取在 application.properties 中設(shè)置的值,這使得配置非常靈活。
<!-- logback-spring.xml 示例片段 -->
<configuration>
<springProperty scope="context" name="LOG_HOME" source="logging.file.path" defaultValue="/tmp/logs"/>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 使用在application.properties中設(shè)置的logging.file.path -->
<file>${LOG_HOME}/spring.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天歸檔日志 -->
<fileNamePattern>${LOG_HOME}/application.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 保留最多30天的日志歷史 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- 其他配置... -->
</configuration>5.3 通過命令行或環(huán)境變量設(shè)置
在部署時(shí)(例如在Kubernetes或Docker容器中),通過命令行參數(shù)或環(huán)境變量來覆蓋配置文件中的設(shè)置,這種方式非常有用。
命令行參數(shù):
java -jar your-app.jar --logging.file.name=/path/to/your/logfile.log
環(huán)境變量:
export LOGGING_FILE_NAME=/path/to/your/logfile.log java -jar your-app.jar
注意事項(xiàng):
掛載到容器外部:在Docker或Kubernetes中部署時(shí),務(wù)必通過卷掛載(Volume)的方式將配置的日志目錄(如
/var/log/your-app)掛載到宿主機(jī)上。這樣可以避免容器重啟后日志丟失,也方便日志收集和管理。權(quán)限問題:確保你的應(yīng)用有在指定日志目錄下寫入文件的權(quán)限,這是一個(gè)常見的部署問題。
路徑選擇:生產(chǎn)環(huán)境中,日志通常放在
/var/log/目錄下,并根據(jù)應(yīng)用名稱建立子目錄,例如/var/log/your-app-name/。配置優(yōu)先級:如果同時(shí)設(shè)置了
logging.file.name和logging.file.path,logging.file.name的優(yōu)先級更高。
總結(jié)
到此這篇關(guān)于SpringBoot項(xiàng)目使用Log4j2+SLF4J構(gòu)建日志的文章就介紹到這了,更多相關(guān)SpringBoot用Log4j2+SLF4J構(gòu)建日志內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring?Boot整合郵箱發(fā)送郵件實(shí)例
大家好,本篇文章主要講的是Spring?Boot整合郵箱發(fā)送郵件實(shí)例,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下2022-02-02
Java中的非對稱加密算法原理與實(shí)現(xiàn)方式
在當(dāng)今的信息時(shí)代,數(shù)據(jù)安全已經(jīng)成為了一個(gè)至關(guān)重要的問題,加密技術(shù)作為保障信息安全的重要手段,受到了廣泛的應(yīng)用和關(guān)注,本篇文章將詳細(xì)介紹Java中的非對稱加密算法原理及其實(shí)現(xiàn)方式,需要的朋友可以參考下2023-12-12
JUC并發(fā)編程LinkedBlockingQueue隊(duì)列深入分析源碼
LinkedBlockingQueue 是一個(gè)可選有界阻塞隊(duì)列,這篇文章主要為大家詳細(xì)介紹了Java中LinkedBlockingQueue的實(shí)現(xiàn)原理與適用場景,感興趣的可以了解一下2023-04-04
RocketMQ中的消費(fèi)者啟動(dòng)流程解讀
這篇文章主要介紹了RocketMQ中的消費(fèi)者啟動(dòng)流程解讀,RocketMQ是一款高性能、高可靠性的分布式消息中間件,消費(fèi)者是RocketMQ中的重要組成部分,消費(fèi)者負(fù)責(zé)從消息隊(duì)列中獲取消息并進(jìn)行處理,需要的朋友可以參考下2023-10-10

