第一原则:日志要结构化

旧:[INFO] 2026-05-09 10:23:45 user 1234 logged in from 1.2.3.4
新:{"ts":"2026-05-09T10:23:45Z","level":"info","event":"login","user_id":1234,"ip":"1.2.3.4"}

非结构化日志靠 grep;结构化日志能按字段过滤、聚合、关联——性能和能力差几个数量级。

每种语言都有结构化日志库:Python structlog / Node pino / Go slog(标准库自 1.21)/ Java Logback + JsonEncoder

三类方案

方案 A:ELK / OpenSearch 栈

应用 → Filebeat / Fluent Bit → Logstash → Elasticsearch → Kibana
  • Elasticsearch:全文索引数据库,给每个字段建倒排索引
  • Logstash:数据加工(过滤 / 转换 / 富化)
  • Kibana:可视化 + 查询
  • Filebeat / Fluent Bit / Fluentd:采集 agent

2021 年 Elastic 改 License,AWS 分叉出 OpenSearch——开源版的 ES。两者 API 大体兼容,新项目优先 OpenSearch(License 干净)。

特点:

  • 全文搜索能力最强
  • 灵活的字段查询和聚合
  • 重——Elasticsearch 吃 CPU + 内存 + 磁盘
  • 索引爆炸:高基数字段进索引会把磁盘吃满

方案 B:Grafana Loki

应用 → Promtail / Fluent Bit → Loki → Grafana

Loki 由 Grafana Labs 出品,借鉴 Prometheus 思路

  • 只对标签做索引(service、env、host 等少量低基数维度)
  • 日志正文不索引,按时间排序压缩存对象存储
  • 查询:先按标签筛到候选块,再在块内 grep

特点:

  • 存储便宜——可以扔到 S3 / R2 / OSS
  • 与 Prometheus / Grafana 体验一致(PromQL 风格的 LogQL)
  • 全文搜索能力弱于 ES——大量正文 grep 慢
  • 适合"标签筛选 + 少量正文 grep"的场景;不适合 SOC 那种全文复杂查询

方案 C:云原生托管

厂商 服务 计费模型常见做法
AWS CloudWatch Logs 按写入量 + 存储量
GCP Cloud Logging 同上
Azure Log Analytics 同上
阿里云 SLS(日志服务) 同上
腾讯云 CLS 同上

特点:

  • 零运维,按量付费
  • 与同云的指标 / 告警 / 安全产品深度集成
  • 写入量大时账单可观——产品成熟后量起来要看明细
  • 跨云搬家麻烦

选型决策

情况 推荐
已重度用 K8s + Grafana Loki
安全 / 审计 / SOC + 复杂全文查询 OpenSearch
全栈在某家云上 + 不想运维 该云的托管日志
多云 + 预算紧 Loki(对象存储便宜)
老 ELK 资产 继续 ES,逐步迁 OpenSearch

没有"全场景最优"。评估一周日志量 + 查询模式比看博客有用。

实操建议

1. 在源头丢

不是所有日志都值得收:

  • 健康检查日志(每秒打一次)→ 默认丢
  • INFO 级别的"业务正常"日志 → 视情况保留 / 不保留
  • DEBUG 级别 → 默认不收,问题时再开

2. 不要把 secret 写进日志

代码里加 redactor:自动去掉 password / token / 信用卡号字段。

3. 加 trace_id 关联

每个请求一个 trace_id(OTel 自动生成),打日志时带上——从 traces 跳到 logs,从 logs 跳回 traces。

4. 容量规划

存储 = 写入速率 × 保留天数 × 压缩比。新项目按估算 × 3 准备空间,业务起来观察实际再调。

推荐阅读

下一篇:把三支柱统一起来——OpenTelemetry。