前言
一、腳本功能
二、實現原理
三、Shell 腳本實現
四、關鍵知識點解析
1. Bash 關聯數組
2. 命令組 { } 與子 Shell ( )
3. 字符串拼接換行
4. 流量計算邏輯
五、測試方法
六、優化建議
七、總結
前言
在生產環境中,監控服務器的 網絡流量 非常重要,尤其是下載/上傳流量突然激增時,需要及時告警。本文將介紹如何使用 Shell 腳本 + msmtp 實現網絡流量監控和郵件告警,并解析其中的關鍵知識點。
一、腳本功能
-
監控指定網卡的下載(RX)和上傳(TX)流量
-
當流量超過閾值(MB)時觸發郵件告警
-
支持多網卡監控
-
可生成日志,記錄每次流量情況
二、實現原理
-
采集網卡流量
Linux 系統中,每個網卡的流量信息在:
/sys/class/net/<網卡名稱>/statistics/rx_bytes # 下載字節數
/sys/class/net/<網卡名稱>/statistics/tx_bytes # 上傳字節數
這些值是 累計字節數。
-
計算流量
公式:
實際流量 = 第二次采樣值 - 第一次采樣值
-
RX = 下載流量(字節)
-
TX = 上傳流量(字節)
-
轉換為 MB:
RX_MB = RX / 1024 / 1024
-
告警觸發
-
當 RX_MB 或 TX_MB ≥ 閾值時,拼接告警信息
-
通過
msmtp
發送郵件
-
日志記錄
-
每次采樣后的流量記錄到日志文件
-
告警信息也記錄到日志
三、Shell 腳本實現
#!/bin/bash#要監控的網卡列表 NET_LIST=("eth0") #設置閾值(MB) NET_WARNING=0 #采集時間 TIME=5 #設置日志文件位置 LOG_FILE="/var/log/net_warning.log" #設置收件人 MAIL_TO="3426848201@qq.com,2270993679@qq.com" #設置標題 TITLE="網絡流量告警" #設置發送郵件函數 send_file(){local msg="$1"{echo "Subject: $TITLE"echo "To: $MAIL_TO"echoecho -e "$msg"} | msmtp -t } #設置日志函數 log(){local msg="$1"echo -e "$(date +"%F %T") $msg" >> "$LOG_FILE" } #設置關聯數組用于保存采集數據 #關聯數組可以使用字符串作為索引 declare -A RX_BYTES_1 declare -A TX_BYTES_1 declare -A RX_BYTES_2 declare -A TX_BYTES_2 #進行第一次采集 for IF in "${NET_LIST[@]}"; doRX_BYTES_1[$IF]=$(cat /sys/class/net/$IF/statistics/rx_bytes)TX_BYTES_1[$IF]=$(cat /sys/class/net/$IF/statistics/tx_bytes) done #等待60秒再進行采集,確保數據合理穩定 sleep $TIME #進行第二次采集 for IF in "${NET_LIST[@]}"; doRX_BYTES_2[$IF]=$(cat /sys/class/net/$IF/statistics/rx_bytes)TX_BYTES_2[$IF]=$(cat /sys/class/net/$IF/statistics/tx_bytes) done #設置空變量用于保存告警信息 ALERT_MSG="" #進行流量計算,判斷閾值 #計算公式為 #實際下載流量 = 第二次采樣下載字節數 - 第一次采樣下載字節數 #實際上傳流量 = 第二次采樣上傳字節數 - 第一次采樣上傳字節數 #1MB = 1024x1024字節,RX/TX計算的默認為字節數,所以需要/1024/1024換算成MB for IF in "${NET_LIST[@]}"; doRX=$((RX_BYTES_2[$IF] - RX_BYTES_1[$IF]))TX=$((TX_BYTES_2[$IF] - TX_BYTES_1[$IF]))RX_MB=$((RX / 1024 / 1024))TX_MB=$((TX / 1024 / 1024))log "接口 $IF: 下載${RX_MB}MB, 上傳${TX_MB}MB"if [ $RX_MB -ge $NET_WARNING ]; thenALERT_MSG+="接口 $IF 下載流量超限: ${RX_MB}MB"$'\n'fi?if [ $TX_MB -ge $NET_WARNING ]; thenALERT_MSG+="接口 $IF 上傳流量超限: ${TX_MB}MB"$'\n'fi? done #發送郵件進行告警 if [ -n "$ALERT_MSG" ]; then#調用log和send_file函數將告警信息傳遞給$1,通過send_file函數發送郵件log "觸發告警:\n$ALERT_MSG"send_file "$ALERT_MSG" fi
四、關鍵知識點解析
1. Bash 關聯數組
declare -A RX_BYTES_1
-
可以用 字符串索引(網卡名)保存數據
-
示例:
RX_BYTES_1["eth0"]=123456
2. 命令組 { }
與子 Shell ( )
{ echo "Subject: $TITLE"
echo "To: $MAIL_TO"
echo
echo -e "$msg" } | msmtp -t
-
{ ... }
在 當前 shell 執行,不創建子 shell -
(...)
會在 子 shell 執行,變量修改不會影響外部
3. 字符串拼接換行
ALERT_MSG+="接口 $IF 下載流量超限: ${RX_MB}MB"$'\n'
-
$'\n'
生成實際換行字符 -
echo -e "$ALERT_MSG"
可正確顯示換行
4. 流量計算邏輯
RX=$((RX_BYTES_2[$IF] - RX_BYTES_1[$IF]))
TX=$((TX_BYTES_2[$IF] - TX_BYTES_1[$IF]))
-
計算兩次采樣的差值
-
單位是字節(Bytes),轉換 MB 后用于判斷閾值
五、測試方法
為了測試腳本功能,可以 臨時降低閾值和縮短采樣間隔:
NET_WARNING=1 # 閾值 1MB,方便觸發
TIME=5 # 采樣間隔 5 秒
-
執行腳本:
sh NetWork上傳下載監控.sh
-
生成日志:
cat /var/log/net_warning.log
-
檢查郵件是否收到
-
可以用下載或上傳測試流量:
wget http://speedtest.tele2.net/10MB.zip -O /dev/null
curl -T localfile
ftp://ftpserver/ --user user:pass
-
測試完成后,恢復正式閾值和采樣間隔
六、優化建議
-
日志按天生成,避免過大
-
支持多個收件人
-
可通過命令行參數調整網卡列表和閾值
-
可通過 cron 定時執行,實現 持續監控
七、總結
-
利用
/sys/class/net/.../statistics/
獲取網卡累計流量 -
關聯數組保存采樣數據,計算兩次差值得到實際流量
-
用
$'\n'
拼接告警信息,并通過msmtp
發送郵件 -
日志記錄每次采樣及告警信息
-
可以通過調整閾值和采樣間隔快速測試腳本