User:Smahan/Nagios Extension

 
A proposal to move this page to MediaWiki.org was rejected.

Nagios Error Status Display for MediaWiki

edit
What?
This is a plugin that creates a <nagios></nagios> tag, which outputs a little table of "problem" services, like this:
 
The Nagios data parsing is largely a rewrite of code from A Simple Nagios Php Interface by Bianchini Stefano. This plugin is thus also licensed under the GPL.
Why?
I'm just Nagios-crazy right now. I wanted to let users check to see if a problem they are having is actually just the result of a problem the IT folk are aware of and working on. We also have Nagios set up to alert when a variety of shared-responsibility problems (network drives full, toner running out, plotter needs paper, etc) crop up, and the hope is that this will keep these responsibilities shared :)
Who?
My name is Sean W. Mahan, I work for architecture/design/planning firm SMWM, and work on a kind of real-world ARG / "collaborative production game" called SFZero
To Do and Other Notes
  • More comments, etc. More info on this page. Possibly "jumping the gun" on posting this, but I'll be moving on to other things for a bit, and wanted to see if anyone else out there was interested in this.
  • I know the status.dat parser is a little overboard for this, but we don't anticipate performance issues (internal wiki), and I may end up using that code for something else...
  • Finish writing the "choose what services/hosts to display" code
  • Enable use of hostgroups / servicegroups for the above
  • Alternate display styles

The Code

edit
$wgExtensionFunctions[] = "wfNagiosStatus";
function wfNagiosStatus (){
	global $wgParser;
	$wgParser->disableCache();
	$wgParser->setHook( "nagios", "renderNagios" );
}
function renderNagios( $input, $argv ) {
	// Defaults
	define(NAGIOSVARDIR,'/usr/local/nagios/var');
	global $NagTrStyle;
	$NagTrStyle='<td style="text-align:center;font-size:10pt;margin:5px;padding:5px;background:#';
	$twidth='200px';
	$hosts='all';
	$view='service';
	$title='Nagios Status';
	if($argv['view']) $view=$argv['view'];
	if ($argv['width']) $twidth=$argv['width'];
	if ($argv['hosts']) $hosts=$argv['hosts'];
	if ($argv['title']) $title=$argv['title'];

	if (strpos($view,'service')!==false){
	//return 'blah!';
		$theData=gather_service_data();
		$theStatus=format_service_data($theData);	
	}
	if (strpos($view,'host')!==false) {
		$theData=gather_host_data();
		$theStatus=format_host_data($theData);
	}	
	$output='<table style="border:1px solid #CDCDCD;width:'.$twidth.';"><tr><th style="border-bottom:1px solid #CDCDCD">'.$title.'</th></tr>';
	if ($theStatus==''){
		//$output.='<pre>'.print_r($theData).'< / pre>';
		$output.='<tr>'.$NagTrStyle.'33FF00" title="Everything seems to be OK">A-OK!'.$theData.'</td></tr>';
	}
	else {
		$output .=$theStatus;
	}
	$output.='</table>';
    return $output;
}

function get_tag($tag,$stat) {
	$tag.="=";
	$pos=strpos($stat,$tag)+strlen($tag)-1;
	$stringatemp=substr($stat, $pos+1);
	$posfine=strpos($stringatemp, "\n");
	return substr($stringatemp,0,$posfine);
}
function read_service_tags($servicestat) {
	$service_props=array('modified_attributes','check_command','event_handler','has_been_checked','should_be_scheduled',
		'check_execution_time','check_latency','check_type','last_hard_state','current_attempt','max_attempts','state_type',
		'last_state_change','last_hard_state_change','last_time_ok','last_time_warning','last_time_unknown','last_time_critical',
		'performance_data','last_check','next_check','current_notification_number','last_notification','next_notification','no_more_notifications',
		'notifications_enabled','active_checks_enabled','passive_checks_enabled','event_handler_enabled','acknowledgement_type',
		'flap_detection_enabled','failure_prediction_enabled','process_performance_data','obsess_over_service','last_update','is_flapping',
		'percent_state_change','scheduled_downtime_depth','service_description','host_name','current_state','plugin_output','problem_has_been_acknowledged');
	foreach ($service_props as $service_prop){
		$data=get_tag($service_prop,$servicestat);
		$service_data[$service_prop]=$data;
	}	
	return $service_data;
}

