ELK日志平台 生产落地案例
生产落地案例
案例一:电商微服务日志接入 ELK,先治「索引爆炸」再治「查不动」
背景。某电商平台把单体拆成四十多个微服务后,每个服务都在自己机器上写日志。大促出问题时,运维要登录十几台机器 grep,一个订单的完整链路要拼半小时。团队决定上 ELK,第一版方案是「每个服务每天建一个索引」,索引名形如 order-2026.09.18。
怎么做。第一步先解决索引数量问题。四十个服务乘以每天一个索引,一天的索引数就上百,保留一个月就是几千个索引、每个索引默认五个分片,分片总数上万。集群元数据暴涨,Master 频繁卡顿,Kibana 里索引列表都刷不出来。改成「一个环境一个 rollover 别名 + ILM」:所有服务写入 app-logs 这个别名,用 service.name 字段区分服务,索引大小或时间任一达到阈值就自动切下一个隐藏索引。
关键配置。索引模板里固定 mapping,把 service.name、level、trace.id、http.status_code 显式声明成 keyword 或数值类型,避免被自动推断成 text;同时开启 dynamic: false,未知字段不建索引只存原文。ILM 策略设为:hot 阶段保持可写,超过阈值 rollover;进入 warm 后设只读并做段合并;满三十天进入 cold;满九十天删除。Logstash 侧把 bulk 批量调到适中值,并对 grok 失败的行打 tag 单独走一条低优先级索引。
效果。索引数量从每天上百降到每天几个,Master 的元数据压力回到正常水位,Kibana 打开 Discover 不再卡顿;全文检索常用查询稳定在亚秒级返回,大促排障从半小时缩短到几分钟。
坑与解决。(1)按天建索引导致分片数上万、集群元数据压力大 —— 改成 rollover + ILM 后解决,注意 rollover 别名写入时索引名要符合 -000001 的六位数字后缀规则。(2)日志打全量请求体,磁盘涨得飞快 —— 先在应用侧把线上日志级别从 DEBUG 降到 INFO,只保留必要的 body 字段,采集侧再配合 mutate 删除无用字段。(3)磁盘到水位线后索引被自动置为 read-only,写入全量失败 —— 清理磁盘或扩容后必须手动解除 block,否则索引会一直是只读状态。(4)mapping 冲突:某个字段一开始打的是字符串、后来打了数字,被自动推成 text,导致后面想按它做数值聚合只能重建索引 —— 根治办法是模板里预先声明字段类型。(5)grok 正则写得过于宽松,遇到不匹配的行大量回溯,Logstash CPU 打满、采集延迟飙到十几分钟 —— 把 GREEDYDATA 换成更精确的模式,并把固定分隔符的日志改用 dissect。
案例二:从「日志能查了」到「日志有人管」
背景。日志接入后,团队发现两个新问题:一是没人知道哪些索引该留多久,磁盘一直涨;二是日志里混着用户手机号与内部接口凭据,安全审计提了整改意见。
怎么做。把日志分三级:核心交易与支付类保留久一些,普通业务日志按常规周期保留,调试与压测日志短周期删除,全部通过 ILM 的 delete 阶段自动兜底,不依赖人工清理。同时在应用侧加统一日志切面,对手机号、身份证号、银行卡号、Authorization 头做脱敏后再落盘,采集侧再加一层 gsub 兜底。访问侧按角色授权:开发只能看自己服务的索引模式,运维看全部,敏感索引单独建角色并开启审计。
关键配置。三个不同的 ILM 策略分别绑定到不同的索引模板,模板用 index_patterns 做区分;Kibana 里按空间(Space)与角色把不同团队隔开,避免所有人共用一套视图。
效果。磁盘增长变得可预测,不再出现「某天早上突然写不进去」;安全审计从「随时可能抽检不过」变成有据可查的脱敏流程;新人上手时能从文档里直接查到「这类日志保留多久、在哪看」。
坑与解决。脱敏放在采集侧是不够的 —— Logstash 一旦积压,未脱敏的原始日志会短暂停留在 Buffer 与磁盘队列里;正确做法是在应用写日志前就完成脱敏,采集侧只做兜底。

