【免费下载链接】semantic-conventions
Defines standards for generating consistent, accessible telemetry across a variety of domains
semantic-conventions 是 OpenTelemetry 官方仓库,定义了跨领域统一、可访问的遥测标准。其中 docs/db/ 模块专门规定了数据库 Span 语义约定:你的每次数据库调用应当携带哪些属性、Span 名字该叫什么、旧版实验约定如何平滑迁移到稳定版。读完本文,你无需通读规范原文,就能看懂并生成"开箱即懂"的数据库遥测。
一、为什么需要数据库 Span 约定
没有统一约定时,同一个 Redis 调用在不同应用里可能记录成 db.statement、command、query……排查问题时人肉翻译,后端聚合更是灾难。
semantic-conventions 的做法是:给每个遥测信号(Span、Metrics、Logs)定义标准化的属性键 + 取值规则 + 稳定性等级(stable / development)。数据库部分的入口文档是 docs/db/README.md,它把约定拆成三类:
| 信号 | 文档 | 作用 |
|---|---|---|
| Spans | database-spans.md | 描述一次数据库客户端调用 |
| Metrics | database-metrics.md | 操作耗时、连接池等指标 |
| Logs | database-exceptions.md | 数据库异常记录 |
属性定义的可信来源是机器可读的 YAML:model/db/registry.yaml(现行)与 model/db/deprecated/registry-deprecated.yaml(已废弃属性),文档表格由它们自动生成,保证"文档即源码"。
二、一次数据库调用如何变成 Span
按约定,数据库客户端 Span 应当:
- Span Kind:通常为
CLIENT(内存数据库可用INTERNAL) - Span 状态:遵循 Recording Errors 规则,失败时记录
error.type - Span 时长:覆盖调用方观察到的完整逻辑操作,包含客户端内部的重试
- Span 命名:按优先级逐级回退 👇
{db.query.summary} ← 有查询摘要时优先(推荐)
{db.operation.name} {target} ← 无摘要时:操作名 + 目标
{target} ← 再退化为目标本身
{db.system.name} ← 最后兜底
{target} 依次取 db.collection.name(表/集合)、db.stored_procedure.name(存储过程)、db.namespace(库名)、server.address(+端口)。例如一条查询匿名表的 SQL,Span 名就是 SELECT。
三、核心属性速查:看懂任何数据库 Span
| 属性 | 级别 | 含义 | 示例 |
|---|---|---|---|
db.system.name | Required | DBMS 产品标识 | mysql、redis |
db.namespace | 条件必填 | 数据库名(多段用 \| 连接) | customers |
db.collection.name | 条件必填 | 表/集合名 | public.users |
db.operation.name | 条件必填 | 操作或命令名 | SELECT、HMSET |
db.query.text | Recommended | 执行中的查询(需脱敏) | SELECT * FROM orders WHERE id = ? |
db.query.summary | Recommended | 低基数查询摘要 | SELECT orders |
db.stored_procedure.name | Recommended | 存储过程名 | GetCustomer |
db.response.status_code | 条件必填 | 数据库返回状态码 | 08P01、ORA-17002 |
error.type | 失败时必填 | 错误类别 | timeout |
server.address / server.port | Recommended | 客户端配置中的数据库地址/端口 | shopdb.example.com / 3306 |
db.operation.batch.size | Recommended | 批量操作中的操作数 | 3 |
db.query.parameter.<key> | Opt-In | 查询参数值(默认关闭,防 PII 泄露) | — |
一个真实的 MySQL Span 长这样(示例来自 docs/db/sql.md):
| Key | Value |
|---|---|
| Span name | "SELECT orders" |
db.namespace | "ShopDb" |
db.system.name | "mysql" |
server.address | "shopdb.example.com" |
server.port | 3306 |
db.query.text | "SELECT * FROM orders WHERE order_id = 'o4711'" |
💡 两个容易混淆的属性:
db.query.text描述具体这一条查询,可能很高基数;db.query.summary是查询族的分组键,形如{operation} {target}(如INSERT shipping_details SELECT orders),适合做指标属性和 Span 名,长度截断到 255 字符。
安全脱敏规则(详见 database-spans.md 的 Sanitization 章节):非参数化 SQL 默认只有在把字面量全部替换为 ? 后才可采集;参数化 SQL 的静态部分默认采集,参数值(db.query.parameter.<key>)默认不采集,由运维按隐私策略开启。
四、server.address 怎么填才不踩坑
server.address 应当是客户端配置里写死的地址,而不是本次操作实际连上的那台节点——客户端切换主从、发现新拓扑时,该值保持不变。实际接触的节点另记到 network.peer.address。
下图直观展示了"逻辑客户端 → 逻辑服务器"的地址归属思想(同一原则适用于数据库):
当数据库通过中间层(代理、哨兵、注册中心)访问时,server.address 应指向中间层之后配置的那台数据库地址:
多端点写法:主机名/ IP 用逗号分隔(无空格),默认端口省略,IPv6 带端口须用方括号,最多记录前 5 个端点。完整示例表见 database-spans.md。
五、识别数据库:db.system.name 取值
db.system.name 必须使用约定内的知名值(列表见 database-spans.md)。常见映射:
| 数据库 | 取值 |
|---|---|
| MySQL / PostgreSQL / MariaDB | mysql / postgresql / mariadb |
| Redis / MongoDB | redis / mongodb |
| Microsoft SQL Server | microsoft.sql_server |
| Oracle Database | oracle.db |
| AWS DynamoDB | aws.dynamodb |
| Azure Cosmos DB | azure.cosmosdb |
⚠️ 用 PostgreSQL 驱动连 CockroachDB 时,按客户端库能识别的最优信息填 postgresql;未知的 SQL 库用兜底值 other_sql。
六、v0 到 v1 迁移:一条环境变量平滑升级
旧版数据库约定长期处于实验状态(即俗称的 v0),新版已整体达到 Stable。存量埋点不能"原地变脸",因此规范要求在现有大版本中引入环境变量 OTEL_SEMCONV_STABILITY_OPT_IN 做灰度(完整迁移方案见 docs/non-normative/db-migration.md):
| 取值 | 行为 |
|---|---|
| 不设置 | 默认继续发旧实验约定,零风险 |
database/dup | 双发旧 + 新约定,便于后端对账(两者同时出现时优先级更高) |
database | 只发稳定版新约定,停止发旧约定 |
最佳实践路径:database/dup 灰度观察 ≥ 6 个月 → 切换为 database → 下一个大版本直接移除开关。
属性改名/移除对照表
| 旧(实验版) | 新(稳定版) | 说明 |
|---|---|---|
db.system | db.system.name | 值改为 <vendor>.<product> 风格 |
db.statement | db.query.text | 默认采集需脱敏 |
db.operation | db.operation.name | — |
db.name | db.namespace | Redis 索引、SQL Server 实例名等并入其中 |
db.sql.table / db.cassandra.table / db.mongodb.collection / db.cosmosdb.container | db.collection.name | 统一表/集合命名 |
db.instance.id | server.address | 或并入 db.namespace |
db.connection_string、db.user、network.transport、network.type | 移除 | 敏感/冗余信息不再上报 |
新增属性:db.query.summary、db.operation.batch.size、db.response.status_code、db.stored_procedure.name、error.type,以及 Opt-In 的 db.query.parameter.<key>、db.response.returned_rows。
db.system.name 典型改名:mssql → microsoft.sql_server、oracle → oracle.db、dynamodb → aws.dynamodb、cosmosdb → azure.cosmosdb、db2 → ibm.db2(完整清单见 db-migration.md)。
指标侧变化
- 新增必填指标
db.client.operation.duration(Histogram,单位s),与同次操作的 Span 时长一致; - 连接池系列指标整体从
db.client.connections.*重命名为db.client.connection.*(如db.client.connection.count、db.client.connection.timeouts),且create_time/wait_time/use_time单位由ms改为s,属性pool.name→db.client.connection.pool.name。
七、具体数据库的专项约定
通用约定之上,各数据库还有细化规则(如 MySQL/PostgreSQL 的 db.response.status_code 取厂商错误码、Redis 的 Span 名不用数字 db.namespace 等):
- SQL 通用:docs/db/sql.md
- MySQL:docs/db/mysql.md | PostgreSQL:docs/db/postgresql.md | MariaDB:docs/db/mariadb.md
- Redis:docs/db/redis.md | MongoDB:docs/db/mongodb.md | Cassandra:docs/db/cassandra.md
- SQL Server:docs/db/sql-server.md | Oracle:docs/db/oracledb.md
- AWS DynamoDB:docs/db/dynamodb.md | Azure Cosmos DB:docs/db/cosmosdb.md | Elasticsearch:docs/db/elasticsearch.md
八、进阶话题(按需阅读)
- 批量操作:
db.operation.batch.size的判定规则(单条参数集不算 batch、空 batch 记 0)见 database-spans.md 脚注; - 上下文传播:可选通过 SQL commenter 把 TraceContext 注入 SQL 注释,默认关闭;
- 采样友好:
db.system.name、server.address等属性应在 Span 创建时(而非结束前)就绪,供采样决策使用。
掌握以上内容,你读到的任何符合 semantic-conventions 的数据库 Span 都能"开箱即懂"——无论它来自 MySQL、Redis 还是 DynamoDB。
【免费下载链接】semantic-conventions
Defines standards for generating consistent, accessible telemetry across a variety of domains
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考





