← 返回场景决策

📋 日志收集方案选型与实战

结果导向 · 怎么选 · 为什么 · 生产上长啥样 · 有什么坑

Loki Grafana ELK 选型 生产实战

1. 直接给结论

中小团队无脑选 Loki + Grafana

轻、便宜、部署简单、一个面板同时看日志 + 监控指标。除非你需要全文搜索日志内容(见下表),否则没有理由选别的。

你的需求选什么一句话原因
中小团队日常排查(按服务/级别/时间查日志) Loki + Grafana 存储省 90%,Grafana 一个面板看日志+监控,部署简单
要像 Google 一样全文搜索日志内容(安全审计/合规) ELK ES 倒排索引全文搜索无敌,但存储贵 3-5 倍
上云了,不想自己运维 阿里云 SLS / 腾讯云 CLS 零运维,按量付费,日志量大时账单贵
K8s 环境 + 要全文搜索 EFK(Fluentd 替代 Logstash) Fluentd 比 Logstash 轻,适配容器
分水岭就一个:要不要全文搜索日志内容
• 要 → ELK(ES 全文索引强,但重)
• 不要 → Loki(只索引标签,轻 10 倍)
• 90% 的日常排查都是按"哪个服务 + 什么级别 + 什么时间"查 → Loki 够用

2. 这些技术分别是什么

每个技术一句话说清楚,不用记原理,知道它是干啥的就够了。

技术是什么一句话定位
Loki 存日志的数据库 只给标签建索引,不索引日志内容 → 省存储 90%,按标签查秒回,全文搜内容慢
Grafana 可视化看板 啥数据源都能接(Loki/Prometheus/ES/MySQL...)→ 一个面板看日志+指标+链路
Promtail 日志采集器 Loki 专属采集器,读日志文件打标签发给 Loki,轻量
Elasticsearch (ES) 搜索引擎 给每个词都建索引 → 全文搜索无敌,但存储膨胀 3-5 倍
Kibana ES 专属看板 只能连 ES,接不了别的数据源(这是它和 Grafana 的核心差距)
Logstash 日志采集+处理器 ELK 里的采集器,Java 写的吃内存(500MB+),现在基本被 Filebeat/Fluentd 替代
Prometheus 存监控指标的数据库 和 Loki 是同一公司(Grafana Labs),Grafana 接它看 CPU/内存/QPS 曲线
SLS / CLS 云厂商日志服务 阿里云/腾讯云托管,②③④⑤ 全包,不用自己部署
核心对比记住两条
Loki vs ES:Loki 只索引标签(轻),ES 索引每个词(重但全文搜索强)
Grafana vs Kibana:Grafana 啥都接(万能面板),Kibana 只认 ES

3. Loki vs ES:一个例子看懂核心差别

同样是存这条日志:

{"level":"error", "service":"order", "msg":"NullPointerException at line 42"}
ES(Elasticsearch)Loki
建什么索引 给 level、service、NullPointerException、line、42 每个词都建 只给 level=error service=order 两个标签建,msg 内容压缩存
存储成本 1GB 日志 → 3-5GB(索引膨胀) 1GB 日志 → ~0.1-0.3GB(只有标签索引)
查"order 的 error 日志" 秒回(标签有索引) 秒回(标签有索引)
查"含 NullPointerException 的日志" 秒回(每个词都有索引) 慢(得逐条扫描内容,查 24h 可能要 2 分钟)
结论 日常排查 90% 是按"哪个服务 + 什么级别 + 什么时间"查 → Loki 秒回,而且存储只要 ES 的 1/10。只有安全审计要全文搜索关键词这种场景,ES 才不可替代。

4. Grafana 长啥样(界面演示)

Grafana 是深色主题的网页应用。下面模拟一个排查线上 ERROR 的场景:左边选数据源,上面输入查询,下面出日志流。

