User:Smahan/Nagios Extension

From Meta, a Wikimedia project coordination wiki
Jump to navigation Jump to search
Blue Glass Arrow.svg MediaWiki logo.png
This page should be moved to MediaWiki.org.
Please do not move the page by hand. It will be imported by a MediaWiki.org administrator with the full edit history. In the meantime, you may continue to edit the page as normal.

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:
MWNagPluginDisplay.png
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;
}