SmoothNet Connectivity Monitor
After being more than frustrated with my Internet Service Provider I decided to start monitoring their service for them, and I figured that if I monitored one, I might as well as monitor all of the local ISP’s in the area. This is the result: Connectivity Monitor.
The following code is used to record the data. Because the script records more than average latency, I’ll leave the graph creation to you. This script is ment to be run from the command line (and NOT called by a web server, remember screen is your friend!) I make no claims as to whether this is the most efficient code but it works great for my purposes!
// RRD Filename
$file = './ISP-Connectivity.rrd';
// Image Destination
$imgdest = './images';
// Hosts to monitor (Use your ISP'a Gateway) (Add more as needed)
$target[] = array('127.0.0.1', 'Localhost');
function termination() {
}
function error_out($msg = null, $clean = true) {
if ( $clean == true ) {
if ( !is_null($msg) ) {
echo 'ERROR: ' .$msg . "\n";
}
exit;
} else {
if ( !is_null($msg) ) {
echo 'ERROR: ' .$msg . "\n";
}
exit(1);
}
}
class GetRemoteStats {
var $host;
function __construct($host = null) {
if (is_null($host)) {
return false;
} else {
$this->host = $host;
}
}
function ping() {
$rdata = array();
if (mt_rand(1,2) == 1) {
$ip = '64.85.164.122';
} else {
$ip = '64.85.164.123';
}
// Ping the host
if (!exec('ping ' . $this->host . ' -c 5 -i .2 -q -w 3 -I ' . $ip, $output)) {
return false;
} foreach ($output as &$line) {
// Get Loss
if (preg_match('/([0-9]{1,3})\%\s*?packet\s*?loss/i', $line, $temp) == 1) {
$rdata['loss'] = $temp[1];
}
// Get Latency
if (preg_match('/([0-9]{1,4}\.[0-9]{1,4})\/([0-9]{1,4}\.[0-9]{1,4})\/([0-9]{1,4}\.[0-9]{1,4})\/([0-9]{1,4}\.[0-9]{1,4})/i', $line, $temp) == 1) {
$rdata['min'] = $temp[1];
$rdata['avg'] = $temp[2];
$rdata['max'] = $temp[3];
$rdata['mdev'] = $temp[4];
}
}
echo $this->host . ': ' . $rdata['avg'] . '/' . $rdata['loss'] . "% (avg/loss)\n";
return $rdata;
}
}
function create_rrd($file, $targets) {
$options[] = '--step';
$options[] = 60;
for ($i = 0; $i != count($targets); $i++) {
$options[] = 'DS:' . $i . '-loss:GAUGE:600:U:U';
$options[] = 'DS:' . $i . '-min:GAUGE:600:U:U';
$options[] = 'DS:' . $i . '-avg:GAUGE:600:U:U';
$options[] = 'DS:' . $i . '-max:GAUGE:600:U:U';
$options[] = 'DS:' . $i . '-mdev:GAUGE:600:U:U'
}
$options[] = 'RRA:AVERAGE:0.5:1:525960';
$options[] = 'RRA:MAX:0.5:12:288';
$options[] = 'RRA:MIN:0.5:12:288';
$options[] = 'RRA:LAST:0.5:1:1';
if (!rrd_create($file, $options, count($options))) {
error_out('Unable to create RRD File!' . "\n" . rrd_error());
}
}
function update_rrd($file, $input) {
$data = 'N';
foreach ($input as $temp) {
$data .= ':';
$data .= $temp['loss'] . ':' . $temp['min'] . ':' . $temp['avg']. ':' . $temp['max'] . ':' . $temp['mdev'];
}
if (!rrd_update($file, $data)) {
error_out('Unable to update RRD File!' . "\n" . rrd_error());
}
}
// Register shutdown function
register_shutdown_function('termination');
// Prevent script timeout
set_time_limit(0);
foreach ($target as $host) {
$remote_data[] = new GetRemoteStats($host[0]);
}
echo 'Script starting up.' . "\n";
// Loop script indefinitely
while(1) {
// Check to see if RRD file exists
if ( !file_exists($file) ) {
// If RRD file does not exist, create it
echo 'Creating RRD File...' . "\n";
create_rrd($file, $target);
}
foreach ($remote_data as $data) {
// Get remote data
if (!$stats[] = $data->ping()) {
$stats['loss'] = 100;
$stats['min'] = 0;
$stats['avg'] = 0;
$stats['max'] = 0;
$stats['mdev'] = 0;
}
}
// Input data into database
update_rrd($file, $stats);
// Free Some memory
unset($stats);
// Wait 50 Seconds before looping
sleep(50);
}