- 1.我们要给每个请求分配一个单独的id
- 2.我们需要把这个id放到我们的日志中
- 3.我们还需要把这个id放到response中,可以被调用方感知到。
第一个方案比较简单,我们可以通过filter拦截所有请求,然后给每个请求分配一个traceId,然后把这个id放到response的header里,同时我们将traceId放到MCD中,然后log4j里读取输出就可以了
先写个Filter拦截请求
packagecom.example.demo2.filter; importcn.hutool.core.util.IdUtil; importorg.slf4j.MDC; importorg.springframework.stereotype.Component; importorg.springframework.web.filter.OncePerRequestFilter; importjavax.servlet.*; importjavax.servlet.annotation.WebFilter; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; /*** home.php?mod=space&uid=686208 zhangjiapeng* home.php?mod=space&uid=1248337 V1.0* @Title: TraceIdFilter* @Description: 每个请求分配一个traceId* home.php?mod=space&uid=686237 2022/1/13 10:22*/publicclassTraceIdFilterextendsOncePerRequestFilter { privatestaticfinalStringTRACE_ID="traceId"; publicvoiddestroy() { } protectedvoiddoFilterInternal(HttpServletRequestrequest, HttpServletResponseresponse, FilterChainfilterChain) throwsServletException, IOException { StringtraceId=IdUtil.fastSimpleUUID(); response.addHeader(TRACE_ID,traceId); MDC.put(TRACE_ID,traceId); filterChain.doFilter(request,response); } }
在logback中使用**%X{traceId}**读取MDC中的内容
<appendername="CONSOLE"class="ch.qos.logback.core.ConsoleAppender"><encoderclass="ch.qos.logback.core.encoder.LayoutWrappingEncoder"><layoutclass="ch.qos.logback.classic.PatternLayout"><Pattern>%date{yyyy-MM-ddHH:mm:ss.SSS} %level [%X{traceId} ] [%thread][%file:%line] -%msg%n</Pattern></layout></encoder></appender>
效果如下:
2023-08-01 09:12:11.926 INFO [845ad00ad3014a2a9c70db003494c81f ] [http-nio-9090-exec-1][Demo2Application.java:29] - hello world
方案2:
因为我们接入了APM,APM中也有对应的traceId,所以我们能不能用APM的traceId呢。
首先引入APM工具包
<!--https://mvnrepository.com/artifact/org.apache.skywalking/apm-toolkit-trace --><dependency><groupId>org.apache.skywalking</groupId><artifactId>apm-toolkit-trace</artifactId><version>8.8.0</version></dependency>
改造一下TraceIdFilter
packagecom.example.demo2.filter; importorg.apache.skywalking.apm.toolkit.trace.TraceContext; importorg.slf4j.MDC; importorg.springframework.stereotype.Component; importorg.springframework.web.filter.OncePerRequestFilter; importjavax.servlet.FilterChain; importjavax.servlet.ServletException; importjavax.servlet.annotation.WebFilter; importjavax.servlet.http.HttpServletRequest; importjavax.servlet.http.HttpServletResponse; importjava.io.IOException; /*** @author zhangjiapeng* @version V1.0* @Title: TraceIdFilter* @Description:* @date 2022/1/13 10:22*/publicclassTraceIdFilterextendsOncePerRequestFilter { privatestaticfinalStringTRACE_ID="traceId"; publicvoiddestroy() { } protectedvoiddoFilterInternal(HttpServletRequestrequest, HttpServletResponseresponse, FilterChainfilterChain) throwsServletException, IOException { StringtraceId=TraceContext.traceId(); response.addHeader(TRACE_ID,traceId); MDC.put(TRACE_ID,traceId); filterChain.doFilter(request,response); } }
效果如下:
2023-08-01 10:32:21.776 INFO [e9a1abc4800345c6af4ee926be230f15.43.16420444870010001 ] [http-nio-9090-exec-2][Demo2Application.java:29] - hello world