日志丢失排查
问题
开发反馈在 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 配置适当延长 |
| Kafka | Topic 保留时间过短 | 调大 retention.ms |
| Logstash | 解析失败丢弃 | 配置 dead_letter_queue |
| ES | 写入被拒 | 增加写入线程池、扩容节点 |
| ES | ILM 策略删除 | 调整保留天数 |
| Kibana | 时间范围/索引选择错误 | 检查查询条件 |
常见面试问题
Q1: 如何保证日志采集链路不丢数据?
答案:
- Kafka 缓冲:Filebeat → Kafka → Logstash,Kafka 作为缓冲层,解耦采集和处理
- Filebeat at-least-once:Filebeat 基于 registry 记录 offset,重启后继续采集(可能重复但不丢)
- Kafka 多副本:
replication.factor=3,min.insync.replicas=2 - Logstash 持久化队列:启用
queue.type: persisted,崩溃恢复后重新处理 - ES 写入重试:Logstash output 配置
retry_on_conflict - 端到端监控:对比应用日志行数 vs ES 文档数,差异超阈值告警