跳到主要内容

日志排查与分析

问题

线上出现异常/告警,如何通过日志快速定位问题?ELK 日志系统怎么用?

答案

日志排查基本功

Linux 日志排查常用命令
# 实时查看日志
tail -f app.log

# 查看最近 100 行
tail -100 app.log

# 搜索错误日志
grep -i "error\|exception" app.log | tail -20

# 按时间范围查找
grep "2024-01-15 10:2[0-9]" app.log

# 统计错误次数
grep "ERROR" app.log | wc -l

# 统计错误类型排名
grep "Exception" app.log | awk -F: '{print $NF}' | sort | uniq -c | sort -rn | head 10

# 查看某个请求的完整日志(按 TraceId)
grep "trace-id-12345" app.log

结构化日志

Logback JSON 格式配置
// 结构化日志比纯文本更利于 ELK 检索
{
"timestamp": "2024-01-15T10:23:45.123",
"level": "ERROR",
"logger": "c.e.s.OrderService",
"message": "创建订单失败",
"traceId": "abc-123-xyz",
"userId": "10086",
"orderId": "ORD20240115001",
"exception": "java.lang.NullPointerException",
"stackTrace": "..."
}
logback-spring.xml JSON 输出
<appender name="JSON" class="ch.qos.logback.core.rolling.RollingFileAppender">
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<customFields>{"app":"order-service","env":"prod"}</customFields>
</encoder>
</appender>

ELK 日志系统

Kibana 常用查询语法(KQL)
# 查询某个 TraceId
traceId: "abc-123-xyz"

# 查询错误日志
level: "ERROR"

# 组合查询
level: "ERROR" AND app: "order-service" AND message: "创建订单失败"

# 时间范围
@timestamp >= "2024-01-15T10:00:00" AND @timestamp <= "2024-01-15T11:00:00"

# 模糊查询
message: *timeout*

链路追踪 + 日志

MDC 传递 TraceId
// 拦截器:请求进入时设置 TraceId
public class TraceInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, ...) {
String traceId = request.getHeader("X-Trace-Id");
if (traceId == null) traceId = UUID.randomUUID().toString();
MDC.put("traceId", traceId);
return true;
}

@Override
public void afterCompletion(...) {
MDC.clear();
}
}
日志模板中使用 TraceId
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{traceId}] %-5level %logger{36} - %msg%n</pattern>

告警日志分析

日志告警规则
// 1 分钟内 ERROR 超过 10 条 → 告警
// 5 分钟内同一异常超过 50 次 → 告警
// 出现 OOM / StackOverflow → 立即告警

常见面试问题

Q1: 线上问题无法复现,怎么通过日志排查?

答案

  1. 拿到 TraceId → ELK 搜索完整调用链日志
  2. 看请求参数、中间步骤、返回值
  3. 看前后时间段是否有 GC / 慢 SQL / 超时
  4. 对比正常请求和异常请求的差异

Q2: 日志级别怎么设置?

答案

级别用途生产环境
ERROR影响功能的异常✅ 必须
WARN潜在问题✅ 建议
INFO关键业务流程✅ 适量
DEBUG调试信息❌ 关闭

Q3: 日志打太多怎么办?

答案

  • 生产环境关闭 DEBUG
  • 使用采样日志(每 N 条打一条)
  • 异步写日志(AsyncAppender)
  • 日志分级存储:ERROR 保留更久

相关链接