3. 常见丢失原因分析:网络故障、磁盘满、权限问题

说实话,排查了这么多年的日志丢失,真正复杂的情况其实不多。绝大多数丢失,翻来覆去就是三个老朋友:网络断了、磁盘满了、权限错了。我个人习惯把这三项当作排查的“三板斧”,每次先扫一遍,能解决掉八九成的问题。

为什么会这样?你想想看,日志采集本质上是一条数据管道。源头在业务服务器,终点在日志中心或大数据平台。中间任何一截出了岔子,数据就丢了。下面我把这三个问题的表现、根因和判断方法拆开讲。

核心原则:排查丢失时,先看网络和磁盘,这两个占了丢失故障的 80% 以上。权限问题虽然少,但一旦遇上,查起来特别绕。

3.1 网络故障:最隐蔽的“隐形杀手”

网络故障是日志丢失的头号元凶。但奇怪的是,很多时候网络本身并没有完全断开——只是变慢了、不稳定了、或者丢包了。这种“半死不活”的网络状态,排查起来特别费劲。

我在项目中遇到过这么一件事:某天业务方反馈说日志少了 3%,但监控上看所有采集节点都“在线”。最后花了整整两天,才发现是核心交换机的一个端口误码率飙升到了 5%。tcp 连接虽然在,但大量数据包需要重传,采集器的发送缓冲区直接被撑爆了。

网络问题类型 典型表现 排查指标
完全断连 采集器日志持续报 connect refused / timeout tcp 握手失败次数飙升
高延迟 发送耗时暴涨,采集器 backlog 持续增长 网络往返时延 rtt > 500ms
高丢包 应用层收到重复 ack,tcp 重传率 > 2% netstat -s 中重传段数量异常
dns 解析异常 采集器日志报 unknown host dns 解析耗时 > 1s 或解析失败

判断网络问题,我一般用两条命令快速定位:

# 检查 tcp 连接状态和重传
netstat -s | grep -E "retransmit|drop"
# 常见输出示例:
# 2345 segments retransmitted
# 89 segments dropped

# 测试到服务端的连通性和延迟
ping -c 10 your-log-server-ip

如果看到大量 tcp 重传,或者 ping 的丢包率超过 1%,基本就能断定是网络层面的问题了。

小技巧: 我习惯在采集器上同时跑一个简单的 tcpdump 做“黑匣子”。平时不干活,一旦检测到发送队列堆积超过阈值,自动开始抓包 30 秒。这样事后分析的时候,能直接看到重传序列。

3.2 磁盘写满:最容易被忽视的“温水煮青蛙”

磁盘问题有意思了。系统盘明明还剩 200GB,日志怎么就丢了呢?嗯,这里要注意:日志采集器本身可能写本地缓存文件,而这些缓存文件通常跟系统盘不在同一块盘上。

我曾经吃过一个大亏。那次巡检发现日志少了整整 2 个小时,所有采集器都在线,网络正常。查到最后,发现是一台机器的数据盘写满了——采集器的本地 spool 目录(/var/log/spool/agent/)被写爆了。采集器进程没崩,但新来的日志往磁盘上写不进去,直接静默丢弃了。最坑的是,日志文件里只报了一行 write error: no space left on device,然后就安静了。

排查磁盘问题,我建议分三步走:

  1. 检查采集器使用的所有目录——不只看数据盘,还要看日志目录、临时目录、spool 目录
  2. 检查 inode 使用率——有时候磁盘没满,但小文件太多了,inode 用光了,文件一样写不了
  3. 确认采集器的本地缓存策略——是否启用了本地持久化?缓存文件有没有自动清理机制?
# 必查命令集
df -hT  # 看各分区的磁盘使用率
df -i   # 看 inode 使用率
du -sh /path/to/agent/spool/  # 看采集器缓存目录占了多少空间

表格总结了磁盘问题的三种形态:

