igozhang

——

    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-log0.038%(22 / 57171,含 uri 且不含 execTime)

    关键源文件(半截样本对照用)

    所在主机 igo-collector-0110.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 messagetextkeyword.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 应用侧(根本)

    1. 禁止多线程/多进程无锁并发写同一日志文件。
    2. 优先:
      • 按实例/线程拆文件
      • 单写线程 + 内存队列,整段(时间头 → END)顺序写完;
      • 仅单机、确认不跨节点写同一文件时,再用进程内锁保护整段一次写完。
    3. 文件已交错时,采集端无法还原完整内容,必须先修写入方式。

    6.2 加锁影响评估

    日志在 NFS PVC;半截约 0.038%,不宜为完整性上全局/NFS 文件锁。

    方案 影响 建议
    NFS / 跨节点文件锁 写串行、延迟升高;NFS 锁常不可靠;持锁卡住会放大故障 不推荐
    进程内锁(单机) 同文件串行;多 Pod 写同一 NFS 文件仍会穿插 仅单机单文件可用
    按实例拆文件 / 单写线程 无额外锁争用或延迟可控 优先推荐

    6.3 验证建议

    1. offset:源文件至 END 长度 ≈ ES _source.message 字节数。
    2. igo-biz-log 中含 execTime / 以 END 结尾的比例接近 100%。
    3. 源文件中「Parameter 中部再出现新时间头」趋近 0;5 分钟 incomplete 占比趋近 0。

    MP3