你们的服务是怎么做日志收集的?
- 标签:Spring Cloud、微服务、后端、日志采集
🏛 业务架构师
我们的日志收集走的是业界标准的 ELK/EFK 体系,链路是"采集 → 传输 → 存储 → 查询 → 告警"五段:
- 应用层规范:统一 JSON 结构化日志(Logback + logstash-logback-encoder),字段标准化——timestamp、level、service、traceId、userId、bizOrderNo。日志规范是公司级约定,业务关键动作用 bizOrderNo(业务单号)串联,让日志能回答业务问题而不只是技术问题;
- 采集:K8s 环境用 DaemonSet 方式部署 Filebeat/Fluent-bit,收集容器 stdout 和文件日志——应用零侵入;
- 传输与缓冲:发到 Kafka 削峰——日志洪峰(大促、异常循环打日志)不直接打垮存储层,这一层是可用性的关键;
- 存储:Logstash 消费后写 Elasticsearch,按天建索引 + ILM 生命周期管理(热 7 天/温 30 天/冷 90 天后删除)——存储成本必须治理,不设生命周期的 ES 会被日志费用拖死;
- 查询与告警:Kibana 检索排障(traceId 一搜全链路日志,与链路追踪系统打通);关键错误(资损类、超时率)配置告警规则接值班。
架构师视角的三个要点:
- 日志分级治理:ERROR 必须可行动(出现即告警)、INFO 控制数量(一条请求 3-5 条为宜)——日志是成本项,更是排障资产,两个属性要平衡;
- 日志与 metrics/tracing 三支柱分工:日志记细节、指标看趋势、链路定位段——不重复建设;
- 敏感信息(手机号、身份证、卡号)脱敏在输出端强制处理,合规是底线。
🏗 系统架构师
我的标准架构:
应用(logback 滚动文件,JSON 结构化加 traceId 字段)→ 采集 Agent(Filebeat/Fluent-bit,K8s Daemonset 挂日志目录)→ Kafka 缓冲(削峰加解耦,采集与存储故障互不传染)→ 处理(Logstash/Vector 解析富化)→ 存储检索(Elasticsearch 或 Loki)→ Grafana/Kibana 查询告警。
关键设计决策:
- 结构化优先:JSON 日志免解析、字段可索引;traceId 必打——日志与链路系统联动是排障效率的分水岭;
- 存储成本分层:ES 贵在索引;Loki 便宜(标签索引加对象存储)。我的组合:运维排障日志进 ES 保留 7~30 天热数据;审计合规日志转对象存储留一年以上;Debug 级常态关闭、按需动态开启;
- Kafka 是稳定器:下游故障时日志暂存不丢,同时支持多订阅(实时告警加批量入仓);
- 应用侧纪律:异步 appender(不阻塞业务线程)、日志分级限流(防日志风暴打爆采集链路)、容器环境 stdout 与 Daemonset 方案统一。
💻 全栈开发专家
ELK/EFK 体系是标准答案,我讲我们的完整链路和细节:
采集链路:应用 logback 滚动文件 → Filebeat(轻量采集、背压控制)→ Kafka(削峰缓冲,日志洪水不冲垮存储)→ Logstash(解析富化)→ Elasticsearch/ClickHouse(存储)→ Kibana 检索。轻量替代:Grafana Loki(只索引标签,成本约 1/10,配 LogQL)。
生产细节(吃过亏总结的):
- JSON 结构化输出:logback 编码器直接出 JSON(带 trace_id/tenant/level),省掉 Logstash grok 解析,出错率低
- traceId 必打:pattern 里
%X{trace_id},链路方案(Micrometer Tracing/SkyWalking)自动注入 MDC——日志和 trace 打通后才叫可观测 - 滚动与磁盘:按大小+时间滚动、保留 7~30 天、
maxHistory+totalSizeCap双限制——没有上限的日志曾把宿主机磁盘打满连累同机所有 Pod - 异步 appender 防日志阻塞业务线程,配好丢弃策略
- 敏感信息脱敏在 logback 转换器层统一做(手机号、身份证),不靠业务自觉
排障常用姿势:按 trace_id 一键捞全链路日志;error 日志接告警规则。