気になるサーバの現在の転送速度をモニタする。

ifconfigを実行すると、起動から今までの総転送量が表示される。
これを利用して、一定期間内の転送速度を求めることが出来るはず。

ifconfigで出てくる転送量とかのデータは、/proc/net/devの中にある。

$cat /proc/net/dev
Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo:61101820   57561    0    0    0     0          0         0 61101820   57561    0    0    0     0       0          0
  eth0:211752374 14263469    0    0    0     0          0         0 33509783 17990346    0    0    0     0       0          0

この総転送量を2回読んでやり、差を時間で割れば転送速度が求められる。と。

<?php

//関数呼び出し
include("getmicrotime.php");      //現在の時刻をマイクロタイムで返す

//ブラウザからの情報取得
$n = $_GET['n'];
if(!$n){
    $n = 20;
}

//本題
for($i=0;$i<=$n&&$i<=20;$i++){             //最大20ぐらいにしとく。
    $str = file("/proc/net/dev");          //欲しい情報はこの中に
    $str = $str[3];                 //欲しいインターフェイスのある行を読む
    $now = getmicrotime();             //現在時刻を取得
    $time = $now - $now_old;            //前回時刻から引き算
    $now_old = $now;                //現在時刻を前回時刻にしとく
    while(ereg(" ",$str)){             //元データはスペースがいっぱいあるから
        $str = str_replace(" "," ",$str);   //連続したスペースは全部一つのスペースに
    }

    $str = str_replace(":"," ",$str);        //eth0:123456みたいになってるから
    $str = split(" ",$str);             //スペース区切りで配列に

    $rx = $str[2] - $rx_old;            //今回の総転送量から前回のをを引いて
    $tx = $str[10] - $tx_old;            //この約1秒間での転送量を出す。

    $rx_old = $str[2];               //欲しいデータは得れたから今回の総転送量は
    $tx_old = $str[10];               //次回のために保管しとく。

    $rxs = round($rx * 8 / ($time * 1024 * 1024),2);    //bytes*8でbitsに変換したのを、
    $txs = round($tx * 8 / ($time * 1024 * 1024),2);    //時間* M で割ってMbpsになる。

    if($i){                         //一回目は前回データが無いのでパス
        $i  = str_pad($i, 2,0,STR_PAD_LEFT);         //桁そろえるために2桁に。
        $rxs = str_replace("000",".00",str_pad($rxs,4,0));   //ゼロのときに桁がズレ
        $txs = str_replace("000",".00",str_pad($txs,4,0));   //ないよう0.00に変換する。
        echo "$i | $rxs [Mbps] | $txs [Mbps] | $time<BR>\n";  //結果表示
    }else{                             //せっかくなので1回目で
        echo " n | 受信     | 送信     | time<BR>\n";  //凡例を表示する
    }
    ob_flush();                   //一回ずつ
    flush();                    //ブラウザに表示してやる。
    usleep(988000);                 //だいたい1ループ1秒ぐらいになるように。
}

?>

最初にインクルードしてるgetmicrotime.phpの中身は、

<?php
function getmicrotime(){
    list($msec, $sec) = explode(" ", microtime());
    return ((float)$sec + (float)$msec);
}
?>

これだけ。
microtime()関数では戻り値がスペース区切りで"小数部 整数部"で返ってくる。
これじゃ引き算しにくいから、普通の小数にして返してくれる関数。
(パクりモノ from PHPの基礎体力様)

usleep(988000);と半端な理由は、1秒から1ループにかかるだいたいの時間を引いたから。
環境によって変わるし、そのときのコンディションでも変わるから特に重い意味はない。
別に1秒ちょうどである必要もないし。気分だけの問題。

一応完成だけど、これじゃ総転送量がオーバーフローしてゼロに戻ったときに変な値が出る。
そのうち書き足そう。

実際に動かすとこんな感じ。
http://www.genkikko.net/transfer_speed.php?n=10