traceparent 解码器 — W3C Trace Context
不用再数十六进制位。免费在线 traceparent 解码器,全程在浏览器内运行,不上传任何数据。解析 trace ID、span ID、全部 8 个 trace-flags 位,校验 tracestate,并转换为 Datadog、X-Ray、B3 格式。
- 版本
00- Trace ID
4bf92f3577b34da6a3ce929d0e0e4736- Parent ID(span ID)
00f067aa0ba902b7- Trace flags
01
| 位 | 掩码 | 名称 | 状态 |
|---|---|---|---|
| 0 | 0x01 | sampled | 1 |
| 1 | 0x02 | random-trace-id | 0 |
| 2 | 0x04 | reserved | 0 |
| 3 | 0x08 | reserved | 0 |
| 4 | 0x10 | reserved | 0 |
| 5 | 0x20 | reserved | 0 |
| 6 | 0x40 | reserved | 0 |
| 7 | 0x80 | reserved | 0 |
请用按位与来读这些位。拿整个字节和 01 比较,会误报任何同时带有保留位的链路。
- x-datadog-trace-id
11803532876627986230- x-datadog-tags: _dd.p.tid
4bf92f3577b34da6- x-datadog-parent-id
67667974448284343- AWS X-Ray trace ID
1-4bf92f35-77b34da6a3ce929d0e0e4736- b3 (single header)
4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-1- X-B3-TraceId
4bf92f3577b34da6a3ce929d0e0e4736- X-B3-SpanId
00f067aa0ba902b7- X-B3-Sampled
1
Datadog 把 trace ID 的低 64 位当十进制字符串携带,高 64 位以十六进制放在一个标签里。把完整的 128 位当十进制传过去,正是日志里的 trace ID 在界面上查不到的经典原因。
X-Ray 的 ID 内嵌了一个 32 位时间戳;W3C 的 trace ID 根本不携带时间戳。下面的日期只有在这个标识符确实源自 X-Ray 时才有意义。
| # | 键 | 值 | 状态 |
|---|---|---|---|
| 1 | rojo | 00f067aa0ba902b7 | OK |
| 2 | congo | t61rcWkgMzE | OK |
traceparent 格式:字段解剖
| 字段 | 十六进制位数 | 字节数 | 含义 | 非法值 |
|---|---|---|---|---|
| version | 2 | 1 | 格式版本。今天永远是 00;ff 被禁止。 | ff |
| trace-id | 32 | 16 | 端到端标识整条链路。 | 全为 0 |
| parent-id | 16 | 8 | 标识调用方的 span,而不是这个请求。 | 全为 0 |
| trace-flags | 2 | 1 | 一个 8 位字段——逐位来读,别当成布尔值。 | — |
trace-flags 取值:00、01、02 和 03 详解
| 十六进制 | 二进制 | sampled | random-trace-id | 含义 |
|---|---|---|---|---|
| 00 | 00000000 | 0 | 0 | 上游选择不采样——去看调用方,别看自己的服务。 |
| 01 | 00000001 | 1 | 0 | 正常记录。绝大多数时候你看到的就是它。 |
| 02 | 00000010 | 0 | 1 | 声明了随机 trace ID,但未采样。 |
| 03 | 00000011 | 1 | 1 | 已记录,且声明 trace ID 是均匀随机的。 |
bit 0 — 调用方记录了这条链路。为 0 表示它有意选择不记录。
bit 1 — Level 2:trace ID 最右侧 7 字节是均匀随机的。
bit 2-7 — 保留。接收时必须忽略,向外发请求时必须清零。
直接对照 W3C Trace Context 建议标准与 Level 2 候选建议实现,解析器针对规范列出的每一种合法与非法形态都有单元测试覆盖。
什么是 traceparent 请求头?
traceparent 是把一次分布式追踪从一个服务带到下一个服务的 HTTP 请求头。在它被标准化之前,每家追踪厂商都用自己的请求头传递上下文,请求一旦跨系统就在边界上丢了身份。W3C Trace Context 规范用一种刻意做得很小的格式解决了这件事:version-trace-id-parent-id-trace-flags,四个十六进制字段用连字符连接,当前版本总长 55 个字符。
每个字段只干一件事。version 今天永远是 00,ff 被直接禁止。trace-id 是 16 字节,端到端标识整个请求——它在每一跳都不变。parent-id 是 8 字节,标识直接调用方的 span,所以和 trace-id 不同,它每跳都会变。trace-flags 这个字节是误解最集中的地方:因为 01 实在太常见,它看起来像个布尔值,可它是 8 个位。位 0 是 sampled。位 1 由 Trace Context Level 2 引入,是 random-trace-id,用来声明 trace ID 最右侧 7 字节是均匀随机的,下游系统可以据此采样或分片。其余 6 位保留——这正是必须用按位与去读这个字段、而不是做相等比较的原因。
配套的 tracestate 请求头在旁边携带厂商自定义的键值对,上限 32 个成员。这个上限解释了一个让人费解的现象:厂商数据在边缘还在,几跳之后就没了,因为列表一旦超限,中间件就开始丢条目。OpenTelemetry 采用它之后,这个请求头才真正通用起来。本页把这些全部解码——字段、位、tracestate 成员,以及其他传播格式下的等价标识符——并且不向任何地方发送数据。
# The header as it travels on the wire
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
tracestate: rojo=00f067aa0ba902b7,congo=t61rcWkgMzE
# Read the four fields apart
# version 00
# trace-id 4bf92f3577b34da6a3ce929d0e0e4736 (16 bytes, whole request)
# parent-id 00f067aa0ba902b7 (8 bytes, calling span)
# trace-flags 01 (bit 0 set = sampled)
# Send one yourself
$ curl -H 'traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01' \
https://example.com/api 核心功能
每个字段单独拆出、可直接复制
version、trace-id、parent-id 和 trace-flags 各占一行,各有一个复制按钮,把 32 个字符的 trace ID 拿去查询只要点一下,不用小心翼翼地拖选。
trace-flags 按 8 个位来读
标志字节被展开成全部 8 个位置并标出十六进制掩码。位 0 是 sampled,位 1 是 Level 2 的 random-trace-id 标志,保留位也会显示出来,而不是被悄悄丢掉。
Datadog、X-Ray 与 B3 转换
低 64 位的十进制 Datadog trace ID、随它一起传递的高 64 位标签、X-Ray 的 1-{8}-{24} 形式,以及 B3 的单请求头和多请求头两种布局——全部用 BigInt 计算,不会溢出。
给的是诊断,不只是判决
全零 trace ID 会被解释为追踪从未初始化;sampled 位为 0 会被解释为上游做出的决定。分清眼前是这两者中的哪一种,往往就是整场排查的全部。
tracestate 与 32 个成员的上限
成员会逐条列出,键和值分别校验,并对照规范的上限实时计数——正是这个上限,解释了厂商数据为什么在下游几跳之后就消失。
数据不离开你的浏览器
解析只用普通字符串和 BigInt 运算,零依赖、零网络请求,并由每次构建运行的自动化契约测试验证。复制链接用的是 URL 片段,而片段永远不会被发送。
traceparent 示例解码
规范自带的示例,逐字段解码
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
version 00 · trace-id 4bf92f3577b34da6a3ce929d0e0e4736 · parent-id 00f067aa0ba902b7 · trace-flags 01 (sampled)
四个用连字符分隔的字段,version 00 下总长 55 个字符。trace-id 标识整个请求,贯穿它经过的每一个服务;parent-id——通常叫 span ID——只标识直接调用方,所以它每跳都会变,而 trace-id 不会。结尾的 01 是一个完整的字节,不是布尔值:位 0 被置起,说明调用方记录了这条链路。
trace-flags 00——调用方决定不记录
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-00
有效 header · sampled 位为 0
这个请求头完全有效,而这正是关键。sampled 位被清零是上游下达的指令,不是你服务的缺陷:调用你的那一方跑过了自己的采样器,选择不记录。在这种情况下翻自己的配置找丢失的 span,几个小时就没了。该问的问题是:哪个服务在调用你、带着 parent span、并且决定不采样这条链路。
全零 trace ID 意味着追踪从未开始
00-00000000000000000000000000000000-00f067aa0ba902b7-01
无效 —— trace-id 全为 0
规范把全零 trace-id 定义为非法值,并要求接收方忽略整个 traceparent。值得知道的是它在实践中意味着什么:不是“一条还没有数据的链路”,而是某个 SDK 根本没初始化,或者某个中间件注入了占位请求头。全零 parent-id 适用同一条规则。
同一个 trace ID 在 Datadog 的格式下
00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
x-datadog-trace-id 11803532876627986230 · _dd.p.tid 4bf92f3577b34da6
Datadog 把 128 位 trace ID 的低 64 位当作十进制字符串携带,高 64 位则以十六进制放在另一个标签里。把完整的 128 位当十进制传进去,得到的数字什么都匹配不上——这正是各家 tracer 的 issue 里反复出现这个转换问题的原因。这里的低半部分是 a3ce929d0e0e4736,而 64 位超出了 JavaScript number 能表示的范围,所以本页用 BigInt 做这段算术。
如何使用 traceparent 解码器
- 1
粘贴 traceparent 请求头
直接放入原始的请求头值,例如 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01。解码随输入进行,不需要按任何按钮。
- 2
分开读四个字段
version、trace-id、parent-id 和 trace-flags 各占一行,每行都带复制按钮,你可以只把 trace ID 拿去查询,而不用手动选中 32 个字符。
- 3
逐位检查标志位
trace-flags 字节被展开成全部 8 个位并标出掩码,sampled 和 Level 2 的 random-trace-id 标志都单独可见,不再藏在一个两字符的值里。
- 4
转换成后端要的格式
下方会生成 Datadog、AWS X-Ray 以及 B3 的两种形式,包括 Datadog 需要的低 64 位十进制 trace ID,和随它一起传递的高 64 位标签。
- 5
加上 tracestate 并分享结果
粘贴 tracestate 请求头即可逐条列出成员、单独校验,并对照 32 个成员的上限计数;然后用复制链接把当前状态原样装进一个 URL,丢进工单里。
traceparent 常见错误
拿整个标志字节和 01 比较
这是把一个 8 位字段当成了枚举。一条既被采样、又带 Level 2 random-trace-id 标志的链路,flags 是 03,相等比较会把它报成未采样。
if (traceFlags === 0x01) { record(); } if (traceFlags & 0x01) { record(); } 把 128 位整体转成一个十进制数
Datadog 期望低 64 位是十进制,高 64 位以十六进制放在另一个标签里。把完整值当成一个十进制数传过去,得到的标识符什么都匹配不上。
x-datadog-trace-id: 100985939111033328018442752961257817910
x-datadog-trace-id: 11803532876627986230 x-datadog-tags: _dd.p.tid=4bf92f3577b34da6
拒绝一切非 00 的版本
规范要求解析器从更高的版本里读出自己认识的部分,并容忍多余的尾部字段。直接拒绝会重开一条链路,把跨边界的关联打断。
if (version !== '00') throw new Error('bad traceparent'); if (version !== '00' && header.length >= 55) { /* parse the known prefix */ } 输出大写十六进制
语法只接受小写。大写的 trace ID 携带的值是对的,却仍会被符合规范的接收方拒绝,这让它成了一个格外难用肉眼发现的 bug。
traceparent: 00-4BF92F3577B34DA6A3CE929D0E0E4736-00F067AA0BA902B7-01
traceparent: 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01
traceparent 解码器能帮你做什么
- 弄清一条链路为什么没有 span
- 粘贴进来的请求头,读它的 sampled 位。如果是 0,这条链路本来就不会被记录,答案在调用方那边,不在你的埋点上——分清这一点,能省下大量核查自家采样配置的时间。
- 找到后端查不到的那条链路
- 从应用日志里复制出来的 trace ID 在 Datadog 里查不到,通常是格式的问题。在这里转换一下,就能看到 API 期望的低 64 位十进制标识符,以及必须随它一起提供的高 64 位标签。
- 验证网关注入的请求头
- 代理和服务网格会在入口处生成追踪上下文。把实际收到的内容粘进来,先确认长度、小写十六进制和非零标识符,再去假设问题出在下游。
- 手工复现一条生产链路
- 拿一个真实请求的请求头,对预发环境的端点重放,跟着同一条链路走一遍。用 curl 命令生成器构造请求,把请求头直接粘进去即可。
- 向团队讲清楚 trace context
- 本页的字段解剖表和 trace-flags 表是可以直接指着讲的静态参考资料,预设按钮则能演示每一种失败形态,不必真的把哪个服务弄坏来制造现场。
W3C Trace Context 校验器的工作原理
- 四字段语法
- version "-" trace-id "-" parent-id "-" trace-flags,全部为小写十六进制。version 2 位,trace-id 32 位,parent-id 16 位,trace-flags 2 位——52 个十六进制字符加 3 个连字符,version 00 下恰好 55 个字符。大写十六进制会让请求头非法,哪怕值本身看着没错;而全零的 trace-id 和全零的 parent-id 都是明确非法,而不是「为空」。
- trace-flags 是位字段
- 位 0(掩码 0x01)是 sampled:置起表示调用方可能记录了追踪数据。位 1(掩码 0x02)由 Level 2 引入,是 random-trace-id:置起时,trace-id 至少最右侧 7 字节必须是均匀分布地随机选出的,下游系统因此可以基于它们采样或分片。位 2 到位 7 保留,接收时必须忽略,向外发请求时必须清零。正因为保留位可能出现,这个字段必须用按位与来判断——拿它和 0x01 做相等比较,会把一条同时带有保留位的已采样链路误报掉。
- 对未来版本的前向兼容
- version 今天是 00,ff 被禁止,但一个把其他值一律拒绝的解析器是错的。规范要求接收方在版本更高、且请求头长度不短于已知格式时尝试解析,读出自己认识的字段并容忍多余的尾部数据,而不是重新开一条链路。本解码器遵循这条规则:更高的版本能解析成功,并被标记为警告而不是错误。
- 生产中真会咬人的 tracestate 限制
- 最多 32 个 list-member——这是一条硬性的语法边界,列表更长时整个 header 就是非法的,接收方会直接丢弃。每个键最长 256 个字符,以小写字母或数字开头;从 Level 2 起,@ 只是一个普通的键字符,不再是租户分隔符。每个值是 1 到 256 个可打印 ASCII 字符,不能含逗号或等号。重复的键非法;而空的 list-member 是规范明确允许的——中间件删掉某个条目后留下的尾随逗号,仍然是一个合法的 header。另有一条独立的约定:厂商应当传播至少 512 个字符的合并后 header;当需要裁剪以塞进这个预算时,应当先丢掉超过 128 个字符的条目——所以话多的厂商,数据总比话少的先消失。
Trace Context 最佳实践
- 用按位与来判断标志位
- 写 flags & 0x01,不要写 flags == 0x01。8 个位里有 6 个留给未来使用,只要其中任何一个开始出现在真实流量里,相等比较就会开始误报已采样的链路。
- 把全零 ID 当成管道坏了
- 它不是一个可以容忍的空值。拒绝这个请求头,然后去找那个没能初始化 tracer、或者在注入占位值的组件。
- sampled 位为 0 时往上游看
- 基于父级的采样器会传播调用方的决定。如果链路缺失,先找出是哪个服务带着关掉采样的 parent span 在调你,再去审查自己的配置。
- 让 tracestate 保持简短
- 32 个成员的上限是一条硬性的语法边界——一旦超出,整个 header 就是非法的。另外,合并后的 header 只有 512 个字符能保证被传播,裁剪时会先丢掉超过 128 个字符的条目。任何你希望能撑过一条长调用链的数据,都不该放在 tracestate 里。
- 永远不要把 trace ID 当成 JavaScript number 打日志
- 128 位的 trace ID,乃至 64 位的 Datadog 标识符,都超过了 Number.MAX_SAFE_INTEGER。把它们当字符串保存,需要做运算时用 BigInt 转换,否则末尾几位会被悄悄改掉。
traceparent 解码器常见问题
traceparent 请求头是什么?
traceparent 的 trace-flags 00 是什么意思?
trace-flags 的 01、02 和 03 有什么区别?
为什么我的 trace ID 全是 0?
怎么把 W3C 的 trace ID 转成 Datadog 的 trace ID?
traceparent 里含有时间戳吗?
我粘贴的请求头会被上传到哪里吗?
这个解码器能离线使用吗?
相关工具
查看所有工具 →cURL 命令生成器与构建工具
网络与 API
在浏览器中构建 curl 命令——设置请求方法、请求头、认证与请求体,即刻获得可复制的命令。支持 Bearer、POST JSON、文件上传预设。免费、隐私安全、无需注册。
htpasswd 生成器 — bcrypt、Apache MD5 (apr1) 与 Basic Auth
网络与 API
在线生成 htpasswd 条目,支持 bcrypt、Apache MD5 (apr1)、SHA-1 等算法,并输出 Apache、nginx 和 Docker 的即用配置。100% 在浏览器中运行,密码不上传。
Open Graph 与 Meta 标签生成器
网络与 API
生成 Open Graph、Twitter Card 与 SEO meta 标签,并实时预览在 Google、Facebook、X 上的分享效果。100% 免费、纯浏览器运行、无需注册——一键复制代码即可粘贴使用。
Nginx location 匹配规则测试器 — 为何是这个块
网络与 API
看清哪个 nginx location 块生效,其他块各自输在哪一步。免费在线 location 匹配规则与优先级测试器,支持 =、^~、~、~*,全程浏览器内运行。
AES 解密工具 — 兼容 OpenSSL 与 CryptoJS
安全工具
在线解密 AES —— 支持 GCM/CBC/CTR、口令或原始密钥,自动识别 OpenSSL 与 CryptoJS 的 "U2FsdGVkX1" 格式。100% 浏览器本地运行,密钥永不离开页面。
AES 加密工具 — GCM、CBC 与 CTR 模式
安全工具
免费在线 AES 加密工具 — 支持 AES-128/192/256、GCM/CBC/CTR 模式,可用口令(PBKDF2)或原始密钥。100% 浏览器本地运行,不上传任何数据。