目的
- 用户的每次请求都是独立的,为了方便追溯,我们打出的日志应该针对单次请求有唯一标示,就是 traceId
- 可以通过线程 ID 来区分,但线程是可复用的。
- 解决方法是 MDC。
- 通过添加 filter,请求到达时,把 traceId 放到 MDC,这样每次请求生命周期,打出的日志就可以带上唯一标识。
方法
1. 实现 TraceInterceptor
import java.util.UUID;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.MDC;
import org.springframework.web.servlet.HandlerInterceptor;
public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String traceId = UUID.randomUUID().toString().toUpperCase();
MDC.put("TRACE_ID", traceId);
return true;
}
}
2. 注册 Interceptor
@Configuration 注解保证 InterceptorConfig 会被 SpringBoot 作为 bean 加载
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Bean
public TraceInterceptor initTraceInterceptor() {
return new TraceInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(initTraceInterceptor()).addPathPatterns("/**");
}
}
3. 配置 log4j2.xml
里边需要包含 TRACE_ID
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - TRACE_ID=%X{TRACE_ID} %msg%n</pattern>
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="120 seconds">
<appender name="FILE_TEST" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>/Users/charles.lin/Downloads/jingwei.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>/Users/charles.lin/Downloads/%d{yyyy-MM-dd}/jingwei.%d{yyyy-MM-dd}.%i.gz
</fileNamePattern>
<maxFileSize>512MB</maxFileSize>
<!-- keep 7 days' worth of history capped at 5GB total size -->
<maxHistory>7</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - TRACE_ID=%X{TRACE_ID} %msg%n
</pattern>
</encoder>
</appender>
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{36}) - TRACE_ID=%X{TRACE_ID} %msg%n
</pattern>
</encoder>
</appender>
<logger name="FileTest" level="INFO">
<appender-ref ref="FILE_TEST"/>
</logger>
<logger name="console" level="INFO">
<appender-ref ref="console"/>
</logger>
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>
4. 查看效果
20:43:48.093 [http-nio-8081-exec-2] ERROR c.a.d.p.controller.ServiceController - TRACE_ID=8905FF6C-2B8E-4412-A31A-4E3CFB04DB6D some log info