网关和业务服务traceId打通记录

        项目里面使用的是skywalking通过tid来记录一次请求的调用链的,但是发现在网关层的tid显示是N/A.网关处skywalking由于权限问题没办修改,我就想着使用MDC的方式来修改吧。

       第一步:

       因为网关处使用的是ServerWebExchange来接受参数的,但是在业务层的拦截器里面使用的是HttpServletRequest,首先需要在网关处的header里面添加一个traceId的属性,这样在业务层的拦截器处就能拦截到。

     

public void logRequest(ServerWebExchange exchange, ServerHttpRequest mutatedRequest) {
        ServerHttpRequest request = exchange.getRequest();
        HttpHeaders headers = request.getHeaders();
        if(Objects.isNull(request.getHeaders().getFirst(TraceUtils.TRACE_ID))){
            request.mutate().header(TraceUtils.TRACE_ID,TraceUtils.createTraceId());
        }
        String curIp = exchange.getRequest().getHeaders().getFirst(Constant.H_KEY_IP);
        JSONObject json = getHeaderJson(headers);
        json.put("method",request.getMethodValue());
        json.put("ip",curIp);
        json.put("path",request.getPath().toString());

        //请求参数,post从请求里获取请求体
        if (request.getMethod() == HttpMethod.POST) {

        } else if (request.getMethod() == HttpMethod.GET) {
            json.put("body",request.getQueryParams().toString());
        } else if (request.getMethod() == HttpMethod.PUT) {
            json.put("body",request.getQueryParams().toString());
        }
        logger.info("request-info:{}",json.toString());
    }

 

public class TraceUtils {
    public static final String TRACE_ID = "traceId";

    public static synchronized String createTraceId() {
        String traceId = UUID.randomUUID().toString().replaceAll("-", "").toLowerCase();
        MDC.put(TRACE_ID, traceId);
        return traceId;
    }

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


}

 

之后需要在日志里面将traceId记录起来:

 

        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %tid [%-5level] [%thread] [%logger{15}:%line] %X{traceId} --- %msg%n</pattern>
            </layout>
        </encoder>

 

3.在业务层的拦截器处

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String gatewayTraceId = request.getHeader(TRACE_ID);
        log.info("gateway traceId:" + gatewayTraceId + ",MDC:" + MDC.get(TRACE_ID));
        if(Objects.isNull(gatewayTraceId)){
            request.setAttribute(TRACE_ID, TraceUtils.createTraceId());
        }else {
            request.setAttribute(TRACE_ID,gatewayTraceId);
            MDC.put(TRACE_ID,gatewayTraceId);
        }
//其他业务逻辑 }

 

同时在业务代码层也需要在日志添加好:

        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.TraceIdPatternLogbackLayout">
                <pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} %tid [%-5level] [%thread] [%logger{15}:%line] %X{traceId} --- %msg%n</pattern>
            </layout>
        </encoder>

 

posted @ 2023-07-05 16:40  Doyourself!  阅读(210)  评论(0编辑  收藏  举报