结构化日志是什么
结构化日志把日志写成字段化的、机器可直接解析的格式(通常是 JSON):字段名固定(ts、level、service、trace_id),取值规则稳定。相比自由文本,结构化日志在过滤、聚合与关联上都更省力——查某个接口的 5xx 只需按字段筛选,而不用写越来越复杂的正则。
基本信息
| 常见格式 | JSON(也有 logfmt) |
|---|---|
| 核心字段 | ts / level / service / trace_id / msg |
| 时间格式 | ISO8601 UTC |
| 级别取值 | 固定枚举(debug/info/warn/error) |
| 解析成本 | 字段直接可用,无需正则 |
| 常见规范 | OpenTelemetry 日志模型、ECS 字段规范 |
典型使用场景
- 按 level 与 service 过滤日志,快速定位错误范围
- 按 status 与 duration 聚合,统计错误率与慢请求占比
- 把 trace_id 打进日志,实现日志与链路的互相跳转
- 统一多语言服务的日志格式,跨服务检索用同一套字段
- 在采集端做字段裁剪与脱敏,控制存储与合规风险
- 用结构化字段做告警,避免靠关键词匹配带来的误报
结构化日志行示例
结构化日志行示例
{"ts":"2026-10-12T10:00:00.123Z","level":"error","service":"api",
"trace_id":"4bf92f3577b34da6a3ce929d0e0e4736","route":"/v1/order",
"status":500,"duration_ms":812,"msg":"upstream timeout"}
# 查询侧按字段过滤(Loki 示例)
{service="api"} | json | level="error" and status >= 500
# 字段稳定后可直接聚合
sum by (route) (count_over_time({service="api"} | json | status>=500 [5m]))推荐字段约定
| 字段 | 含义 | 约定 |
|---|---|---|
| ts | 时间戳 | ISO8601 UTC,便于跨时区排序 |
| level | 级别 | 固定枚举,不用自由文本 |
| service | 服务名 | 用部署名,不用实例 ID |
| trace_id | 链路标识 | 十六进制,与追踪系统一致 |
| duration_ms | 耗时 | 字段名带单位,避免歧义 |
字段约定先小后大:时间用 ISO8601 UTC、级别用固定枚举、service 用部署名,其余按需扩展,逐步统一比一次性大改更容易落地。
敏感信息(证件号、令牌、完整卡号)禁止进入日志正文,脱敏必须在写入前完成,事后清理成本极高。
自定义字段尽量不与规范字段重名(如自建 time 与标准 ts 并存),否则解析与查询会反复踩坑。
结构化不等于全部字段化:把整段堆栈塞进一个 JSON 字段虽可行,但堆栈内容仍应保留可读性,避免正则再解析。