磁盘故障形态 现象 影响范围
磁盘写满 采集器日志报 write error,缓存目录无法写入 该采集器上所有日志源都可能缺失
inode 耗尽 df -h 显示还有空间,但文件创建失败 新生成的日志文件无法落盘
磁盘 i/o 瓶颈 采集器写文件耗时变长,cpu 的 iowait 飙升 采集速度跟不上日志产生速度,逐步积压直至丢失
避坑指南: 我曾经一台机器上同时跑了 3 个采集器,每个都有独立的 spool 目录,共计 200GB。但系统盘只有 40GB。一开始排查只看了数据盘,死活找不到问题。最后才知道——其中一个采集器的日志输出到系统盘了,把 root 分区填满了,导致所有采集器都无法启动。所以,所有采集器用到的目录都要逐一排查。

3.3 权限问题:看似简单实则坑多

权限问题在日志采集领域非常“阴”。它不像网络或磁盘那样会有明确的报错,很多时候只是静默地跳过某些文件,或者读取到的内容不完整。

常见场景:一个业务系统每天凌晨轮转日志,新生成的日志文件权限是 640,属主是 webapp 用户。而采集器是用 root 之外的一个专用账户跑的,比如 logagent。那么问题来了——新文件生成的前几秒,如果没有被正确授权,采集器根本读不到这个文件。

我记得有一次排查线上日志打点不完整的问题。数据看板上的 pv 曲线每天凌晨 00:05 左右会有一个明显的“塌陷”,持续 3-5 分钟后恢复。查了整整一周,最终定位到:凌晨日志轮转时,新文件创建后 chmod 命令还没执行完,采集器就去读了,发现权限不足直接跳过。等到权限恢复正常时,那几分钟的日志已经丢了。

排查权限问题的命令很简单,但方向要对:

# 检查采集器运行用户
ps aux | grep log-collector

# 检查被采集日志目录的文件权限
ls -la /var/log/your-app/

# 模拟采集器用户能否读取
sudo -u logagent cat /var/log/your-app/access.log.2024-01-01
我的做法: 在采集器上增加一个启动前的“权限自检”步骤。启动时遍历所有配置的日志目录,尝试用当前用户身份读取一个新生成的测试文件。如果发现某个目录不可读,直接打印 warning 级别的日志,而不是静默跳过。

为了让你更直观地理解这三种原因的关系,我画了一张排查流程图:

日志采集丢失常见原因排查流程 收到日志丢失告警 网络连接是否正常? 否 排查网络设备 检查延迟、丢包、连通性 是 磁盘空间/inode/I/O 是否正常? 检查 spool 目录、系统盘、数据盘 否 清理磁盘 / 扩容 清理缓存、调整保留策略 是 采集用户是否有读取权限? 检查日志目录、文件属主和文件权限 否 调整文件/目录权限 赋予采集用户 r+rx 权限 是 排查其他原因 文件轮转、采集器自身 bug 建议按图从左到右、从上到下逐一排查。网络→磁盘→权限,三步走完,90% 的丢失都能找到根因。

3.4 三种原因的交叉影响

这三种原因从来不是孤立发生的。它们经常会互相“勾结”,让排查变得更加复杂。

举个例子:

  • 网络不稳定 → 采集器本地缓存持续堆积 → 磁盘空间被耗尽 → 新日志直接丢弃
  • 磁盘 i/o 达到瓶颈 → 采集器处理速度变慢 → 采集器 socket 缓冲区打满 → 业务侧发送失败
  • 日志轮转 + 权限问题:轮转后新文件权限 640,采集器用户没有进入目录的 x 权限 → 读不到文件

所以排查的时候,不要只盯着一个点。先快速排除明显故障(全量断网、磁盘写满),再深入排查“模糊故障”(偶发性丢包、inode 耗尽、权限间歇性异常)。

一个忠告: 不要过分相信“监控”。很多监控只采集进程的存活状态和 cpu/内存使用率,这些指标在磁盘写满或网络半断开的情况下可能完全正常。我建议你自己写一个 端到端验证脚本——每隔几分钟从配置的日志源里随机读一条记录,模拟采集器行为,确认这条记录确实进入了最终的日志平台。这个验证脚本比任何监控都靠谱。