跳到主要内容

日志丢失排查

问题

开发反馈在 Kibana 上查不到某些时间段的日志,或日志条数与预期不符,如何排查?

答案

排查方向:沿着日志链路逐段排查

每个环节都可能丢日志,需要逐段排查

Step 1:确认应用确实写了日志

# 在应用服务器上确认日志文件存在且有内容
ls -lt /var/log/app/*.log | head -5
wc -l /var/log/app/app.log

# 按时间过滤,确认问题时段是否有日志
grep "2024-01-15 14:3" /var/log/app/app.log | wc -l

# 如果这里就没日志 → 应用层问题(日志级别、限流、磁盘满)

Step 2:检查 Filebeat 采集

# 查看 Filebeat 采集状态
# Filebeat 记录了每个文件的 offset
cat /var/lib/filebeat/registry/filebeat/data.json | \
python3 -m json.tool | grep -A 5 "app.log"

# 查看 Filebeat 日志
journalctl -u filebeat --since "1 hour ago" | grep -i "error\|drop\|harvester"

# 常见问题:
# - Harvester 达到上限(harvester_limit)
# - 文件被 logrotate 后 Filebeat 没跟上
# - 磁盘 IO 高导致采集延迟

Step 3:检查 Kafka

# 查看 Topic 的 lag(消费延迟)
kafka-consumer-groups.sh --bootstrap-server kafka:9092 \
--describe --group logstash-group

# 如果 LAG 很大 → Logstash 消费赶不上

# 查看 Topic 数据量
kafka-run-class.sh kafka.tools.GetOffsetShell \
--broker-list kafka:9092 \
--topic app-logs \
--time -1 # 最新 offset

# 检查 Kafka Broker 是否有问题
kafka-log-dirs.sh --bootstrap-server kafka:9092 --describe

Step 4:检查 Logstash

# 查看 Logstash 日志
journalctl -u logstash --since "1 hour ago" | grep -i "error\|drop\|dead"

# 常见问题:
# 1. Grok 解析失败 → 日志被发到 dead_letter_queue
# 2. ES 写入被拒(429 Too Many Requests)→ ES 过载
# 3. Logstash pipeline 管道阻塞

# 查看 Logstash 监控 API
curl localhost:9600/_node/stats | python3 -m json.tool
# 关注 events.filtered 和 events.out 是否一致

Step 5:检查 Elasticsearch

# 查看集群健康
curl localhost:9200/_cluster/health?pretty

# 查看写入被拒次数
curl localhost:9200/_nodes/stats/thread_pool | \
python3 -c "
import sys, json
data = json.load(sys.stdin)
for node_id, node in data['nodes'].items():
rejected = node['thread_pool']['write']['rejected']
print(f'{node[\"name\"]}: write rejected = {rejected}')
"

# 查看索引文档数
curl "localhost:9200/app-logs-2024.01.15/_count?pretty"

# 查看 ILM 策略是否删除了数据
curl "localhost:9200/_ilm/policy/logs-policy?pretty"

常见日志丢失原因

环节原因解决方案
应用日志级别配置错误检查 log4j / logging 配置
应用磁盘满写入失败监控磁盘,logrotate
Filebeat文件轮转后丢失close_inactive 配置适当延长
KafkaTopic 保留时间过短调大 retention.ms
Logstash解析失败丢弃配置 dead_letter_queue
ES写入被拒增加写入线程池、扩容节点
ESILM 策略删除调整保留天数
Kibana时间范围/索引选择错误检查查询条件

常见面试问题

Q1: 如何保证日志采集链路不丢数据?

答案

  1. Kafka 缓冲:Filebeat → Kafka → Logstash,Kafka 作为缓冲层,解耦采集和处理
  2. Filebeat at-least-once:Filebeat 基于 registry 记录 offset,重启后继续采集(可能重复但不丢)
  3. Kafka 多副本replication.factor=3min.insync.replicas=2
  4. Logstash 持久化队列:启用 queue.type: persisted,崩溃恢复后重新处理
  5. ES 写入重试:Logstash output 配置 retry_on_conflict
  6. 端到端监控:对比应用日志行数 vs ES 文档数,差异超阈值告警

相关链接