题干与适用场景
多个团队使用不同日志库和代理,级别名称从 TRACE、DEBUG 到 CRITICAL 不一致。请说明如何映射到 OpenTelemetry 的 SeverityNumber 与 SeverityText,如何保留原始信息,并处理异常、采样、查询和版本迁移。
面试官考察点
- 是否区分标准化的 SeverityNumber、原始 SeverityText 和日志正文。
- 是否理解数值区间表达严重度,而不是把所有系统的同名级别硬编码成一一对应。
- 是否能结合异常事件、资源属性、trace/span 关联和采集器转换。
- 是否考虑未知级别、采样偏差、查询兼容、告警阈值和回放验证。
回答前需要澄清的问题
- 每种来源的级别定义、数值范围和升级规则是什么?是否存在自定义级别?
- 需要保留原始级别字符串、日志库名称和版本吗?下游查询依赖哪些字段?
- 异常是独立事件还是普通日志正文?是否需要关联 trace、span 和 request ID?
- 映射会影响告警、采样、存储成本和合规留存吗?如何回放历史日志验证结果?
30 秒回答框架
我会先为每个来源建立语义字典,区分日志级别的含义和名称,再映射到 OpenTelemetry SeverityNumber 区间,同时保留原始 SeverityText 与来源元数据。异常使用标准异常语义并关联 trace/span,不把堆栈全文塞进级别字段。采集器负责转换和校验,未知级别进入可观测的降级路径。上线前用代表性样本回放,检查告警阈值、采样、查询和成本,避免一次性重解释全部历史数据。
分步骤深入解答
1. 先定义标准字段
OpenTelemetry Logs Data Model 将严重度拆成 SeverityNumber 和 SeverityText。Number 用于可比较的严重度范围,Text 保留产生方的原始或显示名称;正文、属性、资源和时间戳承担其他语义。映射表应记录来源系统、原级别、目标范围和理由,而不是只写一段转换代码。
2. 建立来源到范围的映射
不同框架的 WARN、ERROR 或 FATAL 可能对应不同运营动作。按语义将它们映射到连续区间,保留无法确认的级别为未定义或低置信度,并把原始值放入 SeverityText 或受控属性。不要把数字本身跨系统直接比较,先验证每个来源的文档和样本。
3. 处理异常与关联信息
OpenTelemetry 异常语义建议记录异常类型、消息和堆栈等字段,并按异常是否导致应用失败选择合适严重度。日志应携带 trace ID、span ID、服务和部署版本等关联信息,让查询能区分同一请求中的多条日志。异常堆栈属于诊断数据,应按敏感信息和留存策略处理。
4. 验证采集、告警与迁移
在 Collector 或边缘代理中执行映射、字段校验和兼容转换,记录无效值与丢弃原因。用历史样本和合成故障回放,验证告警阈值、采样规则、查询结果和存储成本。版本升级时保留映射版本与原始字段,让下游可以按版本解释历史数据,而不是静默改变告警含义。
高质量示范回答
我会先为 Java、Python、Nginx 等来源建立带文档依据的语义映射,目标是 OpenTelemetry SeverityNumber,原始名称保留在 SeverityText 和受控属性中。数字只用于同一标准内比较,未知或自定义级别进入低置信度路径并告警。异常按 OpenTelemetry 异常语义记录类型、消息和堆栈,同时关联 trace/span 和服务版本。Collector 负责转换、校验和指标记录;上线前回放历史与故障样本,验证告警、采样、查询和成本。映射版本与原始字段长期保留,保证迁移可追溯。
常见错误
- 把所有来源的 ERROR、WARN 或 FATAL 直接一一映射,不核对语义。
- 只保留 SeverityNumber,丢弃原始级别和来源版本。
- 用日志正文代替异常字段,导致堆栈无法检索或泄漏敏感内容。
- 忽略 trace/span 关联,无法把日志与请求链路对齐。
- 映射失败时静默丢弃或强行降为 INFO,没有指标和告警。
- 修改映射后直接重算历史告警,却没有版本和回放记录。
追问及应对
未知级别应该映射到哪个数值?
先保留原始文本并标记未知或低置信度,不应随意塞进 ERROR。若业务必须排序,定义明确的默认区间并记录映射版本,同时监控未知值比例,推动来源补齐语义。
采样会不会改变严重度分布?
会。按严重度和异常事件设计优先级,保留高价值故障样本,并记录采样决策和输入分母。比较采样前后的级别分布,避免用采样后的计数直接代表真实错误率。
如何兼容旧查询?
在转换层保留原始字段和旧别名一段时间,提供版本化视图或查询函数。迁移期间对告警和报表做双写或对照回放,确认新旧结果差异后再下线旧字段。