xiaoxpai / Tip-a-day

0 stars 0 forks source link

【系统增强】日志快速定位-traceId #20

Open xiaoxpai opened 9 months ago

xiaoxpai commented 9 months ago

实现方案

第一个方案比较简单,我们可以通过filter拦截所有请求,然后给每个请求分配一个traceId,然后把这个id放到response的header里,同时我们将traceId放到MCD中,然后log4j里读取输出就可以了

先写个Filter拦截请求

package com.example.demo2.filter;

import cn.hutool.core.util.IdUtil;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * @Title: TraceIdFilter
 * @Description: 每个请求分配一个traceId
 */
@WebFilter
@Component
public class TraceIdFilter extends  OncePerRequestFilter {

    private static final String TRACE_ID = "traceId";

    @Override
    public void destroy() {
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        String traceId = IdUtil.fastSimpleUUID();
        response.addHeader(TRACE_ID,traceId);
        MDC.put(TRACE_ID,traceId);
        filterChain.doFilter(request,response);
    }
}

在logback中使用%X{traceId}读取MDC中的内容

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <Pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %level [%X{traceId} ] [%thread][%file:%line] - %msg%n</Pattern>
            </layout>
        </encoder>
    </appender>

效果如下:

2023-01-13 11:12:11.926 INFO [845ad00ad3014a2a9c70db003494c81f ] [http-nio-9090-exec-1][Demo2Application.java:29] - hello world

response

Content-Length: 11
Content-Type: text/html;charset=UTF-8
Date: Thu, 13 Jan 2022 03:12:11 GMT
traceId: 845ad00ad3014a2a9c70db003494c81f

for by