🍊 Grafana Explore Dashboards Alerting Last 1 hour ▾ · Auto-refresh 10s
Data Sources
🔮 Loki (日志)
📈 Prometheus (指标)
🔍 Elasticsearch
Recent
订单服务日志
监控总览
Loki   {job="order-service"} |= "ERROR" ▶ Run
日志流 (5,234 lines) 按时间倒序
10:30:45.123 ERROR order-service NullPointerException at OrderService.create(OrderService.java:42)
10:30:45.118 ERROR order-service Failed to create order userId=10086 reason=NPE
10:30:44.992 WARN order-service Redis connection timeout, retrying... attempt=3
10:30:44.871 INFO order-service Received POST /api/orders from 192.168.1.50
10:30:43.220 ERROR order-service NullPointerException at OrderService.validate(OrderService.java:88)
ERROR 日志量趋势(叠加 Prometheus CPU 曲线) Last 1h
ERROR 日志量(Loki) CPU 使用率(Prometheus)
关键看点
  • 左侧 sidebar:数据源列表 — Loki(日志)、Prometheus(指标)都在一个 Grafana 里
  • 查询框{job="order-service"} |= "ERROR" — LogQL 语法,先按标签选服务,再过滤关键词
  • 日志流:ERROR 红色、WARN 黄色、INFO 绿色,时间戳对齐,一眼看到问题
  • 趋势图:ERROR 日志量曲线 + CPU 曲线叠加 — 一眼看出 10:30 同时飙升,关联性明摆着
这就是 Grafana 的核心价值:一个页面同时看日志 + 指标,时间轴对齐,不用在 Kibana 和 Prometheus 之间来回切。

🖥️ Grafana 还能干什么(能力全景)

上面只展示了"查日志",Grafana 实际上是个全能可视化平台。下面用实际界面展示它的主要能力:

① Explore(临时查询)
随时输入查询,看结果。就像浏览器里的万能搜索框,想查日志、查指标、查链路都行。上面的界面就是 Explore 页面。
② Dashboard(仪表盘)
把多个面板拼成一个页面。一个 Dashboard = 一张监控大屏,左边放 CPU 曲线,右边放 ERROR 日志量,下面放 QPS 趋势。
③ Alerting(告警中心)
基于查询结果自动告警。"Loki 里 ERROR > 10条/分钟 → 发钉钉消息"、"Prometheus CPU > 90% → 打电话"。所有数据源的告警统一管理
④ Annotations(事件标记)
在图表上标事件点。比如"发布 v1.2.3"、"重启数据库"。排查时一眼看到:CPU 飙高发生在发布后 5 分钟 → 关联明显。

能力一览表:

能力能做什么对应数据源类比
搜日志按服务/级别/关键词/时间范围搜索日志Loki / ES像 Google 搜网页,但搜的是你的日志
看曲线CPU/内存/QPS/延迟等指标的实时曲线图Prometheus像股票行情图,但看的是你的服务器状态
链路追踪一条请求从网关→订单→支付→DB 的完整调用链Tempo / Jaeger像快递物流跟踪,每一步耗时清清楚楚
告警通知异常时自动发短信/电话/钉钉/企微所有数据源像医院的呼叫系统,病人出问题自动叫医生
画仪表盘自由拼接面板,做自己的监控大屏混合像 Excel 图表,但数据是实时的、多来源的
事件标记在图表上标注"发布/重启/扩容"等事件手动或自动在历史曲线上插旗子,方便事后复盘
一句话总结 Grafana 的能力 Grafana = 一个能接所有数据源的可视化平台。你给它什么数据它就能画什么图。接 Loki 看日志、接 Prometheus 看指标、接 Tempo 看调用链、接 MySQL 看业务数据。核心卖点不是某个功能,而是"统一"——不用在 N 个系统之间切换。

5. 通常和什么搭配使用

Loki + Grafana 黄金组合

搭配是啥为啥搭配
Prometheus存监控指标(CPU/内存/QPS)同一生态,Grafana 一个面板同时看 Loki 日志 + Prometheus 指标。这是最常见组合
Tempo / Jaeger链路追踪Grafana 生态,点 traceId 从日志跳到调用链
Alertmanager告警通知Grafana 统一告警中心,日志+指标告警都走这里
MinIO / S3对象存储Loki 把日志压缩成块存对象存储,比 ES 便宜 10 倍

ELK 阵营

搭配是啥为啥搭配
Filebeat轻量采集器替代 Logstash 做采集(Logstash 太重),Go 写的几十 MB 内存
Kafka消息队列日志洪峰时缓冲(如大促),ES 写不过来先扔 Kafka
SkyWalking链路追踪ES 存日志 + SkyWalking 存调用链,traceId 串联
一句话:Loki+Grafana 阵营主打"轻量+统一面板",ELK 阵营主打"全文搜索+生态成熟"。两边的看板(Grafana/Kibana)和采集器(Promtail/Filebeat)不能混用,选了阵营就一条路走到底。

