教程
🚀

运维与 DevOps

Docker、Kubernetes、CI/CD 与云原生实践。

日志采集与告警:让问题主动找你

用 ELK/Loki 把分散的日志集中起来,再基于 SLO/SLI 设计告警规则,让系统出问题时第一时间通知到人,而不是等用户投诉。

· 更新于 2026-07-20 阅读量 --

上两篇我们讲了指标(Prometheus/Grafana)和三支柱框架。这一篇补齐监控闭环的另外两块:集中式日志告警

想象一个场景:你有 10 台服务器,每台都在本地打日志。半夜出问题,你得一台台 SSH 上去翻日志,累得半死还找不到。更糟的是,没人告诉你”出问题了”,是用户先发现了。这一篇就是解决这两件事:把日志集中起来好查,让问题主动报警到人。

第一块:集中式日志(ELK / Loki)

单机 tail -f 在集群时代彻底失效。解决方案是日志集中化:所有服务的日志统一发到一个地方存储、检索。

最经典的方案是 ELK

  • E(Elasticsearch):搜索引擎,负责存日志、提供全文检索。
  • L(Logstash):收集器,负责从各服务把日志拉来、清洗、转发。
  • K(Kibana):界面,负责在网页上搜索、画图、看日志。

轻量替代是 Loki(Grafana 出品):思路和 ELK 类似,但存储更省,和 Prometheus/Grafana 生态天然一体,适合已经用 Grafana 的团队。

典型数据流:

应用打日志 → 采集器(Filebeat/agent) → 存储(ES/Loki) → 界面(Kibana/Grafana) 检索

实战中,应用打结构化 JSON 日志,采集器自动把每条日志带上 servicelevelrequest_id 等字段。出问题时,你在界面搜 level:error AND service:order,一秒定位订单服务的所有错误,再按 request_id 串联一次请求的完整轨迹。

第二块:告警——让问题主动找你

光有仪表盘还不够:你不可能 24 小时盯着屏幕。告警(Alerting)的作用是:当指标或日志触发条件时,自动发消息(钉钉/飞书/邮件/电话)通知到人

告警一般挂在监控系统上。比如 Prometheus 配 Alertmanager,定义规则:

groups:
  - name: 示例告警
    rules:
      - alert: 错误率过高
        expr: sum(rate(http_requests_total{status="500"}[5m])) / sum(rate(http_requests_total[5m])) > 0.01
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "错误率超过 1% 已持续 5 分钟"

解释:

  • expr:PromQL 表达式,这里是”5xx 错误率占比超过 1%”。
  • for: 5m:持续 5 分钟才报警,避免瞬间抖动误报(很重要,下面讲)。
  • labels.severity:严重程度,用于决定通知渠道(warning 发群,critical 打电话)。
  • 触发后,Alertmanager 把告警推到钉钉/飞书/邮件。

SLO 与 SLI:告警该基于什么设

新手常犯的错:把所有指标都设告警,结果告警雪崩,大家麻木忽略(叫”告警疲劳”)。正确做法是先定义 SLO/SLI

  • SLI(Service Level Indicator,指标):衡量服务质量的真实指标,比如”请求成功率""P99 延迟”。
  • SLO(Service Level Objective,目标):你承诺的服务水平,比如”成功率 ≥ 99.9%""P99 延迟 < 300ms”。
  • 错误预算(Error Budget):允许的失误空间。99.9% 意味着一个月约 43 分钟不达标是可以接受的。

告警应围绕 SLO 设:当”错误预算”快烧完时才报警,而不是”每次小波动都叫”。这样既及时又不扰民。

告警设计的几条铁律

  • 宁可少报,别滥报:每条告警都该”值得你爬起来处理”。无意义的告警最终会被忽略,真出事反而没人看。
  • for 持续时间:避免瞬时抖动误报。CPU 飙一下就报警,半夜把你叫醒发现是定时任务,纯属折磨。
  • 分级路由:warning 发群消息,critical 打电话/发短信。别所有告警一个级别。
  • 告警要可行动:一条好告警应包含”是什么、在哪、怎么查”。只写”CPU 高”不如写”订单服务 CPU 95%,见 Grafana 面板 X”。
  • 有告警就要有 runbook:接到告警该怎么做,写成文档。否则新手接到告警只会发呆。

常见坑位提醒

  • 日志没结构化:纯文本日志在 ES 里只能全文搜,没法按字段过滤。尽早统一 JSON 日志格式。
  • 采集器成为瓶颈:日志量巨大时,采集器(Logstash)可能跟不上。用轻量 Filebeat 做采集、必要时加队列缓冲。
  • 告警阈值拍脑袋:“CPU > 80% 就报警”可能永远在响或从不响。基于历史数据和 SLO 定阈值。
  • 只告警不治理:告警来了处理完就完事,不复盘根因,同样的问题反复报。建立”告警→处理→复盘→优化”闭环。
  • 忘了日志保留期:ES 存全量日志很贵,设合理的保留周期(如 30 天热数据 + 归档),别无脑永久存。

小测验:看看你掌握了没

  • 问题一:为什么需要集中式日志?答案:多机环境下逐台翻日志低效,集中化后才能跨服务按字段检索、按 request_id 串联。
  • 问题二:告警为什么要加 for: 5m?答案:过滤瞬时抖动,避免误报造成告警疲劳。
  • 问题三:SLO 和 SLI 的区别?答案:SLI 是真实质量指标,SLO 是你承诺的目标值,告警应围绕 SLO 设。

这一篇你该记住的

  • 集中式日志:ELK(Elasticsearch+Logstash+Kibana)或轻量 Loki,把分散日志汇聚检索。
  • 应用打结构化 JSON 日志,带 service/level/request_id,便于过滤与串联。
  • 告警基于监控系统(如 Prometheus + Alertmanager),expr 定条件、for 防抖、分级路由通知。
  • 告警围绕 SLO/SLI 设计,用错误预算避免告警疲劳;铁律:少而可行动、有 runbook。
  • 坑:日志非结构化难查、阈值拍脑袋、只告警不复盘。

学到这里,监控三件套(指标/日志/告警)你都齐了。但现代服务往往跑在容器和编排平台上——如何把应用弹性地部署、扩缩容、自愈?这就引出了我们的最后一个系列:云原生