3. 日志检索基础:日志级别、结构化日志与非结构化日志、日志字段设计最佳实践
3.1 日志级别:故障排查的信号灯
日志级别是日志系统中最基础、最重要的元数据。它直接决定了日志的严重性和响应优先级。在 MTTR 驱动的体系中,错误地使用日志级别会导致告警风暴或关键故障被淹没。
| 级别 | 含义 | 典型场景 | MTTR 影响 |
|---|---|---|---|
| FATAL | 致命错误,服务无法继续运行 | 数据库连接池耗尽、关键依赖不可用、内存溢出 | 必须立即触发 P0 告警,自动拉起或人工介入 |
| ERROR | 错误,但服务可降级运行 | 请求处理失败、第三方 API 超时、数据校验异常 | 需要聚合分析,判断是否为批量故障 |
| WARN | 警告,潜在风险或非预期行为 | 磁盘使用率超过 80%、重试次数过多、配置即将过期 | 用于趋势分析,避免演变为 ERROR |
| INFO | 正常业务信息,用于追踪流程 | 请求开始/结束、用户登录、定时任务执行 | 提供上下文,辅助定位问题根因 |
| DEBUG | 调试信息,仅在开发或排障时开启 | 变量值、函数调用栈、SQL 语句 | 生产环境默认关闭,避免日志洪流 |
最佳实践:生产环境日志级别应设置为 INFO 或 WARN。DEBUG 日志必须通过动态配置开关控制,避免磁盘 I/O 成为性能瓶颈。
3.2 结构化日志 vs 非结构化日志
非结构化日志(如纯文本)在机器解析和检索时效率极低,是延长 MTTR 的常见原因。结构化日志(如 JSON)则天然支持字段索引和快速过滤。
| 对比维度 | 非结构化日志 | 结构化日志 |
|---|---|---|
| 格式 | 自由文本,无固定 schema | JSON / Logfmt / Protobuf |
| 可读性 | 人类友好,但机器解析困难 | 机器友好,支持自动索引 |
| 检索效率 | 依赖全文搜索,速度慢 | 按字段精确过滤,速度快 |
| 字段扩展 | 需正则提取,易出错 | 直接追加 key-value |
| MTTR 影响 | 定位问题需逐行阅读,MTTR 长 | 可快速聚合、过滤、关联,MTTR 短 |
推荐方案:所有新服务必须使用 JSON 格式输出结构化日志。旧系统应通过日志采集侧(如 Filebeat、Fluentd)进行结构化转换。
3.3 日志字段设计最佳实践
良好的日志字段设计是可观测性的基石。字段设计应遵循 SPE(Standard、Precise、Enough)原则,确保在故障排查时能快速关联上下文。
3.3.1 必选字段(黄金信号)
- timestamp:精确到毫秒或微秒,使用 ISO 8601 格式(如
2025-03-15T10:00:00.123Z)。 - level:日志级别,用于告警和过滤。
- service:服务名称,用于跨服务关联。
- trace_id:分布式追踪 ID,用于串联请求链路。
- message:人类可读的描述信息。
3.3.2 推荐字段(上下文增强)
- instance:实例 ID 或 Pod 名称,用于定位具体节点。
- error_stack:异常堆栈,仅在 ERROR/FATAL 时输出。
- duration_ms:请求处理耗时,用于性能分析。
- user_id / request_id:业务标识,用于用户维度排查。
- region / az:部署区域,用于多活架构。
避坑指南:避免在日志中输出敏感信息(如密码、身份证号、信用卡号)。必须输出的敏感字段应进行脱敏处理(如
password: "***")。
3.3.3 字段设计示例
{
"timestamp": "2025-03-15T10:00:00.123Z",
"level": "ERROR",
"service": "order-service",
"trace_id": "abc123def456",
"instance": "order-svc-7f8b9c1d2e",
"message": "用户下单失败",
"error_stack": "java.lang.RuntimeException: 库存不足\n\tat com.example.OrderService.createOrder(OrderService.java:45)",
"duration_ms": 1523,
"user_id": "user_98765",
"request_id": "req_abc123",
"region": "cn-east-1"
}
3.4 日志检索基础操作
在日志平台(如 Elasticsearch、Loki、Splunk)中,结构化日志的检索效率远高于非结构化日志。以下是一些基础检索技巧:
- 精确过滤:
level:ERROR AND service:order-service - 范围查询:
timestamp:[2025-03-15T09:00:00 TO 2025-03-15T10:00:00] - 存在性检查:
_exists_:trace_id - 聚合统计:按
level分组统计日志数量,快速发现异常趋势。
MTTR 关键指标:在故障排查时,优先使用 trace_id 或 request_id 进行全链路检索,避免逐行扫描。这能将定位时间从分钟级缩短到秒级。