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 必须全局统一,不区分内部/外部。
3.2 语义清晰性:自描述、无缩写、领域对齐
Tag Key 必须做到“见名知义”,禁止使用无上下文含义的缩写、单字母、内部代号。语义清晰性包含三个层次:
- 自描述:不依赖外部文档即可理解 Tag 含义。例如
db.statement优于sql,http.request.method优于method。 - 无歧义缩写:仅允许业界通用缩写(如
http、db、mq、rpc),禁止团队内部缩写(如ord_svc应写为order.service)。 - 领域对齐: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。
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}$,并排除保留关键字列表。