OpenTelemetry学习笔记(十二):在APM系统中,属性的命名空间处理遵循规则
在APM系统(如Elastic APM或Jaeger)中,属性的命名空间处理遵循明确的规则。以下是完整的解析:
1. 属性自动分配规则
当您设置的属性 没有明确前缀(如span.
或service.
)时,APM系统会根据上下文自动分类:
属性类型 | 存储位置 | 示例 | 典型用途 |
---|---|---|---|
无前缀属性 | 存入labels 或tags 区 | {"http.method": "GET"} | 通用业务标签 |
span. 前缀 | Span专属字段 | {"span.duration.us": 4867} | Span技术指标 |
service. 前缀 | Service元数据 | {"service.name": "frontend"} | 服务标识 |
2. 无前缀属性的去向
(1) Elastic APM 的处理方式
{"span": {"id": "abc123","duration": 4867,"tags": { // 无前缀属性落在这里"http.method": "GET","rpc.service": "CurrencyService"}}
}
(2) Jaeger 的处理方式
{"process": {"serviceName": "frontend","tags": [] // service.前缀属性},"spans": [{"spanID": "abc123","operationName": "GET /cart","tags": [ // 无前缀和span.前缀属性混合{"key": "span.duration.us", "value": 4867},{"key": "http.method", "value": "GET"}]}]
}
3. 代码中的最佳实践
(1) 明确前缀的场景
// 必须加前缀的情况
attributes.put("service.name", "frontend") // 服务标识.put("span.duration.us", 4867); // Span技术指标// 会被APM特殊处理的字段(即使不加前缀)
.put("http.method", "GET") // 自动识别为HTTP协议
.put("db.statement", "SELECT * FROM users") // 自动识别为数据库调用
(2) 无需前缀的场景
// 业务自定义标签(不加前缀)
.put("user.id", "12345")
.put("checkout.step", "payment");// 协议标准字段(可不加前缀,但建议明确)
.put("rpc.method", "GetProduct") // 等效于 span.rpc.method
4. 自动映射的常见字段
即使不加前缀,APM也会自动识别这些标准字段:
原始字段 | 自动映射为 | 来源规范 |
---|---|---|
http.method | span.http.method | OpenTelemetry语义约定 |
db.system | span.db.system | |
rpc.service | span.rpc.service | |
messaging.destination | span.messaging.destination |
5. 调试技巧
检查最终上报的数据结构:
// 在exportSpan方法末尾添加日志
System.out.println("上报属性: " + attributes.build().asMap());
输出示例:
{"service.name": "frontend","span.duration.us": 4867,"http.method": "GET", // 自动归类到span"user.id": "12345" // 存入tags区
}
关键结论
- 技术性字段:建议显式添加
span.
或service.
前缀确保准确性 - 业务标签:无需前缀,APM会自动存入
tags
区 - 协议标准字段:如
http.*
/db.*
等,不加前缀也能被正确识别,但显式声明更可靠
通过这种设计,APM系统可以在保持灵活性的同时,确保技术元数据的结构化存储。