6. 生产上怎么用(3 个典型场景,带界面演示)

🎬 场景 1:线上接口报错,快速定位

现象:用户反馈下单失败,监控显示 order-service 接口 5xx 错误率从 0.1% 飙到 23%。值班同学打开 Grafana。

Step 1 — 打开 Grafana Explore,选 Loki 数据源,输入查询

🍊 Grafana Explore Dashboards Last 30 min ▾
Data Sources
🔮 Loki
📈 Prometheus
🔗 Tempo
Loki   {job="order-service"} |= "ERROR" ▶ Run Query
3,421 lines · returned in 0.8s
10:30:45.123ERRORorder-serviceNullPointerException at OrderService.create(OrderService.java:42)
10:30:45.118ERRORorder-serviceFailed to create order userId=10086 reason=NPE
10:30:44.992WARNorder-serviceRedis connection timeout, retrying... attempt=3
10:30:43.220ERRORorder-serviceNullPointerException at OrderService.validate(OrderService.java:88)

Step 2 — 点开一条 ERROR 日志,看到完整内容和标签(traceId)

🍊 Grafana Last 30 min ▾
labels: job=order-service level=ERROR traceId=abc-123-def-456 host=node-03
10:30:45.123 [ERROR] order-service
NullPointerException at OrderService.create(OrderService.java:42)
Failed to create order userId=10086 reason=NPE

Step 3 — 点击 "Jump to Trace",自动切到 Tempo 数据源看调用链

🍊 Grafana Explore Last 30 min ▾
Data Sources
🔮 Loki
📈 Prometheus
🔗 Tempo (链路追踪)
Tempo   {traceId = "abc-123-def-456"} ▶ Run Query
调用链 api-gatewayorder-servicepayment-servicemysql
15ms ✓ 28ms ⚠️ 3212ms
总耗时 3255ms   (正常 ~100ms)
一眼看出问题:payment-service 耗时 3.2 秒(正常 50ms),是瓶颈。点击 payment-service 那行 → 自动跳回 Loki 看支付服务日志。
最终结论
① 日志显示 order-service 报 NPE → ② traceId 追踪发现支付环节耗时 3.2s → ③ 查支付服务日志发现 DB connection timeout
根因:数据库连接池配置太小 + Redis 超时重试耗尽
从用户反馈到定位根因,2 分钟。没这套系统要 SSH 到 5 台机器 grep,至少 30 分钟。

🎬 场景 2:CPU 飙高,对照日志和指标

现象:告警 order-service CPU 使用率持续 95%+。值班同学打开 Grafana 监控 Dashboard。

Dashboard 全貌:同一页面同时展示指标曲线 + 日志流 + 告警状态

🍊 Grafana Explore order-service 监控 Alerting Last 2h ▾
CPU 使用率
95.2%
⚠️ 告警中
内存使用率
87.1%
正常
QPS
1,234/s
正常
CPU / Memory / QPS — Last 2h
10:30 异常开始
CPU Memory QPS
🔮 Loki: {job="order-service"} |= "ERROR" | logfmt
10:32:01ERRORorderOutOfMemoryError: Java heap space
10:31:55ERRORorderGC overhead limit exceeded
10:31:48WARNorderFull GC took 12.3s, heap usage 94%
10:31:30INFOorderStarting full GC...
一眼看出关联:CPU 曲线在 10:30 开始飙升 → 同一时间下方日志出现 Full GC → 内存不够导致频繁 GC → CPU 被 GC 吃满。
关键:所有信息在同一个页面、同一条时间轴上。Kibana 只能看日志看不到 Prometheus 指标,Prometheus 自带界面只能看指标看不到日志。只有 Grafana 能同时展示。

🎬 场景 3:大促日志洪峰,Kafka 缓冲(ELK 架构)

现象:双 11 凌晨 00:00,日志量从 1GB/h 飙到 50GB/h,ES 写不过来,开始丢日志。

没有 Kafka 的架构(出问题的)

App Filebeat Logstash ES 写不过来!
Filebeat 发太快 → Logstash 处理不过来 → ES 被打满 → 拒绝写入 → Filebeat 重试 → OOM → 丢日志

加上 Kafka 后的架构(扛住的)

