日志聚合:ELK/Loki 思路与结构化日志

服务一多,日志散落在成百上千个容器里,排查问题变成“登录十台机器 grep”。日志聚合把分散日志集中采集、统一检索;配合链路追踪字段,才能“一条 traceId 串起整条调用链”。本章讲聚合思路、结构化日志与 ELK/Loki 两种典型方案。

先做对一件事:结构化日志

聚合的前提是日志可被机器解析。别再打一堆拼接字符串,统一输出 JSON 结构化日志,字段名固定,采集与检索才有意义。

<!-- logback-spring.xml 片段:JSON 输出 + 关键字段 -->
<appender name="JSON" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="net.logstash.logback.encoder.LogstashEncoder">
        <customFields>{"app":"order-service"}</customFields>
    </encoder>
</appender>

推荐字段(统一命名规范):

{
  "timestamp": "2025-06-01T10:00:00.123Z",
  "level": "WARN",
  "app": "order-service",
  "instance": "10.0.1.11:8080",
  "traceId": "a1b2c3d4e5f6",
  "spanId": "x1y2z3",
  "message": "扣减库存失败,走降级",
  "userId": 10086,
  "costMs": 321
}

规范建议:时间统一 UTC/带时区、traceId/spanId/环境/实例必带、业务上下文(订单号、用户号)作为独立字段而非拼进 message、禁止打印明文口令与敏感数据。

方案一:ELK/EFK

经典组合 Elasticsearch + Logstash + Kibana(采集端常用 Filebeat):

服务容器日志(stdout)
   │
   ▼
Filebeat(轻量采集,逐行/按 JSON 解析)
   │
   ▼
Logstash(可选:清洗、过滤、转换)
   │
   ▼
Elasticsearch(存储 + 倒排索引)
   │
   ▼
Kibana(检索、看板、告警)
  • 优点:全文检索强、生态成熟、Kibana 可视化与告警完善。
  • 缺点:ES 集群资源占用高,日志量大时成本可观。
  • 适用:检索条件复杂、需要长期留存分析、预算充足。

方案二:Loki + Grafana

Grafana Loki 走“标签索引 + 原文存储”路线,采集端为 Promtail,展示复用 Grafana:

容器日志 --> Promtail(打标签) --> Loki(按标签索引)
                                    │
                                    ▼
                         Grafana(LogQL 检索 + 看板,可与指标同屏)
  • 优点:轻量、成本低,与 Prometheus 指标体系天然打通(指标与日志同一界面关联)。
  • 缺点:全文检索能力弱于 ES,复杂分析不如 ELK 灵活。
  • 适用:以“查原文、关联指标”为主的中等规模集群。

选型不必纠结:追求检索与分析能力选 ELK,追求轻量与指标联动选 Loki;两者都要求“结构化 + 打标签”先行。

采集与落地的通用要点

  1. 日志只写 stdout:容器/编排平台统一接管输出,采集器从 stdout 收集,禁止应用自己写文件(多副本下文件管理是灾难)。
  2. 按服务/环境打标签:检索第一刀切 namespace/环境/服务,第二刀切 traceId/时间。
  3. 保留策略分级:近期热数据全量留存,老数据压缩或按服务裁剪,避免成本失控。
  4. 敏感信息脱敏:日志输出前对手机号、令牌等做掩码,采集链路启用传输加密。
  5. 与应用监控联动:日志只是“事后的现场”,要与指标告警配合——先由指标触发告警,再由日志定位根因。

小结

日志聚合三件事:应用侧输出结构化 JSON(带 traceId/业务字段)、采集侧统一入湖并打标签、检索侧按环境-服务-链路 ID 收敛。ELK 强在检索分析,Loki 强在轻量联动;先统一日志规范,再选平台,工具永远排在规范后面。

笔记加载中…