日志收集系统设计
问题
如何设计一个分布式日志收集与分析系统?
答案
ELK 架构
日志分级与格式
结构化日志(JSON 格式)
// logback-spring.xml 配置 JSON 输出
// 每条日志包含:时间、级别、traceId、服务名、类名、消息
{
"timestamp": "2026-03-27T10:30:00.123Z",
"level": "ERROR",
"traceId": "abc123def456",
"service": "order-service",
"class": "OrderService",
"message": "创建订单失败",
"exception": "java.lang.NullPointerException...",
"userId": "10086"
}
链路追踪集成
通过 MDC 传递 traceId
// 请求入口统一设置 traceId
@Component
public class TraceFilter implements Filter {
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain)
throws IOException, ServletException {
String traceId = ((HttpServletRequest) req).getHeader("X-Trace-Id");
if (traceId == null) traceId = UUID.randomUUID().toString().replace("-", "");
MDC.put("traceId", traceId);
try {
chain.doFilter(req, resp);
} finally {
MDC.clear();
}
}
}
ES 索引策略
| 策略 | 说明 |
|---|---|
| 按天分索引 | logs-2026.03.27,便于清理过期数据 |
| 冷热分离 | 7 天内的在 SSD(热节点),超过 7 天迁移到 HDD(冷节点) |
| 索引生命周期 | ILM 自动管理:Hot → Warm → Cold → Delete |
常见面试问题
Q1: 为什么用 Kafka 作为缓冲?
答案:
日志量突增时 Kafka 做削峰填谷,防止 Logstash/ES 被打垮。Kafka 高吞吐、持久化,且支持多消费者。
Q2: 如何通过日志快速定位问题?
答案:
- 通过 traceId 串联整条请求链路
- Kibana 按 traceId 搜索,查看所有服务的日志
- 按时间排序,定位错误发生的具体环节
Q3: 日志量太大怎么办?
答案:
- 采样:非关键日志只保留 10%
- 日志分级:生产环境 INFO 及以上
- 索引生命周期:自动删除 30 天前的日志