开发工具

如何检测网卡流量,并按规定格式记录在日志中?

以下是一个用于检测网卡流量并按指定格式记录日志的Shell脚本,支持自定义监控间隔、网卡选择和日志轮转功能:

#!/bin/bash
# 网卡流量监控脚本
# 日志格式:时间戳,网卡名称,接收流量(KB),发送流量(KB),总流量(KB)

# 配置参数
INTERFACE="eth0"       # 监控的网卡名称
LOG_DIR="/var/log/network"   # 日志存放目录
LOG_NAME="traffic.log"    # 日志文件名
MAX_LOG_DAYS=30        # 日志保留天数
INTERVAL=10          # 监控间隔(秒)

# 创建日志目录
mkdir -p "$LOG_DIR"

# 初始化流量计数器
declare -A prev_bytes
init_counters() {
    while read dev rbytes tbytes; do
        prev_bytes["$dev"]="$rbytes:$tbytes"
    done < <(grep "$INTERFACE" /proc/net/dev | awk '{print $1,$2,$10}')
}

# 获取当前流量
get_traffic() {
    local curr_rbytes curr_tbytes
    read curr_rbytes curr_tbytes < <(grep "$INTERFACE" /proc/net/dev | awk '{print $2,$10}')
    echo "$curr_rbytes $curr_tbytes"
}

# 计算流量差值(KB)
calculate() {
    local prev=$1 curr=$2
    local diff=$(( (curr - prev) / 1024 ))
    echo $diff
}

# 生成时间戳
timestamp() {
    date '+%Y-%m-%d %H:%M:%S'
}

# 日志轮转管理
manage_logs() {
    find "$LOG_DIR" -name "*.log" -mtime +$MAX_LOG_DAYS -delete
}

# 主监控循环
main() {
    echo "时间戳,网卡名称,接收流量(KB),发送流量(KB),总流量(KB)" >> "$LOG_DIR/$LOG_NAME"
    
    init_counters
    while true; do
        sleep $INTERVAL
        
        # 获取当前流量
        read curr_rbytes curr_tbytes < <(get_traffic)
        
        # 解析上一次值
        IFS=':' read prev_rbytes prev_tbytes <<< "${prev_bytes[$INTERFACE]}"
        
        # 计算增量
        rdiff=$(calculate $prev_rbytes $curr_rbytes)
        tdiff=$(calculate $prev_tbytes $curr_tbytes)
        total=$(( rdiff + tdiff ))
        
        # 记录日志
        echo "$(timestamp),$INTERFACE,$rdiff,$tdiff,$total" >> "$LOG_DIR/$LOG_NAME"
        
        # 更新计数器
        prev_bytes["$INTERFACE"]="$curr_rbytes:$curr_tbytes"
        
        # 每日0点执行日志管理
        if [ $(date +%H%M) == "0000" ]; then
            manage_logs
        fi
    done
}

# 异常处理
trap "echo '监控被用户中断'; exit 0" SIGINT
trap "echo '发生未捕获错误'; exit 1" ERR

# 执行主函数
main


使用说明

1、配置参数调整

修改 INTERFACE 为目标网卡(通过 ip link 查看可用网卡)

调整 INTERVAL 监控频率(建议≥5秒)


2、首次运行授权

chmod +x net_monitor.sh
sudo ./net_monitor.sh  # 需要root权限读取/proc文件


3、查看实时日志

tail -f /var/log/network/traffic.log

日志格式示例

时间戳,网卡名称,接收流量(KB),发送流量(KB),总流量(KB)
2023-10-05 14:30:00,eth0,1024,2048,3072
2023-10-05 14:30:10,eth0,512,4096,4608



扩展功能

1. 多网卡监控

修改主函数支持多个网卡:

INTERFACES=("eth0" "wlan0")
main() {
    for intf in "${INTERFACES[@]}"; do
        # 采集每个网卡数据
    done
}


2. 动态单位转换

增加智能单位显示:

format_bytes() {
    local bytes=$1
    if [ $bytes -gt 1048576 ]; then
        echo "$(( bytes/1048576 )) GB"
    elif [ $bytes -gt 1024 ]; then
        echo "$(( bytes/1024 )) MB"
    else
        echo "$bytes KB"
    fi
}


3. 告警阈值

添加流量超限通知:

ALERT_THRESHOLD=100000  # 100MB
if [ $total -gt $ALERT_THRESHOLD ]; then
    echo "流量超标警告:$total KB" | mail -s "网络告警" admin@example.com
fi


部署建议

1、后台运行

nohup sudo ./net_monitor.sh > /dev/null 2>&1 &


2、系统服务化

创建systemd服务文件 /etc/systemd/system/netmon.service:

[Unit]
Description=Network Traffic Monitor

[Service]
ExecStart=/usr/local/bin/net_monitor.sh
Restart=always

[Install]
WantedBy=multi-user.target



注意事项

1、精度误差

采样间隔越短精度越高,但会增加系统负载

1024进制转换会产生小数误差


2、虚拟化环境

KVM/Xen等虚拟网卡需特殊处理(过滤virbr、vnet前缀)


3、容器网络

Docker创建的veth设备需要额外监控逻辑


通过此脚本可实现企业级网络流量监控,数据可直接导入Excel/PowerBI生成流量趋势图,或对接Zabbix等监控平台实现可视化告警。