3. Tag 命名规范总则

Span Tag 是 Jaeger 可观测性数据的核心元数据载体。命名规范直接影响数据检索效率、自动化分析准确度以及跨团队协作成本。本章定义 Tag 命名的四项硬性总则:命名风格统一、语义清晰、避免歧义、禁止使用保留关键字。

核心原则:Tag 命名是“写一次,读千次”的契约。命名阶段多花 1 分钟,可节省后续排障、告警、自动化分析数小时。

3.1 命名风格:统一使用小写蛇形(snake_case)

Jaeger 生态中,Span Tag 的 Key 必须采用小写蛇形(snake_case)风格。禁止使用驼峰(camelCase)、帕斯卡(PascalCase)、短横线(kebab-case)或混合风格。

风格 示例 是否允许 原因
小写蛇形 http.status_code ✅ 强制 Jaeger UI 默认排序、Prometheus 标签兼容、OpenTelemetry 语义约定
驼峰 httpStatusCode ❌ 禁止 大小写敏感环境下易混淆,与 Jaeger 内置标签不一致
帕斯卡 HttpStatusCode ❌ 禁止 与 Go/Java 结构体字段命名冲突,降低可读性
短横线 http-status-code ❌ 禁止 部分查询引擎将短横线解析为减号,导致语法错误
混合风格 http_StatusCode ❌ 禁止 无规律可循,自动化工具无法统一处理
常见陷阱:部分团队在微服务内部使用驼峰,在公共 API 层使用蛇形,导致同一 Trace 内 Tag 命名风格分裂。Span Tag 必须全局统一,不区分内部/外部。
命名风格决策流程 Tag Key 命名 风格统一? 是 通过 → 进入语义检查 否 拒绝合并 → 强制整改 仅允许小写蛇形 snake_case

3.2 语义清晰性:自描述、无缩写、领域对齐

Tag Key 必须做到“见名知义”,禁止使用无上下文含义的缩写、单字母、内部代号。语义清晰性包含三个层次:

  1. 自描述:不依赖外部文档即可理解 Tag 含义。例如 db.statement 优于 sql,http.request.method 优于 method。
  2. 无歧义缩写:仅允许业界通用缩写(如 http、db、mq、rpc),禁止团队内部缩写(如 ord_svc 应写为 order.service)。
  3. 领域对齐:Tag 命名应与业务领域术语一致。例如支付域使用 payment.amount,而非 price 或 money。
反例(不清晰) 正例(清晰) 改进说明
uid user.id 明确标识用户 ID,避免与订单 ID 混淆
ts timestamp.start 指明时间戳类型(开始/结束/创建)
err error.message 区分错误码、错误消息、错误堆栈
svc service.name 与 Jaeger 内置 service.name 对齐
cnt retry.count 明确计数对象(重试次数/请求次数)
最佳实践:命名时遵循“领域.子域.具体含义”三层结构。例如 cache.redis.hit、queue.kafka.partition、storage.s3.bucket。层级用点号分隔,最多不超过 4 层。

3.3 避免歧义:消除同形异义与上下文依赖

歧义是 Tag 命名中最隐蔽的缺陷。以下三类歧义必须规避:

  • 同形异义:同一个 Tag Key 在不同服务中含义不同。例如 status 在 HTTP 服务中表示状态码,在订单服务中表示订单状态。解决方案:加前缀区分,如 http.status_code、order.status。
  • 单位歧义:数值型 Tag 必须标注单位。例如 duration_ms 而非 duration,size_bytes 而非 size。
  • 布尔歧义:布尔 Tag 必须使用正向语义。例如 is_cached 优于 not_cached,has_error 优于 no_error。
歧义 Tag 对比示例 ❌ 歧义 Tag • status → HTTP 状态码?订单状态? • duration → 毫秒?秒?微秒? • no_error → 双重否定,易误解 • count → 重试次数?请求次数? • id → 用户 ID?订单 ID?Trace ID? ✅ 清晰 Tag • http.status_code → 明确 HTTP 层 • duration_ms → 单位明确 • has_error → 正向布尔语义 • retry.count → 前缀限定范围 • user.id → 领域前缀消除歧义

3.4 禁止使用保留关键字

Jaeger 和 OpenTelemetry 定义了一系列保留关键字,用于 Span 的内置属性。自定义 Tag 不得与这些关键字冲突,否则会导致数据覆盖、查询异常或 UI 显示错乱。

保留关键字 所属规范 用途 冲突后果
span.kind Jaeger / OpenTelemetry Span 类型(client/server/internal) Span 类型被覆盖,UI 显示异常
span.status Jaeger / OpenTelemetry Span 状态(OK/ERROR/UNSET) 错误状态无法正确聚合
error Jaeger 布尔标记是否发生错误 Jaeger UI 错误筛选失效
service.name OpenTelemetry 服务名称标识 服务拓扑图错乱
trace_id Jaeger / OpenTelemetry Trace 唯一标识 查询索引冲突
span_id Jaeger / OpenTelemetry Span 唯一标识 Span 关联关系断裂
parent_span_id Jaeger / OpenTelemetry 父 Span 标识 Trace 树结构损坏
start_time Jaeger Span 开始时间 时间轴显示异常
duration Jaeger Span 持续时间 耗时统计错误
硬性规则:自定义 Tag 禁止以 span.、trace.、service. 为前缀。如果确实需要表达类似语义,使用其他前缀替代,例如 custom.span.type 而非 span.kind。

3.5 命名规范总则速查表

规则 要求 示例(正确) 示例(错误)
命名风格 小写蛇形 snake_case http.request.method httpRequestMethod
语义清晰 自描述 + 领域前缀 db.redis.cache_hit hit
避免歧义 标注单位 + 正向布尔 timeout_ms、is_retry timeout、no_retry
保留关键字 禁止使用内置关键字 custom.error_code error
层级深度 点号分隔,最多 4 层 storage.s3.object.size a.b.c.d.e
字符集 仅小写字母、数字、点号、下划线 http.status_code_2xx http-status-code
自动化检查建议:在 CI/CD 流水线中集成 Tag 命名规范检查工具,对每个新增或修改的 Span Tag 进行正则校验。规则示例:^[a-z][a-z0-9_]*(\.[a-z][a-z0-9_]*){0,3}$,并排除保留关键字列表。