function read_host_tags($hoststat) {
	$host_props=array('host_name','modified_attributes','check_command','event_handler','has_been_checked','should_be_scheduled',
		'check_execution_time','check_latency','check_type','current_state','last_hard_state','plugin_output','performance_data','last_check',
		'next_check','current_attempt','max_attempts','state_type','last_state_change','last_hard_state_change','last_time_up','last_time_down',
		'last_time_unreachable','current_notification_number','last_notification','next_notification','no_more_notifications','notifications_enabled',
		'problem_has_been_acknowledged','acknowledgement_type','active_checks_enabled','passive_checks_enabled','event_handler_enabled',
		'flap_detection_enabled','failure_prediction_enabled','process_performance_data','obsess_over_host','last_update','is_flapping',
		'percent_state_change','scheduled_downtime_depth');
	foreach ($host_props as $host_prop){
		$data=get_tag($host_prop,$hoststat);
		$host_data[$host_prop]=$data;
	}
	return $host_data;
}

function gather_service_data() {
	$statusfile = NAGIOSVARDIR.'/status.dat';
	if (!file_exists($statusfile)) {
		return "Can't find status.dat";
		exit();
	}
	$fp = fopen($statusfile,'r'); 
	$stat = fread($fp,filesize($statusfile));
	$n=0;
	while ($n<filesize($statusfile)-1) {
		$stat_support=substr($stat, $n);
		$position=strpos($stat_support, "service {");
		if ($position==false) { break; }
		$temp_stat=substr($stat_support, $position);
		$endposition=strpos($temp_stat, "}");
		$servicestat=substr($stat_support,$position,$endposition+1);
		$service_data[]=read_service_tags($servicestat);
		$n=$position+$endposition+$n;
	}
	fclose($fp);
	return $service_data;
}

function gather_host_data() {
	$statusfile = NAGIOSVARDIR.'/status.dat';
	if (!file_exists($statusfile)) {
		return "Can't find status.dat";
		exit();
	}
	$fp = fopen($statusfile,'r'); 
	$stat = fread($fp,filesize($statusfile));
	$n=0;
	while ($n<filesize($statusfile)-1) {
		$stat_support=substr($stat, $n);
		$position=strpos($stat_support, "host {");
		if ($position==false) { break; }
		$temp_stat=substr($stat_support, $position);
		$endposition=strpos($temp_stat, "}");
		$servicestat=substr($stat_support,$position,$endposition+1);
		$service_data[]=read_host_tags($servicestat);
		$n=$position+$endposition+$n;
	}
	fclose($fp);
	return $service_data;
}

function format_service_data($service_data,$problems_only=true,$hostnames='all',$services='all',$style='table') {
	$color_array=array("#33FF00","FFFF96","FF817F","orange");
	foreach ($service_data as $service){
		$report=true;
		if ($problems_only && $service['current_state']==0) $report=false;
		if ($hostnames!=='all' && !strpos($hostnames,$service['host_name'])) $report=false;
		if ($services!=='all' && !strpos($services,$service['service_description'])) $report=false;
		if ($report && $style=='table'){
			$nagiosStatus.= "<tr>";
			global $NagTrStyle;
			$nagiosStatus.= $NagTrStyle.$color_array[$service['current_state']].'" title="'
				.htmlentities($service['plugin_output']).'">'.$service['service_description'].' on '.$service['host_name'].'</td>';
			$nagiosStatus.= "</tr>";
		}
	}
	return $nagiosStatus;
}