App Filebeat Kafka (缓冲) Logstash ES 稳住!
Filebeat 快速写入 Kafka(Kafka 吞吐量极大)→ Logstash 按 ES 承受能力慢慢消费 → 日志有 2-3 分钟延迟但不丢
Kafka 在这里就是"蓄水池":洪峰时水先存在池子里,慢慢放。没有这个池子,洪水直接冲垮下游。
代价:日志有 2-3 分钟延迟(存在 Kafka 里等消费)。对实时性要求不高的日志查询来说完全可以接受。

7. 生产坑与事故

坑 1:Loki 全文搜索慢,排查延误

现象:在 Grafana 输入 {job="order-service"} |= "NullPointerException",查最近 24 小时,转了 2 分钟才返回

原因:Loki 只索引标签不索引内容,全文搜索 = 全量扫描,时间范围越大越慢。

解法

  • 先按标签缩小范围:{job="order-service", level="ERROR"} 再搜关键词
  • 把错误类型打成标签:error_type="NPE",直接按标签查
  • 确实要全文搜索 → 并行部署 ES,重要日志同时送 Loki 和 ES

教训:Loki 不是 ES,全文搜索是弱项。要么缩小范围,要么上 ES。

坑 2:ES 磁盘满,集群变只读

现象:开发把日志级别从 INFO 改成 DEBUG,日志量翻 10 倍。3 小时后 ES 磁盘 95% → 进入只读模式 → 所有日志写入失败

原因:ES 默认 95% 磁盘水位后只读。没有磁盘告警 + 没有日志保留策略。

解法:紧急删旧索引 → 配 ILM 自动清理 7 天前索引 → 加磁盘告警 80% 预警 → 日志级别改回 INFO。

教训:ES 磁盘 = 生命线。必须配 ILM 自动清理 + 磁盘告警 + 日志级别管控。

坑 3:Grafana 告警风暴炸手机

现象:配了 50 条告警规则,ERROR > 10/分钟就告警。某次发布引入 bug,50 条同时触发,每 5 分钟重复一次,10 分钟收 200+ 条短信,手机卡死。

原因:告警没有去重、分组、抑制。

解法:同服务告警合并成一条 → P0 告警抑制同服务 P2/P3 → 同告警 15 分钟不重复 → 分级(P0 电话/P1 短信/P2 即时消息/P3 邮件)。

教训:告警不是越多越好。告警风暴比没告警更可怕 — 会淹没真正重要的告警。

8. FAQ

日志量多大才需要上日志收集系统?
  • 1-3 台机器:SSH + tail -f + grep 够用
  • 4-10 台:开始痛苦,建议上 Loki + Grafana
  • 10+ 台:必须上,否则排查是噩梦
  • 微服务 20+:必须上 + 链路追踪(Tempo/Jaeger)
Grafana 和 Kibana 选哪个?
  • 只用 ES → Kibana(和 ES 深度集成)
  • ES + Prometheus + Loki 混用 → Grafana(一个面板看全部)
  • 从零开始要监控+日志统一 → Grafana(扩展性强)

趋势:越来越多团队从 Kibana 迁到 Grafana,因为统一面板是刚需。

日志要存多久?
  • ERROR:30 天(排查问题)
  • INFO:7-14 天
  • DEBUG:1-3 天(生产通常不开 DEBUG)
  • 审计日志:1 年+(金融 5-7 年,合规要求)

ES 用 ILM 自动删,Loki 用 retention 配置。不要一直存,磁盘费钱。

云日志服务(SLS/CLS)值不值得用?

值得:公司上云 + 不想自己运维 + 日志量中等 → 零运维省心。

不值得:日志量极大(TB/天,账单爆炸)+ 数据合规不能出机房(金融/政务)+ 需要深度定制。

成本对比:日均 100GB 日志,SLS 约 ¥9000/月;自建 Loki 3 台 4C8G 约 ¥1500/月。日志量小用云省心,量大自建便宜。

Spring Boot 怎么打适合日志收集的日志?

JSON 结构化日志 + traceId。传统文本日志:

2026-06-18 10:30:45 ERROR OrderService - NullPointerException at line 42

日志系统要解析这个得用 grok 正则(脆弱、耗 CPU)。

JSON 格式(推荐):

{"@timestamp":"2026-06-18T10:30:45","level":"ERROR","logger":"OrderService","traceId":"abc123","message":"NullPointerException at line 42"}

直接被索引为字段,搜索 level: "ERROR" 秒级返回。配置:logback + logstash-logback-encoder,traceId 通过 MDC 注入。

📋 日志收集方案选型与实战 · 全栈资料库

← 返回场景决策 · 部署运维场景决策