日志聚合
把所有服务日志集中到带保留、搜索和告警的单一聚合器。
为什么
本地盘上日志事件中不可见 — 崩的 pod 没了、自动扩缩终结实例、值班无法 SSH 到不存在的机。日志聚合器(Loki、Datadog、ELK、CloudWatch)实时从所有服务摄入日志,故日志活过 pod 死且可从单窗查询。这是"日志没了"和"50ms 查过去 5m checkout ERROR 日志"之差。聚合器也提供保留(30-90 天供事件取证)、搜索(结构化查询非 grep)和告警(按日 志模式告警非仅指标)。无聚合每事件以"日志在哪?"开始 — 有它日志就在那、可查询、值班跳 10 分钟 hunting 直诊断。
何时使用
第一天。无日志聚合的服务是你无法在 prod 调试的服务。
如何做
1. 选聚合器并从所有服务发日志
- Loki(Grafana 栈,便宜,结构化日志好)、Datadog(付费,全功能)、
ELK(自托管,强但运维重)、CloudWatch(AWS 原生)
- 经 agent(Promtail、Fluentd、Datadog agent)或直接从 app 发
2. 强保留策略
- 7-30 天热(可查询、快)、90 天温(可查询、慢)、1-7 年冷(合规)
- 热保留贵;别保 90 天热除非你常查那么远
3. 使日志按要紧字段可查询
- 按以下索引或标签:service、level、trace_id、route、status_code
- 别全索引(贵);索引你查询的字段
4. 为常见事件模式建保存查询
- "过去 5m checkout 错误":{service="checkout", level="ERROR"} | last 5m
- "慢请求":{latency_ms > 1000} | last 1h
- 事件中值班跑保存查询非自定义
5. 按日志模式告警,非仅指标
- "ERROR 率 > 1/s 持续 5m" → page
- "特定错误消息出现" → page(如"DB connection refused")
- 日志抓指标漏的失败(如不动错误率指标的罕见错误)示例
# 日志聚合架构:
App → logger(JSON)→ Promtail → Loki → Grafana(查询/仪表盘/告警)
↓
Datadog agent → Datadog(若两者都用)
# 保留策略(Loki):
retention:
hot: 30 天 # 快查询,贵存储
warm: 90 天 # 慢查询,便宜
cold: 7 年 # 合规,少查
# 保存查询(Grafana):
- name: "checkout-errors-5m"
query: '{service="checkout", level="ERROR"} |= "" | last 5m'
- name: "slow-requests-1h"
query: '{latency_ms > 1000} | last 1h'
- name: "db-connection-refused"
query: '{msg=~"DB connection refused"} | last 15m'
# 按日志模式告警(非仅指标):
- alert: CheckoutDbConnectionRefused
expr: count_over_time({service="checkout", msg=~"DB connection refused"}[5m]) > 0
annotations:
runbook_url: "https://rb/checkout-db-failover"
# 这抓特定失败即使错误率指标未破常见问题
- ⚠仅本地盘日志 — pod 崩、日志没、事件以"日志在哪?"开始。
- ⚠无保留策略 — 日志 3 天过期,故一周后复盘看不到发生了什么。
- ⚠全字段索引 — 存储成本爆;仅索引你查询的字段(service、level、trace_id)。
- ⚠仅指标告警无日志告警 — 罕见错误(DB connection refused)不动错误率指标但仍是失败;也按日志模式告警。
最佳实践
- ✓实时从所有服务发日志到中央聚合器(Loki、Datadog、ELK);日志活过 pod 死且可从单窗查询。
- ✓设分层保留策略(热 30d、温 90d、冷 7y 合规);别全热 — 贵。
- ✓仅索引你查询的字段(service、level、trace_id、route);为常见事件模式建保存查询使值班跑非写查询。
- ✓除指标外按日志模式(特定错误消息、按服务错误率)告警;日志抓指标漏的失败。