文章目录
TraceID提高问题排查效率
问题
通常服务遇到问题,通过查询日志信息来定位bug,但是只能根据日志的关键信息来查询,查询信息不全,排查困难
如何解决
将traceID注入日志,查询的时候根据traceID查询出整个链路信息
上代码
Web接口在拦截器中注入traceID
注意这里是org.apache.logging.log4j.ThreadContext
import cn.hutool.extra.servlet.ServletUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Component
@Slf4j
public class MyHttpInterceptor extends HandlerInterceptorAdapter {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("url:{}, params:{}",
request.getRequestURL(),
ServletUtil.getParams(request));
ThreadContext.put("traceId", "我是traceId");
log.info("注入traceID");
/*if (request instanceof MyRequest) {
MyRequest myRequest = (MyRequest) request;
log.info(myRequest.getBody());
return super.preHandle(myRequest, response, handler);
}*/
return true;
}
}
RPC接口在RPC过滤器中注入traceID
provider端
rpc添加拦截器
import com.alibaba.dubbo.rpc.*;
import org.apache.logging.log4j.ThreadContext;
public class MyFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
ThreadContext.put("traceId", RpcContext.getContext().getAttachment("x_traceId"));
return invoker.invoke(invocation);
}
}
配置RPC拦截器
consumer端
添加拦截器
import com.alibaba.dubbo.rpc.*;
import org.apache.logging.log4j.ThreadContext;
public class MyRpcFilter implements Filter {
@Override
public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
System.out.println("注入RPC");
RpcContext.getContext().setAttachment("x_token", "我是token");
String traceId = ThreadContext.get("traceId");
RpcContext.getContext().setAttachment("x_traceId", traceId);
return invoker.invoke(invocation);
}
}
在log4j2.xml中修改pattern
log4j2依赖
注意要解决冲突
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
如下在PatternLayout的pattern中加入 %X{traceId},%X代表获取自定义的参数
<?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}][%t][%highlight{%X{traceId}}][%highlight{%level}][%C:%L] %m%n"/>
</Console>
<RollingFile name="RollingFile" fileName="logs/demo-service.log"
filePattern="logs/demo-service-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss.SSS}][%traceId][%userId][%t][%X{traceId}][%level][%C:%L] %m%n" />
<Policies>
<TimeBasedTriggeringPolicy/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO">
<AppenderRef ref="Console"/>
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
效果
web 端Filter注入traceID
服务提供者
如在ks8这种日志系统中搜索日志时,就可以根据traceID查到整个调用链