SpringBoot中使用TraceId进行日志追踪

**查询日志的痛点:**项目中每当我们查询日志的时候都是看前端请求什么接口,根据一些关键字进入服务器查询日志中是否有这个关键字,然而这个关键字在日志里面并不是唯一的,所以要生成一个唯一的标识,每一次请求都是唯一的一串字符,查询会过滤掉很多无用的信息,快捷查找到这次请求。为了解决这个痛点,就使用了TraceId。

一、TraceId 定义

用于标识某一次具体的请求ID。当用户的请求进入系统后,会在RPC调用网络的第一层生成一个全局唯一的traceId,并且会随着每一层的RPC调用,不断往后传递,这样的话通过traceId就可以把一次用户请求在系统中调用的路径串联起来。

在分布式系统中,一个请求可能会涉及多个服务和组件的调用,而traceId可以帮助我们追踪和查看整个请求的流程和调用链

二、TraceId的请求流程

在最开始请求系统时候生成一个全局唯一的traceId,放在http 请求header中,系统接收到请求后,从header中取出这个traceId,放入MDC中,这个traceId伴随着这整个请求的调用周期,即当一个服务调用另外一个服务的时候,需要将traceId往下传递,从而形成一条链路。

注意:这次的traceId主要是用UUID来生成的,前端生成traceId,后端拦截器拦截到了做一层判断,如果前端有,就不需要后端生成,而且只需要将前端的这个traceId发给后端人员,后端人员就能直接能定位到日志,不需要再让前端给请求的是什么接口,所以建议是前端来生成traceId。

三、SpringBoot整合TraceId

(一)添加一个logback.xml

logback.xml内容如下:



      
    
    

    
    
    
    
    
    
    
        
            ${log.pattern.console}
            utf8
        
    
    
    
        ${LOG_PATH}/${LOG_FILE}.log
        true
        

            ${log.pattern.file}
        
        
            
                ${DATE_PATH}/%i.log
            
            15
            20GB
            50MB
        
    

    
        
            ERROR
            ACCEPT
            DENY
        
        ${LOG_PATH}/${LOG_FILE}.error.log
        true
        
            
            ${log.pattern.file}
        
        
            
                ${DATE_PATH}/%i.error.log
            
            15
            20GB
            50MB
        
    

    
        
        
        
    


(二)添加TraceId工具类

TraceIdUtil.java

package xxx;

import org.slf4j.MDC;

import java.util.UUID;

/**
 * @author lyc
 * @date 2024/10/17
 * @funtion
 */
public class TraceIdUtil {
    public static final String TRACE_ID = "traceId";

    public static String getTraceId() {
        String traceId = MDC.get(TRACE_ID);
        return traceId == null ? "" : traceId;
    }

    public static void setTraceId(String traceId) {
        MDC.put(TRACE_ID, traceId);
    }

    public static void remove() {
        MDC.remove(TRACE_ID);
    }

    public static void clear() {
        MDC.clear();
    }

    public static String generateTraceId() {
        return UUID.randomUUID().toString().replace("-", "");
    }
}

(三)添加TraceId拦截器

SystemTraceIdInterceptor.java

package xxx;

import xxx.TraceIdUtil;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * @author lyc
 * @date 2024/10/17
 * @funtion
 */
@Component
public class SystemTraceIdInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
        //如果有上层调用就用上层的ID
        String traceId = request.getHeader(TraceIdUtil.TRACE_ID);
        if (traceId == null) {
            traceId = TraceIdUtil.generateTraceId();
        }
        MDC.put(TraceIdUtil.TRACE_ID, traceId);

        //配置traceId到响应header中
        response.setHeader(TraceIdUtil.TRACE_ID, MDC.get(TraceIdUtil.TRACE_ID));

        return true;
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //调用结束后删除
        MDC.remove(TraceIdUtil.TRACE_ID);
    }
}

(四)InterceptorConfig配置TraceId拦截器

InterceptorConfig.java

package xxx.config;

import xxx.SystemTraceIdInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;

/**
 * @author lyc
 * @updated: 2024/10/17
 * @funtion
 */
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {

    @Resource
    private SystemTraceIdInterceptor systemTraceIdInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //配置链路追踪traceId拦截器
        registry.addInterceptor(systemTraceIdInterceptor).addPathPatterns("/**");
    }

}

四、效果

你可能感兴趣的:(面试,学习路线,阿里巴巴,spring,boot,状态模式,后端)