Skip to content

traceparent 解码器 — W3C Trace Context

不用再数十六进制位。免费在线 traceparent 解码器,全程在浏览器内运行,不上传任何数据。解析 trace ID、span ID、全部 8 个 trace-flags 位,校验 tracestate,并转换为 Datadog、X-Ray、B3 格式。

无追踪 浏览器中运行 免费
全部在你的浏览器里本地解码——你粘贴的请求头不会离开这台设备。打开 Network 面板看它始终没有请求,或者干脆断网使用。
试试示例
字段拆解
版本
00
Trace ID
4bf92f3577b34da6a3ce929d0e0e4736
Parent ID(span ID)
00f067aa0ba902b7
Trace flags
01
trace-flags 逐位解析
掩码 名称 状态
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 时才有意义。

tracestate 成员 2/32
# 状态
1 rojo 00f067aa0ba902b7 OK
2 congo t61rcWkgMzE OK

traceparent 格式:字段解剖

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 详解

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 — 保留。接收时必须忽略,向外发请求时必须清零。

本页的字段宽度、非法值、标志位语义以及 tracestate 各项限制,均以已发布的规范原文核对,而非二手文章。 — Go Tools 工程团队 · 2026年7月22日

直接对照 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. 1

    粘贴 traceparent 请求头

    直接放入原始的请求头值,例如 00-4bf92f3577b34da6a3ce929d0e0e4736-00f067aa0ba902b7-01。解码随输入进行,不需要按任何按钮。

  2. 2

    分开读四个字段

    version、trace-id、parent-id 和 trace-flags 各占一行,每行都带复制按钮,你可以只把 trace ID 拿去查询,而不用手动选中 32 个字符。

  3. 3

    逐位检查标志位

    trace-flags 字节被展开成全部 8 个位并标出掩码,sampled 和 Level 2 的 random-trace-id 标志都单独可见,不再藏在一个两字符的值里。

  4. 4

    转换成后端要的格式

    下方会生成 Datadog、AWS X-Ray 以及 B3 的两种形式,包括 Datadog 需要的低 64 位十进制 trace ID,和随它一起传递的高 64 位标签。

  5. 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 请求头是什么?
它是把一次分布式追踪跨服务边界传递下去的那一个 HTTP 请求头,由 W3C 标准化,好让不同厂商的工具能跟踪同一个请求。它包含四个用连字符分隔的字段——version、trace-id、parent-id 和 trace-flags——在当前版本下总长恰好 55 个字符。现在所有主流追踪系统都支持它,正因如此,一个请求才能从边缘代理一路穿过六七个服务而保持可追踪,不需要每一跳都统一到同一家厂商。完整语法定义见 W3C Trace Context 建议标准
traceparent 的 trace-flags 00 是什么意思?
它表示调用方明确决定不记录这条链路。sampled 是 trace-flags 字节的位 0;当它为 0 时,说明上游的采样器评估过这个请求,选择了不记录。这是整个请求头里最容易被误读的值,因为它看起来像故障,实际上是一个决定。如果 span 缺失,有用的问题不是「我的服务哪里坏了」,而是「哪个上游服务给我发来了关掉采样的 parent span」——基于父级的采样器会把这个选择一路传播到所有下游。
trace-flags 的 01、02 和 03 有什么区别?
trace-flags 是一个 8 位字段,所以这些值是位的组合,不是枚举。01 只置起位 0:这条链路被采样。02 只置起位 1,即 Level 2 的 random-trace-id 标志,它声明 trace ID 至少最右侧 7 字节是均匀随机生成的——下游系统于是可以安全地基于这几个字节采样或分片。03 两个位都置起。因为它是位字段,你必须用按位与来判断;拿整个字节和 01 比较,会把任何同时带有保留位的链路误报成未采样,而保留位恰恰是未来版本会开始启用的东西。
为什么我的 trace ID 全是 0?
因为追踪从未初始化,而不是因为链路存在但还没有数据。规范把全零 trace-id 列为非法值,并要求接收方忽略整个请求头,所以下游不会有任何东西关联到它。实践中它来自没能启动的 SDK、手工拼出来的请求头,或者在拿不到真实上下文时插入占位值的中间件。全零的 parent-id,也就是 0000000000000000,因为同样的原因非法。
怎么把 W3C 的 trace ID 转成 Datadog 的 trace ID?
取低 64 位——也就是右边 16 个十六进制字符——渲染成十进制字符串,这才是 x-datadog-trace-id 该放的值。高 64 位保持十六进制,单独放在 _dd.p.tid 标签里传递。parent-id 则整体转成十进制。把高低两半搞反,或者把 128 位整体转成一个十进制数,得到的标识符在界面里什么都匹配不上,这也是各家 tracer 的 issue 里反复出现这个问题的原因。本页会替你完成拆分;如果你想在任意数值上研究底层的十六进制运算,进制转换器负责通用的进制换算,而本页只专注于追踪标识符。
traceparent 里含有时间戳吗?
没有——这一点常把人绊住,因为别的追踪标识符确实带时间。W3C 的 trace-id 是 16 个不透明字节,没有内嵌时间。相比之下,AWS X-Ray 的 trace ID 是 1-{8 位十六进制}-{24 位十六进制},其中前 8 个十六进制字符是以 epoch 秒表示的创建时间,所以两种格式互转只是搬动字节,无法凭空造出一个原本不存在的时间戳。如果你需要的是能按时间排序的标识符,那是 UUIDv7ULID 的活。
我粘贴的请求头会被上传到哪里吗?
不会。每个字段都在你的浏览器里用普通字符串和 BigInt 运算解析——没有服务器调用,不记录你输入的内容,也不留存任何东西。这件事在这里比在多数工具上更要紧,因为取自生产请求的 traceparent 会直接指向你可观测性后端里的真实流量。你不必信我们的一面之词:打开浏览器开发者工具,边输入边看 Network 面板始终没有请求,或者干脆断网继续解码。「不发起任何外部请求」这一点还由每次构建都会运行的自动化契约测试强制保证,不会悄悄退化。
这个解码器能离线使用吗?
可以。页面是静态的,解码器只有几 KB 的 JavaScript,零依赖,所以一旦加载完成,你就可以断网——或者在粘贴任何内容之前先开飞行模式——它照样工作。如果你处理的是敏感环境里的请求头,值得按这个顺序来:先加载页面,再断网,然后粘贴。复制链接按钮把状态编码在 URL 的 # 之后的片段里,而片段同样不会被发送到服务器。

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% 浏览器本地运行,不上传任何数据。