分享
福uu链路追踪重构
输入“/”快速插入内容
福uu链路追踪重构
用户9219
用户9219
4月14日修改
背景
福uu当前的链路追踪使用字节框架集成 jaeger(其实好像也没用上),只能记录到 http + rpc 调用链路,不会对外部依赖调用进行埋点,同时也没有将链路与 logger 做绑定,在链路追踪的可观测性上堪称残废。
概念梳理
•
OpenTelemetry(OTel)
是一套厂商中立的可观测性标准与 SDK,用来统一生成、传递、收集和导出 traces、metrics、logs。Go 官方文档也把它定位成统一处理三类遥测数据的框架。
•
traceId
用来标识“一整条请求链路”;同一个请求在 gateway、微服务、数据库、Redis、下游 HTTP/RPC 中共享同一个 traceId。
•
spanId
用来标识“链路中的一个具体步骤”;一个 trace 下会有多个 span,每个 span 有自己的 spanId,并通过父子关系组成调用树。OTel/OTLP 规范将 trace、metric、log 都作为统一遥测信号处理。
•
OTLP
是 OpenTelemetry Protocol,用于在应用、Collector、后端之间传输遥测数据;它是当前 trace / metric / log 的统一传输协议。OTLP 支持 gRPC 和 HTTP/protobuf 两种主流传输方式。
•
Uptrace
是一个 OpenTelemetry-native 的后端,能同时接收 traces、metrics、logs,并且官方提供了 Go 的接入文档与
uptrace-go
发行版,比较轻量,适合用作上报目标
•
如何通过 traceID 查 logger
a.
在 middleware / interceptor 中把 trace context 放入 ctx
b.
提供统一的
logger.WithContext(ctx)
c.
logger.WithContext(ctx)
自动提取并注入:
▪
trace_id
▪
span_id
▪
可选
service.name
d.
所有日志统一用这个 logger 输出
这样:
◦
在 Uptrace 里拿到 traceId
◦
在日志系统或日志文件里 grep / query 相同 trace_id
◦
就能回查整条请求对应的日志
目标
1.
使链路追踪能够覆盖到 http + rpc + 外部依赖整个链路,也能覆盖 cronjob 场景,同时支持对报错的埋点
2.
将链路追踪与 logger 集成,在排查错误时,通过链路追踪的 traceID 能够查到该链路对应的 logger
3.
通过 OpenTelemetry 协议上报 trace,目前希望是通过 Uptrace 来集成,上报到 Uptrace 中
4.
业务开发人员不需要在意链路追踪的实现,程序能够自动做到链路的追踪与上报
链路总览
设计补充
trace middleware
trace middleware 在所有请求传到 api 层之前,负责:
1.
从上游 header 中提取 trace context;如果没有,则创建 root span
2.
将派生后的
context.Context
传入后续 handler
3.
在请求结束时自动
span.End()
4.
内层报错时将该trace标记为error
这里建议直接使用 OTel 官方 Go SDK 与 HTTP instrumentation,OpenTelemetry Go 官方建议优先使用现成的 instrumentation library;在 HTTP 场景下可使用
otelhttp
这类方式统一创建与结束 span。
trace inspector
trace inspector 放在 rpc handler 前,负责:
1.
检查 ctx 中是否已有 span context
2.
若已有,则沿用并派生 child span
3.
若没有,则补建 trace,避免内部异步调用链路断裂
4.
统一补充 service / rpc method / peer 等属性
gRPC / RPC 场景同样推荐优先走 OTel 的 server/client interceptor 思路,使用官方支持的 instrumentation libraries
loggerSpan