应用接入 APM 以后,TraceID 由系统自动生成,在绝大多数的情况下,您不需要自定义 TraceID,也不需要关注 TraceID 生成逻辑。如果需要实现链路与日志关联分析,也仅需要在应用中将获取到 TraceID 输出日志,具体实现方式请参见 链路与日志关联分析。
只有在极少数特殊的场景中,才可能存在自定义 TraceID 的需求。本文列出了其中一种典型场景,您可以参考本文实现自定义 TraceID。
说明:
本文适用于使用 OpenTelemetry 方案的业务系统,如果您的业务系统使用 Skywalking 等方案,需要调整 TraceID 的生成规则以及传递方式。
场景分析
在实际业务中,如果某应用同时满足如下条件,可以考虑在此应用中自定义 TraceID:
该应用没有接入 APM。
该应用的下游应用接入了 APM。
该应用对下游应用的请求基于 HTTP 协议。
对于经过该应用的链路,需要通过特定的 TraceID 关联其他的业务场景。例如存在 TraceID 与订单 ID 之间的映射关系,或者需要通过 TraceID 查询该应用的日志数据。
以如下架构图为例,Service A 就是一个符合自定义 TraceID 标准的应用。对于 Service A 收到的每条用户请求,都根据本文的步骤自定义 TraceID,就能保持 TraceID 在整个系统中的传递。

实现步骤
自定义 TraceID 的流程严格遵循 W3C Trace 规范,包括 TraceID/SpanID 的生成,以及需要在 HTTP 请求中添加的 Header。如果任何一个环节不满足规范,自定义生成的 TraceID 将被 APM 忽略,这种情况不会对实际业务有任何影响 ,但接入 APM 的应用会重新生成新的 TraceID。
生成 TraceID
TraceID 表现为一个长度为32的字符串,其中每个字符为一个16进制数字,取值范围为:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,例如
4bf92f3577b34da6a3ce929d0e0e4736
。针对每次用户操作,都需要生成新的 TraceID 与之对应,请自行确保 TraceID 的随机性,并注意全零情况00000000000000000000000000000000
会被视为不合规 TraceID。生成 SpanID
SpanID 表现为一个长度为16的字符串,其中每个字符为一个16进制数字,取值范围为:0,1,2,3,4,5,6,7,8,9,a,b,c,d,e,f,例如
00f067aa0ba902b7
。针对每次用户操作,都需要生成新的 SpanID 与之对应,请自行确保 SpanID 的随机性,并注意全零的情况0000000000000000
会被视为不合规 SpanID。说明:
拼接 Traceparent 字段
Traceparent 字段包含4个组成部分,通过
-
进行连接,这4个部分分别是:version:固定为
00
trace-id:生成的 TraceID
parent-id:生成的 SpanID
trace-flags:固定为
01
例如,
00-0af7651916cd43dd8448eb211c80319c-b7ad6b7169203331-01
就是一个合法的 Traceparent 。在 HTTP 请求中添加 Traceparent Header
在发往下游应用 HTTP 请求中,添加名为
traceparent
的 HTTP Header,其值为上一步拼接好的 Traceparent 字段,请注意 Header 名为小写。这样就完成了自定义 TraceID 的全部流程,对于下游接入 APM 的应用,都将使用自定义的 TraceID 标识一条链路。