最轻量可控的定时流量记录方案是用ifstat+crontab,需清理表头、对齐时间戳、按天轮转日志、动态获取网卡名、基于/proc/net/dev做增量统计、避免sleep和netstat-i误用,并注意cron环境变量与错误重定向。

用 ifstat + cron 实现定时流量记录
直接写脚本加定时任务是最轻量、最可控的方式,适合长期无人值守统计。关键不是“能不能”,而是“怎么避免日志滚雪球”和“怎么让数据可读”。
-
ifstat输出默认带表头和空行,必须用sed '1,2d'或awk 'NR>2'清掉,否则后续解析会错位 - 时间戳不能靠脚本里
date单独打,要和流量数据对齐——推荐用ifstat -n 1 1 | awk '{print strftime("%Y-%m-%d %H:%M:%S"), $0}'把时间塞进同一行 - 日志文件按天轮转,但别用
logrotate:它可能切在ifstat正在写入时,导致末尾半行损坏;改用脚本开头判断if [ ! -f "$DATE.log" ]; then touch "$DATE.log"; fi - 网卡名别硬写
eth0,用ip -o link show | awk '$2 ~ /:/ {print $2}' | sed 's/://'动态取第一个活跃非 lo 接口
用 /proc/net/dev 做增量累计统计
内核暴露的 /proc/net/dev 是源头数据,每行最后两列是接收/发送总字节数(单位字节),重启归零。想算出某段时间流量,得做减法,不是直接读。
- 第一次采集存个基准值到临时文件,比如
/tmp/dev_base,内容格式:eth0 123456789 987654321 - 后续每次读
/proc/net/dev,用awk提取对应网卡当前值,再减去基准值,得到增量 - 注意字段偏移:前两列是接口名和冒号,真正字节数从第2列(接收)和第10列(发送)开始,不同内核版本列数稳定,但别信“第几列”,用
$2和$10更可靠 - 别用
sleep等间隔采样——系统负载高时sleep可能不准,改用date +%s记录采集时间戳,后期按时间差算速率
避免用 netstat -i 统计实时流量
netstat -i 显示的是自系统启动以来的累计包数和字节数,不是速率。它没法告诉你“过去5秒走了多少MB”,只告诉你“到现在一共收了几个包”。误当实时工具用,结果全是误导。
- 它不支持指定时间窗口,也没有 -t 或 --interval 参数
- 输出中
RX-DRP(接收丢包)、TX-ERR(发送错误)等字段容易被当成流量主体,其实它们是异常指标,数值小才健康 - 如果真要查丢包率,应该用
cat /proc/net/dev | awk '{print $3,$11}'(接收/发送错误数)配合总收发字节数一起看 - 替代方案:要速率就用
ifstat,要连接级明细就用iftop -P -B,别在netstat -i上浪费调试时间
定时任务里别漏掉权限和环境变量
cron 执行时用的是最小化 shell 环境,PATH 很短,ifstat 或 awk 路径找不到是高频报错点。
- crontab 里写绝对路径:
/usr/bin/ifstat而不是ifstat;查路径用which ifstat - 重定向错误要显式处理:
>> /var/log/traffic.log 2>&1,否则 cron 默认邮件告警,没人收件就等于没报错 - 脚本开头加
#!/bin/bash并设set -e,任意命令失败立刻退出,避免中间出错还继续写脏数据 - 测试时先手动跑一遍脚本,再用
run-parts --test /etc/cron.hourly验证 cron 能识别,别等凌晨三点才发现权限拒绝


















