如何命名你的 Span 属性
欢迎来到我们关于 OpenTelemetry 命名最佳实践系列文章的第二篇。在我们上一篇文章中,我们探讨了如何使用 {动词} {名词} 模式来命名 Span。今天,我们将深入探讨 Span 属性——这些丰富的上下文数据将您的追踪从简单的操作日志转变为强大的调试和分析工具。
本指南面向以下开发者:
- 使用自定义 Span 和属性对自己的应用程序进行插桩
- 丰富遥测数据,使其超越自动插桩所提供的功能
- 创建供他人插桩的库
您所做的属性命名决策直接影响到您的可观测性数据的可用性和可维护性。让我们把它们做好。
从语义约定开始
以下是最重要的规则,它将为您节省时间并提高互操作性:如果 OpenTelemetry 语义约定存在并且语义与您的用例匹配,请使用它。
这不仅仅是为了方便——而是为了构建能够与更广泛的 OpenTelemetry 生态系统无缝集成的遥测数据。当您使用标准化的属性名称时,您的数据将自动与现有的仪表板、告警规则和分析工具配合使用。
当语义匹配时,请遵循约定
| 您的需求 | 使用此语义约定 | 原因 |
|---|---|---|
| HTTP 请求方法 | http.request.method | 所有 HTTP 插桩都标准化了 |
| 数据库集合名称 | db.collection.name | 与数据库监控工具配合使用 |
| 服务识别 | service.name | 服务关联的核心资源属性 |
| 网络对等地址 | network.peer.address | 网络级别调试的标准 |
| 错误分类 | error.type | 实现一致的错误分析 |
关键原则是语义匹配优先于命名偏好。即使您更喜欢 database_table 而不是 db.collection.name,当语义约定能准确描述您的数据时,也请使用它。
当语义不匹配时,不要强行套用
抵制滥用语义约定的诱惑
| 不要这样做 | 为什么是错误的 |
|---|---|
使用 db.collection.name 来表示文件名 | 文件和数据库集合是不同的概念 |
使用 http.request.method 来表示业务操作 | “approve_payment”不是 HTTP 方法 |
使用 user.id 来表示交易 ID | 用户和交易是不同的实体 |
滥用语义约定比创建自定义属性更糟糕——它会造成混淆并破坏期望标准语义的工具。
黄金法则:领域优先,绝不公司优先
当您需要超出语义约定范围的自定义属性时,最关键的原则是:从领域或技术开始,绝不以您的公司或应用程序名称开始。
这个原则看似显而易见,但在整个行业中却被一再违反。以下是它为何重要以及如何做对。
为什么公司优先命名会失败
| 糟糕的属性名称 | 问题 |
|---|---|
og.user.id | 公司前缀污染了全局命名空间 |
myapp.request.size | 特定于应用程序,不可重用 |
acme.inventory.count | 难以与标准属性进行关联 |
shopify_store.product.sku | 不必要地将概念与某个供应商绑定 |
这些方法创建的属性是:
- 难以跨团队和组织进行关联
- 在不同上下文中无法重用
- 供应商锁定且不灵活
- 与 OpenTelemetry 的互操作性目标不一致
领域优先的成功案例
| 良好的属性名称 | 为何有效 |
|---|---|
user.id | 通用概念,供应商中立 |
request.size | 可在应用程序中重用 |
inventory.count | 清晰、特定于领域的概念 |
product.sku | 标准电子商务术语 |
workflow.step.name | 通用的流程管理概念 |
这种方法创建的属性是普遍可理解的,可供面临类似问题的其他人重用,并且是面向未来的。
理解结构:点号和下划线
OpenTelemetry 属性名称遵循特定的结构模式,该模式在可读性和一致性之间取得了平衡。理解这种模式有助于您创建与标准语义约定自然融合的属性。
使用点号进行分层分隔
点号 (.) 分隔分层组件,遵循模式:{domain}.{component}.{property}
来自语义约定的示例
http.request.method- HTTP 领域,请求组件,方法属性db.collection.name- 数据库领域,集合组件,名称属性service.instance.id- 服务领域,实例组件,ID 属性
使用下划线分隔多词组件
当单个组件包含多个单词时,请使用下划线 (_)
http.response.status_code- “status_code”是一个逻辑组件system.memory.usage_percent- “usage_percent”是一个测量概念
需要时创建更深层级结构
当可以增加清晰度时,您可以进一步嵌套
http.request.body.sizek8s.pod.label.{key}messaging.kafka.message.key
每个级别都应代表有意义的概念边界。
保留的命名空间:您绝不能使用
某些命名空间被严格保留,违反这些规则可能会破坏您的遥测数据。
otel.* 命名空间是禁区
otel.* 前缀仅保留给 OpenTelemetry 规范本身使用。它用于在本地不支持的遥测格式中表达 OpenTelemetry 概念。
保留的 otel.* 属性包括:
otel.scope.name- 插桩范围名称otel.status_code- Span 状态码otel.span.sampling_result- 采样决策
切勿创建以 otel. 开头的属性。此命名空间的所有添加都必须作为 OpenTelemetry 规范的一部分获得批准。
其他保留属性
该规范还保留了以下特定属性名称:
error.typeexception.message,exception.stacktrace,exception.typeserver.address,server.portservice.nametelemetry.sdk.language,telemetry.sdk.name,telemetry.sdk.versionurl.scheme
语义约定模式
培养良好的属性命名直觉的最佳方法是研究 OpenTelemetry 的语义约定。这些约定代表了可观测性专家数千小时的设计工作。
领域组织模式
注意语义约定是如何围绕清晰的领域进行组织的
基础设施领域
service.*- 服务标识和元数据host.*- 主机/机器信息container.*- 容器运行时信息process.*- 操作系统进程
通信领域
http.*- HTTP 协议细节network.*- 网络层信息rpc.*- 远程过程调用属性messaging.*- 消息队列系统
数据领域
db.*- 数据库操作url.*- URL 组件
通用属性模式
在所有领域中,通用属性都出现了持续的模式
身份属性
.name- 人类可读标识符(service.name,container.name).id- 系统标识符(container.id,process.pid).version- 版本信息(service.version).type- 分类(messaging.operation.type,error.type)
网络属性
.address- 网络地址(server.address,client.address).port- 端口号(server.port,client.port)
测量属性
.size- 字节测量(http.request.body.size).count- 数量(messaging.batch.message_count).duration- 时间测量(http.server.request.duration)
在创建自定义领域时,请遵循相同的模式。对于库存管理,请考虑:
inventory.item.nameinventory.item.idinventory.location.addressinventory.batch.count
安全地创建自定义领域
有时您的业务逻辑需要现有语义约定之外的属性。这是正常的——OpenTelemetry 无法涵盖所有可能的业务领域。
安全自定义领域的指南
- 选择描述性、通用的名称,以便他人可以重用。
- 避免在领域名称中使用公司特定的术语。
- 遵循语义约定建立的层级模式。
- 考虑您的领域是否可能成为未来的语义约定.
设计良好的自定义属性示例
| 领域 | 良好的属性 | 为何有效 |
|---|---|---|
| 业务 | payment.method, order.status | 清晰、可重用的业务概念 |
| 物流 | inventory.location, shipment.carrier | 特定于领域但可转移 |
| Process | workflow.step.name, approval.status | 通用的流程管理 |
| 内容 | document.format, media.codec | 通用的内容概念 |
罕见的例外:何时前缀才有意义
在极少数情况下,您可能需要公司或应用程序前缀。这通常发生在您的自定义属性可能与分布式系统中其他来源的属性发生冲突时。
考虑前缀的情况:
- 您的属性可能与分布式系统中的供应商属性发生冲突。
- 您正在插桩真正特定于公司的专有技术。
- 您正在捕获不应泛化的内部实现细节。
对于大多数业务逻辑属性,请坚持使用领域优先命名。
您的行动计划
良好地命名 Span 属性可以创建可维护、可互操作且在您的组织中有价值的遥测数据。这是您的路线图:
- 始终先检查语义约定——当语义匹配时使用它们。
- 以领域为先,绝不以公司为先——创建供应商中立的属性。
- 尊重保留的命名空间——特别是避免
otel.*。 - 遵循层级模式——一致地使用点号和下划线。
- 为可重用性而构建——超越您当前的需求。
遵循这些原则,您不仅解决了今天的插桩挑战——您还在为建立一个更一致、更具互操作性的可观测性生态系统做出贡献,使每个人受益。
在我们这个系列的下一篇文章中,我们将把重点从 Span 转移到指标——探讨如何命名那些告诉我们系统性能的量化测量,以及为什么分离和领域优先思维的相同原则适用于最重要的数字。