ELK 日志截断问题诊断
总结
日志“少一截”是因为同一 igo-biz-log 文件并发写入造成块交错,Filebeat 在插入的新时间头处切开事件;ES 存的是半截原文。影响约万分之四,优先拆文件/单写线程,不建议上 NFS 全局文件锁。
| 项目 | 内容 |
|---|---|
| ELK 主机 | igo-elk-01(CentOS 7) |
| 相关索引 | 10.10.10.20-2026.07.27 |
| 日志类型 | igo-biz-log(Filebeat → Logstash → Elasticsearch) |
| 结论 | 非 ES/Logstash 截断;根因是 同文件并发写导致内容穿插,Filebeat multiline 在中间误切事件 |
| 影响比例(粗估) | 最近 5 分钟 igo-biz-log:0.038%(22 / 57171,含 uri 且不含 execTime) |
关键源文件(半截样本对照用)
| 项 | 值 |
|---|---|
| 所在主机 | igo-collector-01(10.10.10.20) |
| 完整路径 | /data/igo-log-pvc-xxxx/log2026072710/igo-api-module_10_10_10_21.txt |
| 目录 | /data/igo-log-pvc-xxxx/log2026072710/ |
| 文件名 | igo-api-module_10_10_10_21.txt |
| PVC/数据根 | /data/igo-log-pvc-xxxx/ |
ES log.offset |
23092118 |
| 半截事件时间头 | 2026-07-27 10:47:38.566 |
| 穿插插入的时间头 | 2026-07-27 10:47:38.564 |
1. 现象
业务侧反馈:部分日志在 Elasticsearch / Kibana 中查询时内容不完整。例如整条约 600 字节,只能看到前约 400 字节,后部缺失。实际抽样中,半截日志常停在 JSON 字段中间(如 {"par)。
2. 环境与链路
应用写 *.txt(NFS PVC)
→ Filebeat(igo-collector-01 / 10.10.10.20)
→ Logstash beats:5044(igo-elk-01)
→ Elasticsearch 索引:%{fields.ip}-%{YYYY.MM.dd}
→ Kibana 查询展示
ELK 侧:Elasticsearch 8.x、Logstash、Kibana 均正常运行(CentOS 7)。
3. 问题定位证据
3.1 排除:不是 ES / Logstash 截断
- Logstash 无
truncate/max_bytes等裁剪逻辑;仅对igo-biz-log做 grok +ClientIP替换。 - ES
message为text,keyword.ignore_above=256只影响 keyword 索引,不截断_source。 - 同索引既有 1900+ 字节完整日志,也有半截日志 → 排除全局长度上限。
3.2 现象特征:多数完整,少数半截
对 igo-biz-log 抽样 15 条:含 execTime 14 条,半截 1 条;采集端为 Filebeat。
半截样本
| 字段 | 值 |
|---|---|
| bytes | 1130 |
| has_execTime | False |
| path | /data/igo-log-pvc-xxxx/log2026072710/igo-api-module_10_10_10_21.txt |
| offset | 23092118 |
| tail | ..."stepNo":1},{"par |
完整样本尾部形如:END2026-07-27 ...----------------。
3.3 核心证据:源文件内容已穿插
同 offset=23092118 对照源文件:
| 项 | 结果 |
|---|---|
| ES 入库长度 | ≈ 1130 字节(无 END) |
源文件至 END |
≈ 3032 字节 |
| 约 1130 字节处 | JSON 未写完,插入另一条时间头 |
约 1130 字节处原文(根因直接证据)
ue":"58.647","stepNo":1},{"par
2026-07-27 10:47:38.564--------------------------
穿插结构
'2026-07-27 10:47:38.566-----------------' ← 事件 A 开始
'uri :/igo-api-module'
'Parameter:jsonData={...' ← A 的 Parameter(长 JSON,未写完)
'2026-07-27 10:47:38.564-----------------' ← 事件 B 插入(误切点;时间更早)
'uri :/igo-api-module'
...
说明:多线程/多进程 并发 append 同一文件,把新日志块插进了上一条 JSON 中间。Filebeat 以行首时间(如 ^202[0-9])作为新事件起点,在此处提前切开 → ES 只收到半截。
4. 排除项汇总
| 怀疑点 | 结论 |
|---|---|
ES mapping / ignore_above |
排除 |
| Logstash 截断 | 排除 |
| Kibana 仅展示截断 | 排除(_source 已是半截) |
| 全局 message 长度上限 | 排除 |
| 同文件并发 append | 确认:主因 |
5. 根因与影响
根因:应用(或多实例)并发写同一 igo-api-module_*.txt,日志块物理交错;Filebeat 多行规则在插入的时间头处切开事件。ES 忠实存储了被切开后的半截内容——不是 ES 丢尾。
影响比例(最近 5 分钟)
| 窗口 | total | incomplete(含 uri 无 execTime) | 比例 |
|---|---|---|---|
| now-5m | 57171 | 22 | 0.038% |
- 属偶发,非大面积截断。
- 日量千万级时,半截仍可能有数千~上万条,排障会碰到,相对总量可忽略。
6. 修复建议
6.1 应用侧(根本)
- 禁止多线程/多进程无锁并发写同一日志文件。
- 优先:
- 按实例/线程拆文件;
- 单写线程 + 内存队列,整段(时间头 →
END)顺序写完; - 仅单机、确认不跨节点写同一文件时,再用进程内锁保护整段一次写完。
- 文件已交错时,采集端无法还原完整内容,必须先修写入方式。
6.2 加锁影响评估
日志在 NFS PVC;半截约 0.038%,不宜为完整性上全局/NFS 文件锁。
| 方案 | 影响 | 建议 |
|---|---|---|
| NFS / 跨节点文件锁 | 写串行、延迟升高;NFS 锁常不可靠;持锁卡住会放大故障 | 不推荐 |
| 进程内锁(单机) | 同文件串行;多 Pod 写同一 NFS 文件仍会穿插 | 仅单机单文件可用 |
| 按实例拆文件 / 单写线程 | 无额外锁争用或延迟可控 | 优先推荐 |
6.3 验证建议
- 同
offset:源文件至END长度 ≈ ES_source.message字节数。 igo-biz-log中含execTime/ 以END结尾的比例接近 100%。- 源文件中「Parameter 中部再出现新时间头」趋近 0;5 分钟 incomplete 占比趋近 0。