proc与awk实时网卡流量监控

2013年1月15日 发表评论 阅读评论

通过/proc/net/dev该文件可以获取所有网卡的时时数据信息。通过/sys/class/net/下的文件同样可以获取每块网卡更详细的信息。在cnblogs博客园上看到程默的博客中有一篇使用awk 程序精妙的搞了一个网卡实时流量监控脚本。程序虽然写的非常不错,不过统计的只是网卡向外发送的实时流量情况,我没事也搞了一个脚本,可以实时监控所有网卡的rx、tx及总的流量情况。

一、/proc/net/dev文件介绍

查看该虚拟文件得到的信息如下:

[root@361way ~]# cat /proc/net/dev|column -t
Inter-|  Receive      |          Transmit
face     |bytes       packets    errs      drop  fifo  frame  compressed  multicast|bytes  packets      errs      drop  fifo  colls  carrier  compressed
lo:      30288411132  22091019   0         0     0     0      0           0                30288411132  22091019  0     0     0      0        0           0
eth0:    3368488625   73197048   0         0     0     0      0           0                288645561    966715    0     0     0      0        0           0
eth1:    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秒时可以省略。代码如下:

awk 'BEGIN{
OFMT="%.3f";
devf="/proc/net/dev";
while(("cat "devf) | getline)
{
    if($0 ~ /:/ && ($10+0) > 0)
    {
        split($1,tarr,":");
        net[tarr[1]]=$10+tarr[2];
        print tarr[1],$10+tarr[2];
    }
}
close(devf);
while((system("sleep 1 ")) >=0)
{
    system("clear");
    while( getline < devf )
    {
        if($0 ~ /:/ && ($10+0) > 0)
            {
                split($1,tarr,":");
                if(tarr[1] in net)
                {
                    print tarr[1],":",($10+tarr[2]-net[tarr[1]])*8/1024,"kb/s";
                    net[tarr[1]]=$10+tarr[2];
                }
            }
    }
    close(devf);
}
}' 

说明:第一个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两个文件,代码如下:

#/bin/bash
# site: www.361way.com
# mail: itybku@139.com
# Get all interface network flow ,refresh by 2 second define
inet_byte() {
    for i in `ls /sys/class/net/`; do
        let "$i"_rx"$1"=`cat /sys/class/net/$i/statistics/rx_bytes`
        let "$i"_tx"$1"=`cat /sys/class/net/$i/statistics/tx_bytes`
        #eval echo '$'"$i"_rx"$1"
    done
}
eva() {
    a1=`eval echo '$'"$1"_rx1`
    a2=`eval echo '$'"$1"_rx2`
    b1=`eval echo '$'"$1"_tx1`
    b2=`eval echo '$'"$1"_tx2`
    tol1=$(($a1+$b1))
    tol2=$(($a2+$b2))
    #echo $1 $a1 $a2 $b1 $b2 $tol1 $tol2
    rxkB=$(echo $a2 $a1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
    txkB=$(echo $b2 $b1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
    TolkB=$(echo $tol2 $tol1 | awk '{ printf "%0.2f" ,($1-$2)/1024 }')
    echo -e "$1\t\t$rxkB\t$txkB\t$TolkB"
}
while true; do
    sleep 2
    clear
    awk 'BEGIN {print "interface\trxKB\ttxKB\tTotalKB\n==========================================";}'
    inet_byte 1
    sleep 1
    inet_byte 2
    for i in `ls /sys/class/net/`; do
        eva $i
        #echo $i $a1 $a2 $b1 $b2 $tol1 $tol2
        #echo  "$i $a $b $c"
    done
done

两个脚本的效果对比如下图:

左边为awk脚本执行的效果,右边为我写的小脚本运行的效果。还需要注意的是在awk程序中将Byte 通过乘8转化为bit ,所以最终显示的是kb,而我脚本现实的是kB,两者同时统计的话是差8倍的。

 




本站的发展离不开您的资助,金额随意,欢迎来赏!

You can donate through PayPal.
My paypal id: itybku@139.com
Paypal page: https://www.paypal.me/361way

  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.