SpringBoot全链路调用日志跟踪 SpringBoot+slf4j实现全链路调用日志跟踪的方法(一)

软件发布|下载排行|最新软件

当前位置:首页IT学院IT技术

SpringBoot全链路调用日志跟踪 SpringBoot+slf4j实现全链路调用日志跟踪的方法(一)

kevin_ying   2021-05-13 我要评论
想了解SpringBoot+slf4j实现全链路调用日志跟踪的方法(一)的相关内容吗,kevin_ying在本文为您仔细讲解SpringBoot全链路调用日志跟踪的相关知识和一些Code实例,欢迎阅读和指正,我们先划重点:SpringBoot全链路调用日志跟踪,SpringBoot,日志跟踪,下面大家一起来学习吧。

SpringBoot中除了常见的分布式链路跟踪系统zipkin、skywalking等,如果需要快速定位一次请求的所有日志,那么该如何实现?实际slf4j提供了MDC(Mapped Diagnostic Contexts)功能,支持用户定义和修改日志的输出格式以及内容。本文将介绍 Tracer集成的slf4j MDC功能,方便用户在只简单修改日志配置文件的前提下输出当前 Tracer 上下文 TraceId。

MDC介绍

MDC(Mapped Diagnostic Context,映射调试上下文)是 log4j 、logback及log4j2 提供的一种方便在多线程条件下记录日志的功能。MDC 可以看成是一个与当前线程绑定的哈希表,可以往其中添加键值对。MDC 中包含的内容可以被同一线程中执行的代码所访问。当前线程的子线程会继承其父线程中的 MDC 的内容。当需要记录日志时,只需要从 MDC 中获取所需的信息即可。MDC 的内容则由程序在适当的时候保存进去。对于一个 Web 应用来说,通常是在请求被处理的最开始保存这些数据。

springboot中如何使用

添加拦截器

public class LogInterceptor implements HandlerInterceptor {

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String tid = UUID.randomUUID().toString().replace("-", "");
		MDC.put(CloudConstant.MDC_TRACE, tid);
		return true;
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			@Nullable Exception ex) throws Exception {
		MDC.remove(CloudConstant.MDC_TRACE);
	}

}

注册拦截器

@Configuration
public class WebInterceptorAdapter implements WebMvcConfigurer {
	@Bean
	public LogInterceptor logInterceptor() {
		return new LogInterceptor();
	}

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(logInterceptor());
	}
}

修改日志输出格式,添加%X{traceId},traceId和MDC中的键名称一致

<pattern>%date %-5level ${PID:- } [%thread] [%X{tid}] : /*[%logger{50}:%line] %msg*/%n</pattern>

添加一个controller调用测试

@RestController
@RequestMapping("trace")
@Slf4j
public class TestTraceController {

    @GetMapping("traceLog")
    public String traceLog() {
        log.info("---接口调用了---");
        traceService();
        return "success";
    }

    private void traceService(){
        log.error("## 执行traceService方法");
    }
}

日志打印如下,我们可以通过traceId快速查找出同一个请求的所有日志

细心的同学就会发现,MDC还是存在一些问题

  • 在子线程中打印日志丢失traceId
  • HTTP调用丢失traceId

下一篇文章中小编继续讲解子线程中如何实现traceId的日志跟踪

Copyright 2022 版权所有 软件发布 访问手机版

声明:所有软件和文章来自软件开发商或者作者 如有异议 请与本站联系 联系我们