proc与awk实时网卡流量监控
通过/proc/net/dev该文件可以获取所有网卡的时时数据信息。通过/sys/class/net/下的文件同样可以获取每块网卡更详细的信息。在cnblogs博客园上看到程默的博客中有一篇使用awk 程序精妙的搞了一个网卡实时流量监控脚本。程序虽然写的非常不错,不过统计的只是网卡向外发送的实时流量情况,我没事也搞了一个脚本,可以实时监控所有网卡的rx、tx及总的流量情况。
一、/proc/net/dev文件介绍
查看该虚拟文件得到的信息如下:
1[root@361way ~]# cat /proc/net/dev|column -t
2Inter-| Receive | Transmit
3face |bytes packets errs drop fifo frame compressed multicast|bytes packets errs drop fifo colls carrier compressed
4lo: 30288411132 22091019 0 0 0 0 0 0 30288411132 22091019 0 0 0 0 0 0
5eth0: 3368488625 73197048 0 0 0 0 0 0 288645561 966715 0 0 0 0 0 0
6eth1: 25761486247 500606223 0 0 0 0 0 0 22767379359 20753517 0 0 0 0 0 0
其中receive是收包的信息,transimit是发包的信息。我们平时关注的几个参数意思如下:
- bytes表示收发的字节数;
- packets表示收发正确的包量;
- errs表示收发错误的包量;
- drop表示收发丢弃的包量;
注:/proc/net 目录下还有一些其他文件,都是和网络相关的。
二、awk 实时流量统计
该awk脚本正是调用了/proc/net/dev中的数据,其原理是每隔一段时间再取一下值 ,再和之前的值求差,再除间隔时间段,公式可以表示式(x2 -x1 )/t ,当t间隔为1秒时可以省略。代码如下:
1awk 'BEGIN{
2OFMT="%.3f";
3devf="/proc/net/dev";
4while(("cat "devf) | getline)
5{
6 if($0 ~ /:/ && ($10+0) > 0)
7 {
8 split($1,tarr,":");
9 net[tarr[1]]=$10+tarr[2];
10 print tarr[1],$10+tarr[2];
11 }
12}
13close(devf);
14while((system("sleep 1 ")) >=0)
15{
16 system("clear");
17 while( getline < devf )
18 {
19 if($0 ~ /:/ && ($10+0) > 0)
20 {
21 split($1,tarr,":");
22 if(tarr[1] in net)
23 {
24 print tarr[1],":",($10+tarr[2]-net[tarr[1]])*8/1024,"kb/s";
25 net[tarr[1]]=$10+tarr[2];
26 }
27 }
28 }
29 close(devf);
30}
31}'
说明:第一个while 是获得总的初始值,$1是网卡出流量,$10是网卡进流量。第2个while会间隔1秒钟启动一次。计算总流量差得到平均每秒流量。
注意:通过getline 逐行读取文件,需要close关闭 。否则在第2次while循环中不能获得数据。
awk这个脚本退出时只能通过ctrl + z 进行退出。
三、我的实时监控脚本
为避免落了俗套,有抄袭之嫌,我选取了从/sys/class/net相对应的接口中取值。/sys/class/net/ethX/statistics中详细每项对应的文件,由于只取流量信息,所以主要关注tx_bytes、rx_bytes两个文件,代码如下:
1#/bin/bash
2# site: www.361way.com
3# mail: [email protected]
4# Get all interface network flow ,refresh by 2 second define
5inet_byte() {
6 for i in `ls /sys/class/net/`; do
7 let "$i"_rx"$1"=`cat /sys/class/net/$i/statistics/rx_bytes`
8 let "$i"_tx"$1"=`cat /sys/class/net/$i/statistics/tx_bytes`
9 #eval echo '$'"$i"_rx"$1"
10 done
11}
12eva() {
13 a1=`eval echo '$'"$1"_rx1`
14 a2=`eval echo '$'"$1"_rx2`
15 b1=`eval echo '$'"$1"_tx1`
16 b2=`eval echo '$'"$1"_tx2`
17 tol1=$(($a1+$b1))
18 tol2=$(($a2+$b2))
19 #echo $1 $a1 $a2 $b1 $b2 $tol1 $tol2
20 rxkB=$(echo $a2 $a1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
21 txkB=$(echo $b2 $b1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
22 TolkB=$(echo $tol2 $tol1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
23 echo -e "$1\t\t$rxkB\t$txkB\t$TolkB"
24}
25while true; do
26 sleep 2
27 clear
28 awk 'BEGIN {print "interface\trxKB\ttxKB\tTotalKB\n==========================================";}'
29 inet_byte 1
30 sleep 1
31 inet_byte 2
32 for i in `ls /sys/class/net/`; do
33 eva $i
34 #echo $i $a1 $a2 $b1 $b2 $tol1 $tol2
35 #echo "$i $a $b $c"
36 done
37done
两个脚本的效果对比如下图:
左边为awk脚本执行的效果,右边为我写的小脚本运行的效果。还需要注意的是在awk程序中将Byte 通过乘8转化为bit ,所以最终显示的是kb,而我脚本现实的是kB,两者同时统计的话是差8倍的。
捐赠本站(Donate)
如您感觉文章有用,可扫码捐赠本站!(If the article useful, you can scan the QR code to donate))
- Author: shisekong
- Link: https://blog.361way.com/proc-awk-network/4971.html
- License: This work is under a 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议. Kindly fulfill the requirements of the aforementioned License when adapting or creating a derivative of this work.