app开发者平台在数字化时代的重要性与发展趋势解析
935
2023-01-21
SpringBoot+slf4j实现全链路调用日志跟踪的方法(一)
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中的键名称一致
添加一个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
在cJDNWwJ下一篇文章中继续讲解子线程中如何实现traceId的日志跟踪
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~