生产实践:
使用Shell脚本调用iftop统计服务器外网流量
学习技巧:
Shell 循环,awk统计,iftop、nethogs、lsof工具使用
脚本内容:
通过iftop排除内网连接,监控进程外网上下行流量,iftop最小是2s统计一次,脚本取的是last 10s,要想到达ms级得改iftop源码,用shell脚本结合awk做了个简单的统计和分析,同时用nethogs工具抓所有进程流量配合使用,后面觉得有点麻烦整了个python脚本输出json格式通过filebeat收集到kafka(Python脚本监控服务器进程上下行流量),通过程序来做展示和分析了。
iftop 外网流量监控脚本:
#!/bin/bash LOGFILE="/root/iftop_network_$(date +%F).log" # 使用 iftop 获取网络流量信息 while true; do echo "------------------------`date +%F\ %T`-----------------------------" >> ${LOGFILE} iftop -i eth0 -tnNP -f "not src net 192.168.0.0/16 and not port ssh and not port ntp and not port 53 or not dst net 192.168.0.0/16 and not port 53 and not port 123 and not host 114.114.114.114" -L 500 -s 3 >> /tmp/iftop_network sleep 2 # 从 iftop 输出文件中提取本地端口 local_ports=$(grep 192.168 /tmp/iftop_network | awk -F'[ \t:]+' '{print $4}' | grep -E "^[0-9]+$") #echo $local_ports # 使用 lsof 查找对应的进程名 for port in $local_ports; do process_name=$(timeout 5s lsof -i :$port | awk 'NR>1 {print $1"/"$2}') echo "本地端口: $port, 进程名/PID: $process_name" >> /tmp/port_process done cat /tmp/iftop_network /tmp/port_process >> ${LOGFILE} >/tmp/iftop_network >/tmp/port_process done
使用 nethogs 监控进程网络流量:
#!/bin/bash LOGFILE="/root/net_process.log" # 使用 nethogs 获取进程网络流量信息 while true; do echo "-------------------------------------`date +%F\ %T`----------------------------------" >> ${LOGFILE} nethogs -t -d 3 -c 5 | egrep -v "^$|^192|^127|^172|^unknown|^Refreshing|^Adding|^Ethernet|^Waiting|^2023|^sshd" &>> ${LOGFILE} sleep 10 done
统计分析进程上行流量:
#!/bin/bash network_log="$1" # 获取iftop统计的外网流量 >/tmp/net_outputs.txt address=`cat ${network_log} | egrep -v '192.168.1.+' | egrep -o "\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[0-1][0-9]|22[0-3])\>(\.\<([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>){3}"|sort|uniq` echo $address for i in $address ; do echo $i sed -n '/'"$i"'/{g;1!p;};h' ${network_log}| awk '{print "'"$i"'""\t"$6}' >> /tmp/net_outputs.txt done # 统计平均流量 awk -v OFS="," '{sent[$1]+=/Mb/?$2*1024:(/Kb/?$2:(/b/?$2/1000:$2));counts[$1]++;}END{for (i in sent){print i,sent[i]/counts[i],counts[i],sent[i]}}' /tmp/net_outputs.txt | sort -t',' -k2 -rn echo # 统计最大流量Mb egrep "Mb" /tmp/net_outputs.txt |sed 's/Mb//gp' |awk '{ if ($2 > max[$1]) { max[$1] = $2; line[$1] = $0; } } END { for (key in line) { print line[key]"Mb/s"; } }' echo # 统计最大流量Kb egrep "Kb" /tmp/net_outputs.txt |sed 's/Kb//gp' |awk '{ if ($2 > max[$1]) { max[$1] = $2; line[$1] = $0; } } END { for (key in line) { print line[key]"Kb/s"; } }'
参考: