Aug 30 2012

php command line bandwidth monitor

Category: phperm @ 10:55 am

I wrote this quick & dirty bandwidth monitor for use with htop. It also displays the average bandwidth for the last 10 seconds.

It displays a line similar to this at the top of the screen:
eth0:RX:600b TX:944b Avg:77b eth2:RX:0b TX:0b Avg:0b

Usage is simple:
$ ./bw.monitor.php & htop

#!/usr/bin/php
<?php
    set_time_limit(0);
    define('ESC',chr(27));
    $ignore_interfaces = array('lo','wlan0');
    function human($bytes, $decimals = 1) {
      $sz = 'bkmgtp';
      $factor = floor((strlen($bytes) - 1) / 3);
      if ($factor >= 1) {
        return sprintf("%.{$decimals}f%s", $bytes / pow(1024, $factor), @$sz[$factor]);
      }
      return sprintf("%d%s", $bytes / pow(1024, $factor),@$sz[$factor]);
    }
    /*
    $data="Inter-|   Receive                                                |  Transmit
 face |bytes    packets errs drop fifo frame compressed multicast|bytes    packets errs drop fifo colls carrier compressed
    lo: 70513902  759179    0    0    0     0          0         0 70513902  759179    0    0    0     0       0          0
  eth2:       0       0    0    0    0     0          0         0        0       0    0    0    0     0       0          0
  eth0: 591403745 1474829    0    0    0     0          0      1492 2162660750 2294779    0    0    0     0       0          0";
    */
    $map = array(
        2 => 'RX',
        10 => 'TX'
    );
    $last_data = array();
    $readout = array();
    $total = array();
    $history = array();
    $cnt = 0;
    while (true) {
        $matches = array();
        $associated = array();
        $readout = array();
        $data = file_get_contents('/proc/net/dev');
        preg_match_all('/([a-z0-9]+)\:\s+([0-9]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)\s+([\d]+)/msu',$data, $matches, PREG_SET_ORDER);
        if (!$matches) {
            sleep(1);
            continue;
        }
        $cnt++;
        // echo $data;
        // print_r($matches);
        
        foreach ($matches as $match) {
            $interface = $match[1]; 
             if (in_array($interface, $ignore_interfaces)) {
                continue;
            }
            if (!isset($total[$interface])) {
                $total["$interface"] = 0;
            }
            if (!isset($history[$interface])) {
                for ($i=0;$i<20;$i++) {
                    $history["$interface"][] = 0;
                }
            }
            $associated[$interface] = array();
            foreach ($map as $k=>$v) {
                 $associated[$interface][$v] = $match[$k];
            }
        }
        // print_r($associated);
        foreach ($associated as $i=>$d) {
            if (isset($last_data[$i])) {
                foreach ($d as $k=>$v) {
                    $diff = $v - $last_data[$i][$k];
                    $readout["$i"]["$k"] = human($diff);
                    $total["$i"] = ($total["$i"] + $diff);
                    $history["$i"][] = $diff;
                }
                $history["$i"] = array_slice($history["$i"], -20, 20);
                $readout["$i"]["Avg"] = human(floor(array_sum($history["$i"]) / (count($history["$i"]) / 2)));
                // print_r($history);
            }
        }
        $last_data = $associated;
        // print_r($readout);
        echo ESC,'[s';
        echo ESC,'[0;0H';
        echo ESC,'[K';
        ksort($readout);
        foreach ($readout as $i=>$d) {
            echo $i,':';
            foreach ($d as $k=>$v) {
                printf("%-10s", "$k:$v");
            }
            // echo " ";
        }
        // echo 'mem:',human(memory_get_usage(),2);
        echo ESC,'[u';
        flush();
        sleep(1);
    }

One Response to “php command line bandwidth monitor”

  1. blog.the-erm.com » python command line bandwidth monitor says:

    […] In a previous post I wrote a bandwidth monitory in php. It was running about 300k (on my laptop it was < 100k), and figured it was time to test out my python foo. […]

Leave a Reply

You must be logged in to post a comment. Login now.