OpenTelemetry .NET Core自动插桩:如何通过traceid传播实现日志关联?
自动插桩场景下日志补充Trace信息实现方案
完全不需要全量手动插桩,主流链路追踪体系已经提供了成熟的自动注入能力,具体实现逻辑如下:
基础场景无侵入实现
- 主流APM/链路追踪框架(OpenTelemetry、SkyWalking、Jaeger等)的自动插桩探针,默认会将当前链路的
traceId、spanId、traceparent等元数据写入当前线程的上下文容器(Java生态对应MDC、Go生态对应context.Context、Node.js生态对应AsyncLocalStorage、Python生态对应contextvars) - 仅需要修改日志框架的输出格式模板,添加对应上下文变量的占位符即可,不需要修改任何业务代码
以Java生态Logback框架为例,只需要在日志Pattern中追加对应字段即可:<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - traceId:%X{traceId} spanId:%X{spanId} traceparent:%X{traceparent} - %msg%n</pattern> - 常用异步组件(官方支持的线程池、响应式框架、网络客户端等)的上下文透传已经被自动插桩覆盖,异步线程打印的日志也会自动携带Trace相关字段
特殊场景少量补充适配
只有遇到自动插桩未覆盖的自定义组件时,才需要做极少量的代码适配,无需修改业务日志打印逻辑:
- 自定义未适配的线程池:仅需要给线程池添加全局的上下文传递拦截器,在提交任务时将当前Trace上下文绑定到任务中即可
- 自定义跨进程通信组件(自研RPC、自定义MQ消费逻辑等):仅需要在发送端从当前上下文取出
traceparent写入请求/消息头,接收端从请求/消息头取出值写入当前进程的线程上下文即可,全链路仅需要修改通信组件的2处封装逻辑
接收端关联逻辑
日志采集端(Logstash、Fluentd、Vector等)采集到日志后,会自动识别Trace相关字段,直接和链路存储中的traceId/traceparent字段做等值关联查询即可完成日志与链路数据的打通。
内容的提问来源于stack exchange,提问作者dodegaard
相关产品推荐
相关产品推荐

