目录
[5.1 通过应用配置文件设置](#5.1 通过应用配置文件设置)
[5.2 通过自定义日志配置文件设置](#5.2 通过自定义日志配置文件设置)
[5.3 通过命令行或环境变量设置](#5.3 通过命令行或环境变量设置)
1、添加项目依赖
确保的pom.xml中包含Spring Boot Starter Log4j2的依赖,同时排除默认的Logback
XML
<dependencies>
<!-- Spring Boot Log4j2 Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<!-- 排除掉默认的 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、创建TraceId过滤器
这个Filter负责在请求开始时生成TraceId并放入上下文,在请求结束后清理
java
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,如果没有则生成一个
String traceId = httpRequest.getHeader(TRACE_ID_HEADER);
if (traceId == null || traceId.isEmpty()) {
// 生成唯一ID,这里使用UUID,你可以根据需要调整
traceId = UUID.randomUUID().toString().replace("-", "").substring(0, 16);
}
// 将TraceId放入Log4j2的ThreadContext,这样日志就能自动打印了
ThreadContext.put(TRACE_ID_KEY, traceId);
// 可选:将TraceId设置到响应头,方便前端或下游服务追踪
httpResponse.setHeader(TRACE_ID_HEADER, traceId);
try {
chain.doFilter(request, response); // 继续执行请求链
} finally {
// 请求处理完毕,务必清理ThreadContext,避免内存泄漏和数据污染
ThreadContext.remove(TRACE_ID_KEY);
}
}
}
3、配置Log4j2以输出TraceId
修改src/main/resources/log4j2.xml配置文件,在日志输出模式(Pattern)中加入TraceId
XML
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<!-- 控制台输出配置 -->
<Console name="Console" target="SYSTEM_OUT">
<!-- 设置日志输出格式 -->
<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>
关键说明:
- 格式中的
%X{traceId}就是一个占位符,它会自动从Log4j2的ThreadContext中读取key为"traceId"的值 。如果不存在,则该处输出为空。
4、在代码中记录日志
现在可以在代码中正常使用SLF4J记录日志,TraceId会自动出现在日志中。
java
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("收到请求"); // 日志会自动包含traceId
// ... 你的业务逻辑
return "请求完成";
}
}
5、日志挂载位置
在Spring Boot项目中,设置日志的挂载位置主要有两种思路:一种是通过应用的配置文件(如application.properties或application.yml)进行快速设置,另一种是通过自定义的日志配置文件(如logback-spring.xml或log4j2-spring.xml)实现更精细的控制。
| 配置方式 | 核心参数 | 作用 | 示例 |
|---|---|---|---|
| 配置文件 (application.properties/yml) | logging.file.name |
设置完整的日志文件路径和文件名。 | logging.file.name=/var/log/myapp/app.log |
logging.file.path |
设置日志文件的目录 ,Spring Boot会自动在该目录下生成名为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预定义的系统属性来动态引用在application.properties中设置的日志路径或文件。 |
<file>${LOG_FILE}</file> |
5.1 通过应用配置文件设置
这是最简单直接的方法,适合大多数常规需求。
指定完整路径和文件名:
使用 logging.file.name 可以精确控制日志文件的存储位置和名称。
bash
# application.properties 示例
logging.file.name=/var/log/your-app/application.log
bash
# application.yml 示例
logging:
file:
name: /var/log/your-app/application.log
仅指定目录:
使用 logging.file.path,Spring Boot会在该目录下创建固定的spring.log文件。
bash
# application.properties 示例
logging.file.path=/var/log/your-app
5.2 通过自定义日志配置文件设置
当有复杂需求时(如按天归档、按文件大小分割、对不同级别日志进行过滤等),建议使用自定义日志配置文件。
创建配置文件: 在 src/main/resources 目录下创建 logback-spring.xml(如果使用Logback)或 log4j2-spring.xml(如果使用Log4j2)。
在配置文件中引用外部路径: 在XML配置中,可以使用 ${LOG_FILE} 或 ${LOG_PATH} 来获取在 application.properties 中设置的值,这使得配置非常灵活。
XML
<!-- 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中设置的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 通过命令行或环境变量设置
在部署时(例如在Kubernetes或Docker容器中),通过命令行参数或环境变量来覆盖配置文件中的设置,这种方式非常有用。
命令行参数:
bash
java -jar your-app.jar --logging.file.name=/path/to/your/logfile.log
环境变量:
bash
export LOGGING_FILE_NAME=/path/to/your/logfile.log
java -jar your-app.jar
注意事项:
-
挂载到容器外部 :在Docker或Kubernetes中部署时,务必 通过卷挂载(Volume)的方式将配置的日志目录(如
/var/log/your-app)挂载到宿主机上。这样可以避免容器重启后日志丢失,也方便日志收集和管理。 -
权限问题 :确保你的应用有在指定日志目录下写入文件的权限,这是一个常见的部署问题。
-
路径选择 :生产环境中,日志通常放在
/var/log/目录下,并根据应用名称建立子目录,例如/var/log/your-app-name/。 -
配置优先级 :如果同时设置了
logging.file.name和logging.file.path,logging.file.name的优先级更高。