

SLF4J MDC在全链路跟踪中的应用
source link: https://fredal.xin/mdc-in-tracing?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

经常做线上问题排查的可能会有感受,由于日志打印一般是无序的,多线程下想要串行拿到一次请求中的相关日志简直是大海捞针。那么MDC是一种很好的解决办法。
SLF4J的MDC
SLF4J 提供了MDC ( Mapped Diagnostic Contexts )功能,它的实现也是利用了 ThreadLocal 机制。 在代码中,只需要将指定的值 put 到线程上下文的 Map 中,然后在对应的地方使用 get 方法获取对应的值,从而达到自定义和修改日志输出格式内容的目的。
例如以下受log4j2.xml模板:
<Pattern>%d %p [%c] [%X{key1},%X{key2}]- %m%n</Pattern>
在日志模板log4j2.xml中,使用 %X{} 来占位,内容会替换为对应MDC 中 key的值,以达到自定义日志格式的效果。
MDC在链路跟踪中的应用
在链路跟踪框架中,其实扩展MDC很简单,只需在log span的before方法中塞入traceId与spanId,在after方法中进行清理逻辑即可。
private void beforeStartSpan(Span span){ MDC.put(TraceKeys.TRACE_ID, span.getTraceId()); MDC.put(TraceKeys.SPAN_ID, span.getSpanId()); } private void afterEndSpan(Span span){ MDC.remove(TraceKeys.TRACE_ID); MDC.remove(TraceKeys.SPAN_ID); if (span != null) { MDC.put(TraceKeys.TRACE_ID, currentSpan.getTraceId()); MDC.put(TraceKeys.SPAN_ID, currentSpan.getParentId()); //此处需要塞回parent span的spanId } }
那么在log4j2.xml中配置:
<Pattern>%d %p [%c] [%X{TraceId},%X{SpanId}]- %m%n</Pattern> //在合适的地方加入 [%X{TraceId},%X{SpanId}] 即可
这样输出日志即为:
2019-01-29 19:06:15,482 INFO [com.fredal.TestController] [e9b84d301f73f6e1a6386f216fa0120d,9296f83b058675d2]- this is a test in test 2019-01-29 19:06:15,489 INFO [com.fredal.TestController] [e9b84d301f73f6e1a6386f216fa0120d,f435c1cb819db821]- this is a test in test/provider
异步中的MDC
由于MDC是基于Threadlocal的,那么如果一个请求中有异步的逻辑,那么异步过程中的日志是取不到MDC中的值的。
这也是个老生常谈的问题了,由于我们的全链路跟踪框架已经使用Transmittable ThreadLocal改造过了,见 调用链跨线程传递THREADLOCAL对象 ,所以在异步线程中也是同样能获得的MDC的值的。
Recommend
-
74
...
-
47
-
53
当今的互联网服务,通常都是用大规模的分布式集群来实现的。服务可能来自不同的研发团队、使用不同的编程语言来实现、运行在上千台服务器上。随着链家的业务发展,公司的分布式系统变得越来越复杂,用户的一次请求通常由多个系统协同完成...
-
88
-
50
在微服务架构中,调用链是漫长而复杂的,要了解其中的每个环节及其性能,你需要全链路跟踪。 它的原理很简单,你可以在每个请求开始时生成一个唯一的ID,并将其传递到整个调用链。 该ID称为
-
51
本文全面讲述了云音乐全链路跟踪系统的设计思想,实践路线,以及在技术选择与功能迭代方面上思考总结。...
-
35
谁说Cat不能做链路跟踪的,给我站出来 链路跟踪,我们有很多可选项。常见的有 zipkin,pinpoint,skywalking,jaeger 等。 基本上都是根据谷歌的《Dapper 大规模分布式系统的跟踪系统》这篇论文发展出来的。 今...
-
14
应用监控配置 -Darms.licenseKey 表示javaagent配置文件里的参数arms.licenseKey,表示授权码 -Darms.appName 这个也是配置文件中的appName,表示应用名称 -javaagent:D:/ArmsAgent/ArmsAgent/arms-bootstrap-1....
-
10
Envoy 集成 Jaeger 实现分布式链路跟踪2022-01-1425 29 min.当我们的应用架构,从单体系统演变为微服务时,一个永远不可能回避的现实是,业务逻辑会被拆分到不同的服务中。因此,微服务实际就是不同服务间的互相请求和调用。更重要的是,...
-
5
利用 ASP.NET Core 中的标头传播实现分布式链路跟踪在此之前,我曾写过一篇博客,《Envoy 集成 Jaeger 实现分布式链路跟踪》,主要分享了 ASP.NET Core 应用如何结合
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK