跳到主要内容

日志收集系统设计

问题

如何设计一个分布式日志收集与分析系统?

答案

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: 如何通过日志快速定位问题?

答案

  1. 通过 traceId 串联整条请求链路
  2. Kibana 按 traceId 搜索,查看所有服务的日志
  3. 按时间排序,定位错误发生的具体环节

Q3: 日志量太大怎么办?

答案

  • 采样:非关键日志只保留 10%
  • 日志分级:生产环境 INFO 及以上
  • 索引生命周期:自动删除 30 天前的日志

相关链接