#!/usr/bin/php
<?php
// ############################################################################################
// Author: Philip A. O'Malley, (C)2006 Awareness Software Limited.
// ############################################################################################
// Define our exit codes.
$nagios_exit = array( 'UNKNOWN' => 3, 'OK' => 0, 'WARNING' => 1, 'CRITICAL' => 2 );
// Translate CLI arguments to conventional actions.
$options = getopt("i:w:c:");
if(!array_key_exists("i", $options) or !array_key_exists("w", $options) or !array_key_exists("c", $options)) {
echo "Usage: check_iface_nrpe.php -i iface -w warningmbitsec -c criticalmbitsec\n";
exit($nagios_exit["UNKNOWN"]);
}
else {
$interface = $options["i"];
$warning_level = $options["w"];
$critical_level = $options["c"];
}
// Blow the routine if we don't get an array.
if(!is_array($return = parseProc($interface))) {
echo $return."\n";
exit($nagios_exit["UNKNOWN"]);
}
// Into the interrogation of the data.
checkIfaceData($interface, $return, $warning_level, $critical_level);
// ############################################################################################
// FUNCTION: checkIfaceData($array)
// ############################################################################################
function checkIfaceData($interface, $array, $warning_level, $critical_level) {
global $nagios_exit;
list($input_bits, $output_bits) = $array;
$timestamp = microtime_float();
$iface_file = "/tmp/check_iface_".$interface;
// See if we have a file of past data we can read.
if(file_exists($iface_file)) {
$iface_history = file_get_contents($iface_file);
list($previous_timestamp, $previous_input_bits, $previous_output_bits) = explode(",", $iface_history);
}
// Write out our new data. We do this now in case the machine has rebooted and all the values
// in /proc have been reset - so let's just write it out now.
file_put_contents($iface_file, $timestamp.",".$input_bits.",".$output_bits);
if(!isset($iface_history)) {
echo "UNKNOWN: no historical data for interface ".$interface."\n";
exit($nagios_exit["UNKNOWN"]);
}
// So, let's work out what's incremented.
$diff_timestamp = $timestamp - $previous_timestamp;
$diff_input_bits = $input_bits - $previous_input_bits;
$diff_output_bits = $output_bits - $previous_output_bits;
if($diff_timestamp < 0) {
echo "UNKNOWN: a historical compare returned a negative value for interface ".$interface."\n";
exit($nagios_exit["UNKNOWN"]);
}
if($diff_timestamp < 0) {
echo "UNKNOWN: a historical compare returned a negative value for interface ".$interface."\n";
exit($nagios_exit["UNKNOWN"]);
}
// If we have negative input bits then we've rolled round the 32-bit integer limit.
if($diff_input_bits < 0) {
$diff_input_bits = ($diff_input_bits*-1)+(4294967296-$previous_input_bits);
}
if($diff_output_bits < 0) {
$diff_output_bits = ($diff_output_bits*-1)+(4294967296-$previous_output_bits);
}
$average_input_mbits = ((($diff_input_bits/$diff_timestamp)/1024)/1024);
$average_output_mbits = ((($diff_output_bits/$diff_timestamp)/1024)/1024);
// Let's see if our metrics fall into parameters.
$performance_data = "input=".number_format($average_input_mbits, 2)."Mbps;".$warning_level.";".$critical_level.";0;10000; ";
$performance_data .= "output=".number_format($average_output_mbits, 2)."Mbps;".$warning_level.";".$critical_level.";0;10000;";
if(($average_input_mbits > $critical_level) or ($average_output_mbits > $critical_level)) {
echo "CRITICAL: ".number_format($average_input_mbits, 2)." Mbps input, ".number_format($average_output_mbits,2)." Mbps output | ".$performance_data."\n";
exit($nagios_exit["CRITICAL"]);
}
elseif(($average_input_mbits > $warning_level) or ($average_output_mbits > $warning_level)) {
echo "WARNING: ".number_format($average_input_mbits,2)." Mbps input, ".number_format($average_output_mbits,2)." Mbps output | ".$performance_data."\n";
exit($nagios_exit["WARNING"]);
}
elseif(($average_input_mbits <= $warning_level) and ($average_output_mbits <= $warning_level)) {
echo "OK: ".number_format($average_input_mbits,2)." Mbps input, ".number_format($average_output_mbits,2)." Mbps output | ".$performance_data."\n";
exit($nagios_exit["OK"]);
}
else {
echo "UNKNOWN: unexpected result.\n";
exit($nagios_exit["UNKNOWN"]);
}
}
// ############################################################################################
// FUNCTION: microtime_float()
// ############################################################################################
function microtime_float()
{
list($usec, $sec) = explode(" ", microtime());
return ((float)$usec + (float)$sec);
}
// ############################################################################################
// FUNCTION: parseProc($db_source)
// ############################################################################################
function parseProc($interface) {
if(!$procfile = file_get_contents("/proc/net/dev")) {
return "UNKNOWN: unable to parse /proc/net/dev.";
}
else {
foreach(explode("\n", $procfile) as $lineid => $data) {
if(strpos($data, $interface.":") !== FALSE) {
$data = preg_replace('/'.$interface.':/', '', $data);
$data = preg_replace("/\s+/", " ", $data);
$data = ltrim($data);
$line_explode = (explode(" ", $data));
$input_bits = $line_explode[0]*8;
$output_bits = $line_explode[8]*8;
}
}
}
if(!is_array($line_explode)) {
return "UNKNOWN: no interface found in /proc/net/dev.";
}
return array($input_bits, $output_bits);
}
?>