第2章 日志巡检基础:日志采集、存储与常见格式
日志巡检这件事,我一直觉得“基础”比“高级技巧”更容易翻车。你想想看,告警处置再牛,如果日志压根没采上来,或者采上来存得乱七八糟,那后面的规则、分析全是白搭。所以我习惯先把采集、存储、格式这三个底子打好,再谈适配。
这一章我们就聊聊这三个基础模块。我尽量用我踩过的坑来帮你避开一些弯路。
日志采集的几种常见方式
日志从哪来?无非是服务器、容器、网络设备、中间件。我个人在实际项目中用过下面这几种主流方案:
| 采集方式 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
| Agent 采集(如 Filebeat / Fluentd) | 应用日志、容器 stdout | 灵活、支持多格式解析 | 需要维护 agent 本身 |
| Syslog 收集 | 网络设备、Linux 系统日志 | 标准协议、轻量 | 格式固定、UDP 可能丢包 |
| SDK / API 推送 | 自研应用、微服务 | 实时、可以带上下文 | 侵入性强、改代码 |
| DB 轮询 / 文件 Tail | 遗留系统、数据库日志 | 无需改造、兼容性强 | 性能差、延迟高 |
其实大部分场景我首选 Agent。举个例子,我处理过一个 K8s 集群巡检:每个 Pod 只写 stdout,用 Fluentd DaemonSet 采集,然后加一个 filter 把容器名打进去,后面查什么问题都能定位到 Pod。嗯,效率很重要。
日志存储的考量
日志采上来之后放哪?别以为买个大硬盘就行。我见过有人把一年日志全塞一个 ES 索引,查询直接 OOM。存储上我们得考虑几个维度:
- 集中式存储:Elasticsearch / ClickHouse / Loki。我个人用 ES 最多,但 Loki 如果配套 Grafana 也很香。
- 索引策略:按时间分索引(每天一个),加上按服务名、级别做 routing。我在项目里吃过亏:没分好索引,全表扫描慢到怀疑人生。
- 保留周期与冷热分层:热数据保留7天,温数据30天,冷数据归档到 S3 或 HDFS。别舍不得删,存多了既不快也不省钱。
- 压缩与采样:gzip 能压到原大小的 10% 左右。对 debug 级别日志可以采样存,不然量太大。
常见日志格式解析
格式决定了告警规则好不好写。你要是做过跨团队巡检,一定见过这种场面:A 团队写 JSON,B 团队写混合 Syslog,C 团队干脆自由格式——解析器写死你。我建议一开始就统一格式,至少保证整个巡检链路上能看懂。
| 格式 | 典型例子 | 可解析性 | 适用场景 |
|---|---|---|---|
| Apache Combined | 127.0.0.1 - - [10/Oct/2020:13:55:36 -0700] "GET /index HTTP/1.1" 200 2326 "-" "Mozilla/5.0" | 高(grok 模板成熟) | Web 服务器 |
| JSON | {"time":"2024-01-01T12:00:00Z","level":"ERROR","msg":"Connection refused","service":"api"} | 非常高(自带结构化) | 微服务、应用日志 |
| Syslog RFC 5424 | <14>1 2024-01-01T12:00:00Z myhost myapp 1234 - - Failed to connect | 中(需解析 header) | 系统日志、网络设备 |
| 自定义格式 | 2024-01-01 12:00:00 | ERROR | module=db | msg=timeout | 低(需写定制 parser) | 遗留系统、自研框架 |
我比较推荐 JSON。为什么?因为 JSON 天生带 key-value,你后续写告警规则可以很方便地从字段里取 level、service、error_code。记得有一次接手一个老系统,日志全是自由文本“2024-01-01 ERROR timeout”,根本没有 severity 字段,我花了整整两天写正则拆字段,唉,血泪教训。
另外,Syslog 格式注意协议版本。RFC 5424 比老的 BSD syslog 多了结构化数据,但很多设备还在发老格式。我曾经遇到交换机发的是混杂格式,grok 匹配不上,最后用 ruby 过滤器手动修复才搞定。
知识体系总览
下面这张图概括了本章的核心内容。你可以把它当成一个检查清单:看完图,心里就有数了。
避坑指南:格式统一的重要性
最后说一个我当年犯过的错。当时一个日志巡检项目,要对接 5 个不同部门的应用日志。我图省事,告诉各团队“你们照常写,我这边自适应解析”。结果上线之后:
- 有的团队时间戳带毫秒,有的带时区,有的直接缺年。
- 有的 field 叫
level,有的叫severity,有的叫priority。 - 有的 JSON 嵌套三层,有的平铺。
我花了一周时间写了一堆分支正则,最后还是漏了 case。后来我强制所有服务输出统一的 JSON schema,并上线一个 log-validator sidecar 在采集端做格式校验,不符合的直接抛弃并报警。从那以后,告警规则的适配再也没有因为格式问题出过事。
总结三个要点:
- 采集选 Agent 模式最稳妥,后续扩展也方便。
- 存储必须做索引分片和冷热分层,否则 ES 扛不住。
- 格式统一是告警规则可复用的前提,推荐 JSON + 固定 schema。