在分布式系统中,为了方便追踪和调试问题,通常会为每个请求生成一个唯一的追踪 ID(Trace ID)。这个 ID 可以在整个请求的生命周期中传递,并在日志中记录。Logback 是一个流行的 Java 日志框架,可以通过自定义 MDC(Mapped Diagnostic Context)来实现这一功能。
以下是如何在 Logback 中添加请求唯一追踪 ID 的详细步骤:
1. 引入依赖
首先,确保你的项目中已经包含了 Logback 的依赖。如果你使用的是 Maven,可以在 pom.xml
文件中添加以下依赖:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
2. 配置 Logback
接下来,需要配置 Logback 以支持 MDC。你可以在 src/main/resources
目录下创建一个 logback.xml
文件,并添加以下内容:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg %X{traceId}%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
在这个配置文件中,我们定义了一个控制台输出的 appender,并使用 %X{traceId}
来输出 MDC 中的 traceId
。
3. 生成和设置 Trace ID
在你的应用程序中,你需要为每个请求生成一个唯一的 Trace ID,并将其放入 MDC。假设你在使用 Spring Boot,可以在过滤器或拦截器中实现这一点。
使用过滤器
创建一个过滤器类,用于生成和设置 Trace ID:
import org.slf4j.MDC;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.UUID;
public class TraceIdFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// 初始化代码
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
try {
String traceId = UUID.randomUUID().toString();
MDC.put("traceId", traceId);
chain.doFilter(request, response);
} finally {
MDC.remove("traceId");
}
}
@Override
public void destroy() {
// 销毁代码
}
}
注册过滤器
在 Spring Boot 应用中,可以通过 @Bean
注解将过滤器注册到应用上下文中:
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean<TraceIdFilter> loggingFilter(){
FilterRegistrationBean<TraceIdFilter> registrationBean = new FilterRegistrationBean<>();
registrationBean.setFilter(new TraceIdFilter());
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
4. 测试日志输出
现在,当你的应用程序处理请求时,每个日志条目都会包含一个唯一的 Trace ID。例如:
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 TestController {
private static final Logger logger = LoggerFactory.getLogger(TestController.class);
@GetMapping("/test")
public String test() {
logger.info("This is a test log message");
return "Check the logs for the trace ID!";
}
}
启动应用程序并访问 /test
端点,你应该会在控制台中看到类似以下的日志输出:
2023-10-01 12:00:00 [http-nio-8080-exec-1] INFO com.example.TestController - This is a test log message 123e4567-e89b-12d3-a456-426614174000
其中 123e4567-e89b-12d3-a456-426614174000
就是生成的 Trace ID。通过这种方式,你可以很容易地在分布式系统中追踪和调试请求。