Blog Archives

Check_VM for Oracle VM and Nagios.

Personal backup…

Refinements might be added if bugs or improvements are found. So keep an eye out for newer versions 😉

This script might also be compatible with other  Xen clones.


#!/usr/bin/perl
#
# Author : Chris Gralike
# Company: AMIS Services BV
#
# Simple but effective Oracle VM check command for use with nagios
# This command checks the state of any given VM machine using the XM command.
# It will try to match the friendly name as well as the system name.
# It will return OK - and usefull metadata on succes, NOK on failure.
# usage : check_xm vmname
# ########################

use strict;                     # Good practice
use warnings;                   # Good practice

my (@data, @values, @name, $vmname, $vmcheck, $i, $result);

# Get the command parameters
if( ($#ARGV + 1) == 1 ) {
$vmname = $ARGV['0'];
}else{
print "usage: ./check_xm vmname \n";
exit 1;
}

# Perform the actual test
open(XM, "xm list|");
$i = 0;
while(<XM>){
if($i > 0){
# Split the output in portions
@data = split(" ", $_);
# Get the human readable name
@name = split('_', $data['0']);
if(!$name['1']){
$name['1'] = 'dezeisnietingebruik!';
}
if(($vmname eq $name['1']) || ($vmname eq $data['0'])){
print "OK - $data['0'] is active with Id:$data['1'] $data['3']CPUs $data['2']M \n";
exit 0;
}
}
$i++;
}
close XM;

# If the loop was finished without result, then there is a problem!
print "NOK - $vmname is not running on this server\n";
exit 2;
Advertisements

Cant wait…

After reading this benchmark: http://blog.centreon.com/public/Centreon_Engine_Benchmarks.pdf, I was wondering. isn’t it strange that their own benchmark is telling us they beat the good-old-nagios on all elements?

Do not get me wrong, I still believe that Centreon is a wonderful product. But i cant ignore the fact that the Nagios Core / Nagios XI are on the move as well.  And for some reason I get the feeling they are referring to history. Last time I was informed,  Nagios employed a team of developers as well in developing Nagios XI. And next to that, Nagios also enables OS programmers to commit code: http://www.nagios.org/contribute.

Please dear Centreon, don’t spoil your good name and stick to the facts. You have a great product, no need for bashing. Next to that, don’t use a translate without review in your benchmark documents.

Having that said, what happed to Icinga?

It seams that Icinga is well on their way as well seeing this sheet: https://www.icinga.org/nagios/feature-comparison/

Anyway, any monitoring needs?

It seems a crossroad is nearing in which you are forced to pick a side and stick by it.

And yet somehow, I cant suppress a feeling of sadness about this development.
Goodbye years of scripting, hacking and rewriting happiness, Hello ‘next-next-finish’ world 😉

Any insights?
Please share them with us web reading it-guy folk  :=)

Check_iostat.pl version 0.9.7

Previous version and detaild information
https://sysengineers.wordpress.com/2010/02/05/check_iostat-for-nagios-version-0-9-5/

Application Goal:
Check disk IO using a simple perl script and possibly the counters allready available in the linux /proc/ directory. The program must be able to run under Nagios and should return a ‘Nagios’ correct syntax to the prompt. This way the plugin should be usable for Linux users to monitor their Disk IO within Nagios. The program should also report back performance information in the ‘Nagios’ compatible syntax so that graphing is available in the ‘Nagios’ / Cacti / Centreon add-ons.

Changes
Fixed lacking devision in validated summed results
Added sprintf functions rounding the validated numbers with 2 dimentions
Fixed some declaration problems
Added -debug switch to enable the debugging options
Coded arround the used math::Complex functions and removed the module
Improved the debugging output (readability)
Small fixes in de syntax

Installation
1. Copy the code below to your clipboard (ctr+c or the copy-button inside the code field)
2. Logon to the linuxbox with the nagios or nrpe client.
3. browse to the plugin-dir usually cd /usr/local/nagios/libexec/
4. Create a new file vi ./check_iostat.pl
5. Press insert and paste the code inside (when using putty paste is done with a rightmouse click)
6. save the file (esc > : > rq > enter, when using vi)
7. give the file execute rights using chmod +x ./check_iostat
8. make nagios the owner chown nagios:nagios ./check_iostat
9. Test it using updatedb& ./check_iostat -d sd -dbu -dbuw 70 -dbuc 88 -kbs -kbsw 10000 -kbsc 50000 -p

Next configure a nagios command or use nrpe and have fun 🙂

#!/usr/bin/perl
# Written by Chris Gralike @ AMIS.
# Perl based check command to fetch and report the
# TPS (transactions per second) and IO wait times.
# Plugin uses iostat for opperation.
# Verion 0.9.7
#
# Changes post 0.9.7 >> 28-05-2010
# Line 298...303 Prevent devision by zerro else exit because no data was collected  - Bug reported by Epiq.
# Line 380       Correction of a type that prevented pref data of r/s w/s from being printed. - Bug reported by Epiq.
# Line 40        Added dm as possible device input used by the linux LVM. - Suggested by Epiq.
# Line 269       Extended the device if/pragmatch validation to match more devices - Added by Jean Ventura.
#
###########################
use Switch;
use warnings;

my($numArgs,
   $debug,	# Print debugging information.
   $DevType,	# Used to match a certain devicetype from the resulting IOstat rows.
   $IOBIN,	# Is used to store a path to the iostat binairy for execution.
   $Samples,	# Used to store the initial Samples returned by iostat.
   @SampleRows, # Used to store the rows generated by the splitted samples.
   $firstseen,  # Used to keep track of the found devices (IOstat might return a set of devices i.e sda, sdb, sdc etc.)
   $Items,      # Used in the foreach to store the row being parsed.
   @cols,       # Used to store the columns in a row after an split.
   $dev,	# Used to create a symbolic link to dynamicly create a var.
   $rqm,
   $val,
   $devtypes,
   $rws, $rws_warn, $rws_crit,
   $kbs, $kbs_warn, $kbs_crit,
   $awt, $awt_warn, $awt_crit,
   $svc, $svc_warn, $svc_crit,
   $devices, $itd,$v1,$v2,$v3,
   $v4,$v5,$v6,$v7,$v8,$v9,$v10,$v11,
   $dbu, $dbu_warn, $dbu_crit
   );

# Preparing to collect the dangerious user input.
# Here is a list of known device types. Please add any device you would like to monitor..
$devtypes=";sd;hd;dm;";
$numArgs = $#ARGV + 1;
$critical_global = 0;
$warning_global = 0;

if($numArgs gt '0'){
	for($i=0;$i<$numArgs;$i++){
	# Process our command line arguments and do some basic testing.
	# Could be make human save in the future.
	switch ($ARGV[$i]) {
		# Enable debugging.
		case '-debug'{
				$debug = 1;
			     }
		# Handle device type
		case '-d'    {
				$val=$ARGV[$i+1];
		 		if( (index($devtypes, $val)) gt '-1'){
					$DevType=$val;
					$i++;
		  		}else{
					print "Ivalid Disktype found. Typo?\n"; exit 1;
		  		}
			     }
		# Do we need to check rqm?
		case '-rqm'  { $rqm='1'; }
		# What is the warning treshold?
		case '-rqmw' {
				$val=$ARGV[$i+1];
				# Is the value nummeric?
				if($val=~m/[0-9]*/){
					$rqm_warn= int $val;
					$i++;
				}else{
				# Possible type?
					print "Non Numeric value used in rqmw, typo? \n"; exit 1;
				}
			     }
		case '-rqmc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rqm_crit= int $val;
					$i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rqmc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check rws?
		case '-rws'  { $rws='1'; }
		case '-rwsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsw, typo? \n"; exit 1;
                                }
			     }
		case '-rwsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $rws_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in rwsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check kbs?
		case '-kbs'  { $kbs='1'; }
		case '-kbsw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsw, typo? \n"; exit 1;
                                }
			     }
		case '-kbsc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $kbs_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in kbsc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check awt?
		case '-awt'  { $awt='1'; }
		case '-awtw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtw, typo? \n"; exit 1;
                                }
			     }
		case '-awtc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $awt_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in awtc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check svc?
		case '-svc'  { $svc='1'; }
		case '-svcw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcw, typo? \n"; exit 1;
                                }
			     }
		case '-svcc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $svc_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in svcc, typo? \n"; exit 1;
                                }
			     }
		# Do we need to check dbu?
		case '-dbu'  { $dbu='1'; }
		case '-dbuw' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_warn= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuw, typo? \n"; exit 1;
                                }
			     }
		case '-dbuc' {
				$val=$ARGV[$i+1];
                                # Is the value nummeric?
                                if($val=~m/[0-9]*/){
                                        $dbu_crit= int $val;
                                        $i++;
                                }else{
                                # Possible type?
                                        print "Non Numeric value used in dbuc, typo? \n"; exit 1;
                                }
			     }
		# performance data. Might make the string human unreadable.. ow well, no loss there <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
		case '-p'    { $prf='1'; }
		# Print full messages per device overview.
		#case '-m'    { $fms='1'; }
		# Most used help switches.
		case '--help'{ USAGE(); }
		case '-h'    { USAGE(); }
	}
	}
	# Check if the basic requirements are met.
	if(!($DevType) ||  !(($rqm || $rws || $kbs || $awt || $svc || $dbu))){
		print "Minimal requiremens, device and checktype are not met\n";
		USAGE();
	}
}else{
	# No input was given. Show the Usage();
	USAGE();
}

# Locate the IOBin binairy needed to fetch the stats.
chomp($IOBIN=`which iostat`);

if( !(-f $IOBIN) || !(-x $IOBIN)){
	print "A working iostat command is needed for this script to work \n";
	print "Also make sure the sysstat service is running! /etc/init.d/sysstat \n";
	exit 1;
}

if($DevType){
	# IF IOStat is found, lets collect some data.
	chomp($Samples=`$IOBIN -d -x -k 1 5 | grep $DevType`);
}else{
	print "Please select a valid devicetype \n";
	exit 1;
}

# Break the samples up in lines so we can evaluate them.
# The first set of samples are avg. values counted from boot.
# We need to discard them and collect the remaining samples.
@SampleRows=split(/\n/, $Samples);

# Firstseen is used to track de device names and to skip the first itteration of iostat that contains
# avg stats counted from system boot time, stats we cant use here sadly <img src="https://s-ssl.wordpress.com/wp-includes/images/smilies/icon_smile.gif" alt=":)" class="wp-smiley">
$firstseen='';
$CT=0;
$Devices=0;

# Print Debugging information
if($debug){
	    print "### Data collected ###\n";
	    print "dev|rrqm|wrqm|r/s|w/s|rKB/s|wKB/s|rq-sz|qu-sz|await|svctm|util%|\n";
}

foreach $Items (@SampleRows){
	 # Break the latter up in usable columns.
        @cols=split(/\s+/,$Items);
	 # We only want a certain device type. So lets match what we know.
	 # Disks usualy have a prefix for example (scsi = sd) its set using
	 # the DevType var.
         if($cols[0]=~m/$DevType-[0-9]$/ || $cols[0]=~m/$DevType[a-z]$/ || $cols[0]=~m/$DevType[a-z][0-9]$/){

		$dev=$cols[0];
		if((rindex $firstseen, $dev) gt '-1'){
			#Declare new $$
			#my @$dev;
			# Store the collected data in the correct (dynamic) vars.
			$$dev[1]+=$cols[1];	# rrqm/s   Read Requests Merged per Second.
			$$dev[2]+=$cols[2];	# wrqm/s   Write Requests Merged per Second.
			$$dev[3]+=$cols[3];	# r/s      Number of read requests issued per Second
			$$dev[4]+=$cols[4];	# w/s      Number of write requests issued per Second
			$$dev[5]+=$cols[5];	# rKB/s    Number of Kilobytes read per Second.
			$$dev[6]+=$cols[6];	# wKB/s    Number of Kilobytes written per Second.
			$$dev[7]+=$cols[7];	# Avgrq-sz Avarage size (in sectors) of the issued requests.
			$$dev[8]+=$cols[8];	# Avgqu-sz Avarage Queue length of the requests issued.
			$$dev[9]+=$cols[9];	# Await	  Avarage wait time in ms for IO requests to be served.
			$$dev[10]+=$cols[10];	# svctm    Avarage service time in ms for IO requests that where issued.
			$$dev[11]+=$cols[11];   # %util    Precentage of CPU time during IO requests (bandwidth util), saturation at 90~100%
			$CT++; # Add a new itteration to the count
			# Print some debugging vars if requested. to show the data is collected.
			if($debug){
				    print "$dev|$cols[1]|$cols[2]|$cols[3]|$cols[4]|$cols[5]|$cols[6]|$cols[7]|$cols[8]|$cols[9]|$cols[10]|$cols[11]|\n";
			}
		}else{
			$Devices++;
			$firstseen.="$dev;";
		}
	}
}

# Prevent $itd (itterations / disk) from becomming zerro and exit when no devices are found.
# on line 299.
if($Devices > 0){
	$itd = ($CT / $Devices);
}else{
	print "No performance data was captured. Please check if the device name is correct\n"; exit 1;
}

# Print debugging information
if($debug){
	print "###Devices Counted###\n";
	print "Number of devices : $Devices\n";
	print "Number of itterations per device : $itd\n";
	print "Total Number of Itterations : $CT\n";
}
# Lets collect the device information from the firstseen var
# and start processing it for some perf check/data
# Lets also recycle some previously used vars for this.
@cols=split(/;/,$firstseen);
foreach $Items (@cols){
	# Items now contains the devicenames needed to access the data again.
	# We now need to check them against some basic tresholds
	# Print a nice table with the calculated values when we are in debug.

  	# Print debugging information
	if($debug){
		   print "### Counted Values ###\n";
		   print "$Items|$$Items[1]|$$Items[2]|$$Items[3]|$$Items[4]|$$Items[5]|$$Items[6]|$$Items[7]|$$Items[8]|$$Items[9]|$$Items[10]|$$Items[11]|\n";
        }

	#What do we want to check against a treshold?
	#First check the selection if any.
	if($rqm || $rws || $kbs || $awt || $svc || $dbu){

		#Set the counts to zerro
		$critical_state='0';
		$warning_state='0';
		$ok_state='0';
		# Devide
		$round="%.2f";
		$v1 = sprintf($round, ($$Items[1] / $itd));
        $v2 = sprintf($round, ($$Items[2] / $itd));
		$v3 = sprintf($round, ($$Items[3] / $itd));
        $v4 = sprintf($round, ($$Items[4] / $itd));
		$v5 = sprintf($round, ($$Items[5] / $itd));
        $v6 = sprintf($round, ($$Items[6] / $itd));
		$v7 = sprintf($round, ($$Items[7] / $itd));
        $v8 = sprintf($round, ($$Items[8] / $itd));
		$v9 = sprintf($round, ($$Items[9] / $itd));
        $v10 = sprintf($round, ($$Items[10] / $itd));
        $v11 = sprintf($round, ($$Items[11] / $itd));

		# Requests Merged per second.
		if($rqm){
			# Critical
			if(($v1 >= $rqm_crit) || ($v2 >= $rqm_crit)){
				$critical_state+='1';
			# Warning?
			}elsif(($v1 >= $rqm_warn) || ($v2 >= $rqm_warn)){
				$warning_state+='1';
			# Ok
			}else{
				$ok_state+='1';
			}
			# Add the counters to the performance vars
			$perf.="$Items-rrqm/s=$v1; $Items-wrqm/s=$v2;";
		}
		# Reads / Writes per second.
		if($rws){
			if(($v3 >= $rws_crit) || ($v4 >= $rws_crit)){
	                    	$critical_state+='1';
             		# Warning?
               	 	}elsif(($v3 >= $rws_warn) || ($v4 >= $rws_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			# Add the counters to the performance var.
			$perf.="$Items-r/s=$v3; $Items-w/s=$v4; ";
		}
		# KB Read/Writes per second.
		if($kbs){
			if(($v5 >= $kbs_crit) || ($v6 >= $kbs_crit)){
	                        $critical_state+='1';
	                # Warning?
       	         	}elsif(($v5 >= $kbs_warn) || ($v6 >= $kbs_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                       	 	$ok_state+='1';
                	}
			$perf.="$Items-rKB/s=$v5; $Items-wKB/s=$v6; ";
		}
		# Avarage wait time
		if($awt){
			if(($v9 >= $awt_crit)){
                        	$critical_state+='1';
                	# Warning?
                	}elsif(($v9 >= $awt_warn)){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-await=$v9; ";
		}
		# Avarage service time issuing time
		if($svc){
			if($v10 >= $svc_crit){
       	                	$critical_state+='1';
                	# Warning?
                	}elsif($v10 >= $svc_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-svctm=$v10; "
		}
		# Disk bandwidth Utilization
		if($dbu){
			if($v11 >= $dbu_crit){
                	        $critical_state+='1';
              	  	# Warning?
               	 	}elsif($v11 >= $dbu_warn){
                        	$warning_state+='1';
                	# Ok
                	}else{
                        	$ok_state+='1';
                	}
			$perf.="$Items-util=$v11%; ";
		}
	}else{
		print "At least select a value to measure..\n";
		exit 1;
	}
	# Print Debugging information about the validated values.
	if($debug){ print "### validated Devisions ###\n";
                    print "$Items|$v1|$v2|$v3|$v4|$v5|$v6|$v7|$v8|$v9|$v10|$v11|\n";
	}

	# Create a messages var.
	$mgs.="$Items=O:$ok_state,W:$warning_state,C:$critical_state; ";

	# Track the global state (1 crit 1 warn)
	if(($critical_state gt '0') || ( $critical_global gt '0')){
		$critical_global+='1';
	}
	if(($warning_state gt '0') || ( $warning_global gt '0')){
		$warning_global+='1';
	}
}

# Compose a nice nagios output.
if($critical_global >= '1'){
	print "CRITICAL:";
	$exit=2;
}elsif($warning_global >= '1'){
	print "WARNING:";
	$exit=1;
}else{
	print "OK:";
	$exit=0;
}
# Print the remainder, the most important data was processed.
print $mgs; if($prf){ print "|$perf"; } print "\n";
exit $exit;

###Subroutines
sub USAGE{
	print "
                Usage : $0 -d [Dev] [options]

		-p Print performance data about the measured samples.

		-d {grep string used on IOstat}
		examples;
                 sd     #All scsi devices.
                 hd     #All Cdrom devices.
		 sda	#Only device sda

                [Available Measurement Options]
                -rqm -rqmw val -rqmc val        # read/write merged             [#]
                -rws -rwsw val -rwsc val        # read/write per second.        [s]
                -kbs -kbsw val -kbsc val        # KBs read/written per second.  [s]
                -awt -awtw val -awtc val        # Avarage IO wait time.         [ms]
                -svc -svcw val -svcc val        # Avarage service IO wait time. [s]
                -dbu -dbuw val -dbuc val        # Disk utilization              [%]\n";
        exit 1;
}

check_iostat / check_io for nagios Version 0.9.5

Oke here is the first working version of check_iostat.pl

NEW Version available HERE

https://sysengineers.wordpress.com/2010/05/27/check_iostat-pl-version-0-9-7

Why this version?
Well to my big surprise I was not able to find any satisfying check plugin for diskio that didnt need all kinds of additional software or undocumented perl plugins. What i really wanted was a simple check plugin that would only require the default sysstat daemon allready present on allot of our systems (Oracle DB requirement).

Because no one seemed to have written such a plug-in I decided to write one myself. And here is the result.

How to get started?
Copy paste the source into a check_iostat.pl file within nagios/libexec.

The following needs to be on your Linux machine.
sysstat must be installed!
iostat must be available!
perl (base) should be installed!

What can you do?
1. Let us know on what distro you have tested this code! And or what changes you made to make it work.
2. Tell me if you spotted any improvements in the code.
3. Tell me if there are any bugs.

What more?
Questions? Different requirements? Improvements? Code cleanup?
Please let me know…

Tested with?
PERL
v5.8.8
v5.8.3

LINUX
Enterprise Linux Enterprise Linux Server release 5.3 (Carthage)
Enterprise Linux Enterprise Linux Server release 5.2 (Carthage)
SUSE LINUX Enterprise Server 9 (i586)

Note!
the code is still a bit messy but functional. Keep an eye out here for updates. I will be cleaning up this code further.

Rgrds,
Chris.

Code below…
Read the rest of this entry

Phase one, Check IOStat for Nagios.

Full Working version can be found here

/* CHECK OUT THE LINK AT THE TOP OF THIS POST 😉 */
/* OR CHECK THE SOURCE DIRECTLY HERE ;               
     http://technology.amis.nl/download/iostat/

    THIS SCRIPT REQUIRES THE SYSSTAT PACKAGE (IOSTAT)
*/

Thanks, Rgrds,

Adding perfmon counters using nrpe and centreon

In this little tutorial a detailed description on how to succesfully monitor and add various windows counters using the check_nrpe command and the NSClient++ agent for windows using the Centreon configuration and Monitoring GUI for Nagios. Yup, its all open source, and free for usage…
Read the rest of this entry

Nagios – XI

Yey!

yeah, i have luckily become a tester for the new Nagios XI (eXtended Interface) tool and I thought…. Lets devote a post to this new product!

Well first i was a bit surprised that the new product comes as a VM package meaning that you will download a virtual machine with all the required settings pre-configured for you. When reading various posts on the subject, its all support related, which brings me to the second point. Nope, Nagios XI will not be open source as in “free for download”, but it will be open source as in “your free to develop ontop of the original product”.

Yea i know this will raise allot of questions, but drilling down to the source of this ‘little evil’ it seems that developers need to be payed, so lets blame society for this and not the people developing and releasing the product.

What does it do?
Well the Nagios-Core (which is and stays free for download) monitors network nodes using check_commands that can be utilized by nagios to check for a wide range of network services like; Ping,Oracle,NTP,DHCP,CPU,MEM,DISKSpace.

Using the data the Nagios-Core collects there are a wide range of exsisting GUIs that can make this data visible in many different ways like; headsup-displays,performance-graphs,traffic-lights etc. And allows people to be notified using mail,sms,or other means.

Whats XI?
Well most of the GUIs had a mayor downside, it required a fair amount of know how to get it up and running. You needed to compile allot of tar-bals, install allot different RPMs and next you needed to make all these different things work together using some kind of a unified configuration that could reach 1M lines easily when you wanted all the fancy features.

Nagios-XI primarily makes the nagios tool and its GUI available for non-skilled users that dont have any affinity with linux. Its a VMware image that you can boot easily using a VMware player. Next thing you need to do is configure an IP (with extended manual) and open your explorer. The rest is done from there, pre-configured and working without a hassle.

Next to that the GUI is fully graphical including configuration wizards, custom dashboards (drag-drop style), custom views, custom almost everything. In short, Next, Next, Finish!

Im not sure seasoned engineers like myself would buy this product quickly, most of us would compile, configure, and download a GNU gui and work from there. But i do think there is a large market out there of engineers that dont have the required time, or linux know-how to get up and running. For these people i think Nagios XI will be a welcome alternative!

Rgrds,

Altering the Nagios daemon startup script to include NDO.

previously I wrote an article on how to create a deamon script for ndo. But when you are using Centreon the only “nice” way to do this is by altering the Nagios startupscript to include the ndo part.

Here is what i have done to make this possible.

First i wrote a function to find the PIDs for the ndo deamon process based on a specific config. In this one the config is hardcoded,
but you might also replace the $NagiosNdoConfig with $1 instead and call the function like;

getNdoPid “/usr/local/nagios/etc/yourconfig.cfg”

getNdoPid ()
{
 #Declare a var containing the correct ndo PID, there are processes being forked from ndo so we need to
 #do some awk filtering also to fetch the correct one.
 #Not that the parent process always has a parent pid "1" so we use that to filter the parent from the childs.
 ndoPID=`ps -ef | grep $NagiosNdoConf | grep "?" | awk -F ' '  '{if($3 == '1') print $2}'`
        #next we validate if we got an pid returned to us, and fill a wrapper that we will use like $? that ill convieniently call "ls" LastState.
        if [[ "$ndoPID" == '' ]]; then
            ls=1;
        else
            ls=0;
        fi
}

Next using the getNdoPid function u wrote another two functions to start and to stop the ndo daemon. I choose this method so i can include these function inside the existing start stop scripting used by nagios. In effect when you start nagios, th start case select is used which will call our ndo start script.

The ndo kill function

kill_ndo ()
{
        #Find the actual PID
        if [[ "$ndoPID" == '' ]]; then
             #No process running to kill...
             ls=0;
        else
             kill $ndoPID;
             sleep 2 #parent needs some time to kill the child processes if any
             getNdoPid
             if [[ "$ls" == '1' ]]; then
                   ls=0;
             else
                   ls=1;
             fi
        fi
}

and the start portion…
The ndo start function

start_ndo ()
{
        #always make sure ndo isnt running!
        $NagiosNdo -c $NagiosNdoConf;
        if [[ "$?" == '0' ]]; then
                ls=0;
        else
                ls=1;
        fi
}

Again i am using the ls (laststate) var to save the last state of the executed command. This is important because the state of a command can only be tested right after execution of that command. by using the ls var i make sure i am always testing the correct result. this is because the $? is also overwritten when performing an var assignment, if test etc.

Next I added a few vars for configuration, stuff like where the ndo2db bin is located, and the config file.

NagiosNdo=/usr/sbin/ndo2db;
NagiosNdoConf=/usr/local/nagios/etc/ndo2db.cfg;

naturally the NDO bin could also be found like;
NagiosNdo=`which ndo2db`;
Bu this will require the ndo2db bin to be somewhere in the path var. We are not sure this is always the case because there is no consensus on where these nagios bins should be placed. This may vary from distro to distro and from user to user. In my case, it being placed inside /user/bin this whould also work.

I also extended the functionality of the startupscript by adding new options to start, stop and restart the ndo deamon by using the nagios startupscript. This is what i did.

inside the “case” statement where the “/etc/init.d/nagios args” are tested i added some new options namely “startndo, stopndo, restartndo” and this is what it looks like.

For the option “/etc/init.d/nagios startndo”

 startndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                    start_ndo
                    if [[ "$ls" == '0' ]]; then
                        echo 'NDO deamon started succesfully';
                        exit 0;
                    else
                        echo 'Failed to start NDO, check your logging for more info';
                        exit 1;
                    fi
                else
                    echo "Ndo deamon allready running with PID : $ndoPID";
                    exit 1;
                fi
                ;;

for the “/etc/init.d/nagios stopndo” option

stopndo)
                getNdoPid
                if [[ "$ls" == '1' ]]; then
                     echo "$ls";
                     exit 1;
                else
                     kill_ndo
                     sleep 2 #it needs some time to kill the childs (that get ppid 1 when the parent quits)
                     getNdoPid
                     if [[ "$ls" == '1' ]]; then
                         echo "Ndo stopped succesfully";
                         exit 0;
                     else
                         echo "Unable to kill ndo, please review you logging";
                         exit 1;
                     fi
                fi
                ;;

And a restart option “/etc/init.d/nagios restartndo”

restartndo)
                $0 stopndo
                $0 startndo
                ;;

To include the start and stop options in the nagios start and stop process all you need to do is add the start and or stop options in there.
Here is an example

 start)
                echo -n "Starting nagios:"
                $NagiosBin -v $NagiosCfgFile > /dev/null 2>&1;
                if [ $? -eq 0 ]; then
                        su - $NagiosUser -c "touch $NagiosVarDir/nagios.log $NagiosRetentionFile"
                        rm -f $NagiosCommandFile
                        touch $NagiosRunFile
                        chown $NagiosUser:$NagiosGroup $NagiosRunFile
                        $NagiosBin -d $NagiosCfgFile
                        if [ -d $NagiosLockDir ]; then touch $NagiosLockDir/$NagiosLockFile; fi
                        #chmod 777 $NagiosCommandFile
                        start_ndo
                        echo " done."
                        exit 0
                else
                        echo "CONFIG ERROR!  Start aborted.  Check your Nagios configuration."
                        exit 1
                fi
                ;;
#Stop portion
stop)
                echo -n "Stopping nagios: "

                pid_nagios
                killproc_nagios nagios
                kill_ndo
                # now we have to wait for nagios to exit and remove its
                # own NagiosRunFile, otherwise a following "start" could
                # happen, and then the exiting nagios will remove the
                # new NagiosRunFile, allowing multiple nagios daemons
                # to (sooner or later) run - John Sellens
                #echo -n 'Waiting for nagios to exit .'
                for i in 1 2 3 4 5 6 7 8 9 10 ; do
                    if status_nagios > /dev/null; then
                        echo -n '.'
                        sleep 1
                    else
                        break
                    fi
                done
                if status_nagios > /dev/null; then
                    echo ''
                    echo 'Warning - nagios did not exit in a timely manner'
                else
                    echo 'done.'
                fi

                rm -f $NagiosStatusFile $NagiosRunFile $NagiosLockDir/$NagiosLockFile $NagiosCommandFile
                ;;

        status)
                pid_nagios
                printstatus_nagios nagios
                ;;

Now when i start and stop nagios using the centreon “start / stop / reload” options my ndo daemon is also started / stopped. Ps. This manual uses Nagios 3.0 and Centreon 2.2

This is what a restart looks like 😉

[root@UX127 var]# service nagios restartndo
Ndo stopped succesfully
NDO deamon started succesfully

Rgrds,

Templated mail for nagios / centreon.

This command enables you to dynamicly create a nice templated mail.

Save code below into a file inside the /usr/local/nagios/libexec/mailbytpl.php

On linux you can use the vi command to do so; i.e. $>vi /usr/local/nagios/libexec/mailbytpl.php

#!/usr/bin/php

<?php

// Lets define the defaults //
$showman = false;
$tpldata = false;
$debug = false;
$settings['from'] = 'centreon@amis.nl';
$settings['type'] = 'notification';
$settings['host'] = '{hostname?}';
$settings['reply'] = 'NULL';

// Dont change anything below! //
// Find and sort all the commandline arguments //
// Make a distinct difference between known settings and arguments later to be passed into the template //

if(@is_array($argv)){
// Define that the mail setting isnt passed till we realy found it in the argv
$settings['mail'] = false;
foreach($argv as $value){
$keyval = explode("=", $value);
if(array_key_exists('0', $keyval)){
$key = str_replace('--', '', $keyval[0]);
if(array_key_exists('1', $keyval)){
$val = $keyval[1];
}else{
$val = NULL;
}
}
// Default settings we want to fetch //
switch ($key){
case 'mail':
$settings['mail'] = true;
break;
case 'tplfile':
$settings['tplfile'] = $val;
break;
case 'to':
$settings['to'] = $val;
break;
case 'from':
$settings['from'] = $val;
break;
case 'type':
$settings['type'] = $val;
break;
case 'host':
$settings['host'] = $val;
break;
case 'reply':
$settings['reply'] = $val;
case 'verbose':
$debug=true;
break;
default:
                                // Next to the defaults we fetch additional values...
if(!strstr($key, 'mailbytpl.php')){
$arguments[$key] = $val;
}
}
$keyval = '';
$key = '';
$val = '';
}
$arguments['DATE'] = date('Y-m-d H:i:s');
}else{
// If we got no args (default {basename}.ext is allways passed, still need to fix that.//
// Consider this the spaceholder 😉 //
$showman = true;
}
// Validate if all the needed settings where found //
if(!empty($settings['mail']) && !empty($settings['tplfile']) && !empty($settings['to'])){
// Lets try to open the template file//
if($settings['mail']){
if($settings['tplfile']){
//Does the directory exist?//
if(is_dir(dirname($settings['tplfile']))){
if(opendir(dirname($settings['tplfile']))){
if(is_file($settings['tplfile'])){
$tpldata = file($settings['tplfile']);
}else{
die('ERR::Template file doesnt exist or couldnt be opened');
}
}else{
die('ERR::Template file directory coudnt be opened. please verify the rights!');
}
}else{
die('ERR::Template file directory doesnt exist. please verify its existance!');
}
}else{
$showman = true;
}
}else{
$showman = true;
}
// If we have content from the template file, we need to add the information too it //
if($tpldata){
if(count($tpldata) >= 1){
// If we found more then 1 rule we can continue //
// Lets Generate tablerows too place in the template //
$maildata = '';
$cc = '0';
foreach($arguments as $key => $value){
$maildata .= '
<tr>
<td class="datahead'.$cc.'">'.$key.'</td>
<td class="datacontent'.$cc.'">'.$value.'</td>
</tr>
';
$cc++;
}
$maildata .= '<!--Generated by mailbytemplate.php for nagios by AMIS Services BV.-->'."\r\n";
$mailbody ='';
// If there is an element called $DATAROWS$ then insert the pregenerated block//
foreach($tpldata as $lineno => $line){
$pattern = '$DATAROWS$';
$subject = $line;
if(preg_match($pattern, $subject, $matches, PREG_OFFSET_CAPTURE)){
//if there is a match we match it using the arguments//
//Match is found using $matches[0][0]//
$line = str_replace('$DATAROWS$', $maildata, $line);
}
$mailbody .= $line."\r\n";
}
}else{
// We could have loaded an empty file, lets tell the user! //
die('Template file was found to be empty');
}
}
if($mailbody){
                // You can add any header you like...
                $headers ="MIME-Version: 1.0 \r\n";
                $headers.="From: Centreon <".$settings['from'].">\r\n";
                $headers.="Reply-To: ".$settings['reply']." \r\n";
                $headers.="X-Mailer: PHP/".phpversion()."\r\n";
$headers.="Content-type: text/html; charset='us-ascii' \r\n";
$subject =$settings['type'].":: Notification from ".$settings['host']." ...";
mail($settings['to'], $subject, $mailbody, $headers);
}
}else{
$showman = true;
}

if($showman){
// If the mail command isnt found then show the manual //
echo "Using this module is fairly simple, first edit the mainfile mailbytpl.php and alter the defaults \r\n";
echo "Then run the file like the example using the required settings and adding your own using this \r\n";
echo "Format...\r\n";
echo "\r\n\r\n";
echo "{pathtofile}/mailbytpl.php [args]\r\n";
echo "\r\n\r\n";
echo "Valid arguments\r\n";
echo "\t--mail\t\t\t\t\t'Tell the script to execute the mail functionality'\r\n";
echo "\t--tplfile=[path-to-template]\t\t'The path the the template file that should be used by this script'\r\n";
echo "\t--to=[valid@mail.ext]\t\t\t'A valid mailaddress of the receipient,\$CONTACTMAIL$ within nagios\r\n";
echo "\t--from=[valid@mail.ext]\t\t\t'A valid from addres to exclude it from your junkmail folder'\r\n";
echo "\t--reply=[valid@mail.ext]\t\t'Used as reply-to header to redirect mail to different mailboxes. Defaults to 'NULL'\r\n";
echo "\t--type=[NOTIFICATIONTYPE]\t\t'Used in the subject of the mail i.e. [type]::notification for [host]'\r\n";
echo "\t--host=[HOSTNAME]\t\t\t'Used in the subject of the mail i.e. [type]::notification for [host]'\r\n";
echo "\r\n\r\n";
echo "Add your information to the template by adding additional custom entries. using the following syntax;\r\n";
echo "\t--KEY=VALUE\r\n";
echo "\r\n\r\n";
echo "Example for nagios:\r\n";
echo "\$USER1$/mailbytpl --mail --tplfile=\$USER1$\mail.tpl --to=example@mail.nl --from=example@mail.nl --reply=no-reply@mail.nl\r\n";
echo "--type=\$NOTIFICATIONTYPE$ --host=\$HOSTNAME$ --IP=\$HOSTADDRESS$ --DOWNTIME=\$HOSTDOWNTIME$ --YOUROTHERVAR=\$VALUE$ \r\n";
echo "\r\n\r\n\r\nScript by : Chris Gralike\r\nCompany : AMIS Services BV\r\n GPL:2009©\r\n";
}
?>

Next you can configure the command into centreon as a ‘notification’ command that takes the following commands:

–mail                                                         Should be set, enables the mail functionality
–tplfile=[path to template]                  ‘The is the html template that will be used
–to=[valid@email.com]                       Set the receipient
–from=[valid@email.com]                  Set the sender
–reply=[valid@email.com]                  Set the return-path
–type=[NOTIFICATIONTYPE]          used in the subject of the mail.
–host=[HOSTNAME]                           used in the subject of the mail.
–[KEY]=[VALUE]                                  add additional information to the template, these fields are autofilled if used in the template.

example:

$USER1$/mailbytpl --mail --tplfile=\$USER1$\mail.tpl --to=example@mail.nl --from=example@mail.nl --reply=no-reply@mail.nl --type=\$NOTIFICATIONTYPE$ --host=\$HOSTNAME$ --IP=\$HOSTADDRESS$ --DOWNTIME=\$HOSTDOWNTIME$

Next create a template file to point to. I called mine mail.tpl

<html>
<head>
<title>Network notification</title>
<style>
body {background-color:#999; text-align:left; font-family:verdana;}
table{border:1px solid #020245; width:100%;}
th{background-color:#020245; color:#fff; border-bottom:1px solid #020245; text-align:left;}
td{border-bottom:1px solid #020245; background-color:#ccc; font-size:11px;}
tr{height:20px;}
#1{border-style:none; background-color:#ccc;}
.2{width:150px;  font-size:12px; font-weight:bold;}
.3{width:3px;}
</style>
</head>
<body>
<table cellspacing=0 align='center'>
$DATAROWS$</table>
</body>
</html>

Well hope this was usefull for ya 😉

#!/usr/bin/php
<?php
// Lets define the defaults //
$showman = false;
$tpldata = false;
$debug = false;
$settings[‘from’] = ‘centreon@amis.nl’;
$settings[‘type’] = ‘notification’;
$settings[‘host’] = ‘{hostname?}’;
$settings[‘reply’] = ‘NULL’;
// Dont change anything below! //
// Find and sort all the commandline arguments //
// Make a distinct difference between known settings and arguments later to be passed into the template //
if(@is_array($argv)){
        // Define that the mail setting isnt passed till we realy found it in the argv
        $settings[‘mail’] = false;
        foreach($argv as $value){
                $keyval = explode(“=”, $value);
                if(array_key_exists(‘0’, $keyval)){
                        $key = str_replace(‘–‘, ”, $keyval[0]);
                        if(array_key_exists(‘1’, $keyval)){
                                $val = $keyval[1];
                        }else{
                                $val = NULL;
                        }
                }
                // Default settings we want to fetch //
                switch ($key){
                        case ‘mail’:
                                $settings[‘mail’] = true;
                                break;
                        case ‘tplfile’:
                                $settings[‘tplfile’] = $val;
                                break;
                        case ‘to’:
                                $settings[‘to’] = $val;
                                break;
                        case ‘from’:
                                $settings[‘from’] = $val;

NRPE – Check_memory script

this script is intended to “mime” the NSClient++ checkMem option on linux. Most check_mem scripts i have found where rather “minimal” so i ended up writing my own one. Feel free to test, use, alter, redis or what ever with it 🙂

Here is a new version. Improvements.

– Var footprints reduced to a bare minimum.
– Free command is now only executed once.
– Corrected the swap validation that was using the wrong vars.
– Added small corrections like adding ; within “ execs to mark end of command etc.

Here you go 🙂

    #!/bin/bash
#
#
# @Type 	: Bash
# @Date 	: 19-05-2009
# @Author 	: Chris Gralike
# @Category	: Nagios Monitoring/SLA
# @Category	: MemoryCheck Linux, All memory spaces
# @Company	: AMIS Services BV.
# @License	: GNU_Public
# @ToDo		: See Comments in script. Suggestions are welcome... 
##

## You are free to alter, modify and distribute the content of this file
 # This file is offered "as is", and we offer no guarantee on functionality
 # and or outcome of this check. Neither can the author nor AMIS be
 # responsible for any damages caE by this script. 
 #
 # Have fun with it, and we hope it proves usefull
 # Script is based on precentage orientated monitoring / SLAs
 ##

#Get Options
while getopts 'u:v:w:x:y:z:hpef' OPT; do
  case $OPT in
    u) U=$OPTARG;;
    v) V=$OPTARG;;
    w) W=$OPTARG;;
    x) X=$OPTARG;;
    y) Y=$OPTARG;;
    z) Z=$OPTARG;;
    e)  E="yes";;
    f)  FR="yes";;
    p)  P="yes";;
    h)  H="yes";;
    *)  unknown="yes";;
  esac
done
#Help Output
USAGE="
	usage: $0 [ -option [value]]
	
	[options:]
		-h		-&gt;	Show this help page
		-p		-&gt;	Show performance options
		-e		-&gt;	Warn/Crit based on usage precentage, warn/crit based on usage orientation
		-f		-&gt;	Warn/Crit based on free precantage, warn/crit based on free space orientation
		-u [valeu]	-&gt;	Physical warning treshold (in %)
		-v [value]	-&gt;	Physical critical treshold (in %)
		-w [value]	-&gt;	Virtual waring treshold (in %)	
		-x [value]	-&gt;	Virtual critical treshold (in%)
		-y [value]	-&gt;	Swap warning value (in%)
		-z [value]	-&gt;	Swap critical value (in%)
"
#Show usage if requested
if [ "$H" = "yes" -o $# -lt 1 ]; then
	echo "$USAGE"
	exit 0
fi
#Check if all the thresholds are defined.
if [ "$W" = "" -o "$X" = "" -o "$U" = "" -o "$V" = "" -o "$Y" = "" -o "$Z" = "" ]; then
	echo "All the [u,v,w,x,y,z] options should be defined! \r\n"
	exit 0
fi
#Check if all the thresholds are integers
# if syntax is $0 -e -u 10 -v 10 -w 10 -x 10 -y 10 -z 10 -p things are allright
# if syntax is $0 -e -u 10 -v 10 -w 10 -x 10 -y 10 -z -p A bunch of errors arise because " " is not equal too ""
# and failes the check above.
# This typo needs to be fixed someday...
#Check the orientation
if [ "$E" = "yes" -a "$FR" = "yes" ]; then
	echo "You cant use both the free, as E orientation for the tresholds. Please select -e or -f as orientation"
	exit 0
elif [ "$E" = "yes" ]; then
	# Check the critical / warning thresholds
	if [ "$W" -gt "$X" -o "$U" -gt "$V" -o "$Y" -gt "$Z" ]; then
		echo "Warning: Warning &gt; Critical while using usage orientation!"
	fi	

elif [ "$FR" = "yes" ]; then
	# Check the warning / Critical thresholds
	if [ "$W" -lt "$X" -o "$U" -lt "$V" -o "$Y" -lt "$Z" ]; then
                echo "Warning: Warning &lt; Critical while using free space orientation!&quot;
        fi
else
	echo &quot;Please define an orientation using either the -e or the -f option&quot;
	exit 0;
fi

#Get physiscal numbers 
FRE=`free -m`

PT=`echo &quot;$FRE&quot; | grep Mem | awk &#39;{ print $2; exit;}&#39;;`
PU=`echo &quot;$FRE&quot; | grep Mem | awk &#39;{ print $3; exit;}&#39;;`
FP=$(($PT-$PU));
#Get virtual memory numbers
VU=`echo &quot;$FRE&quot; | grep buffers/cache | awk &#39;{ print $3; exit;}&#39;;`
VF=`echo &quot;$FRE&quot; | grep buffers/cache | awk &#39;{ print $4; exit;}&#39;;`
VT=$(($VU+$VF));
#Get Swapped memory numbers
ST=`echo &quot;$FRE&quot; | grep Swap | awk &#39;{ print $2; exit;}&#39;;`
SU=`echo &quot;$FRE&quot; | grep Swap | awk &#39;{ print $3; exit;}&#39;;`
SF=$(($ST-$SU));

#still needs to be done in an nice syntax.
#Start validating our numbers.
if [ &quot;$E&quot; = &quot;yes&quot; ]; then
	#calculate E precentages
	PPF=`echo &quot;scale=5; (100/$PT)*$PU&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	VPF=`echo &quot;scale=5; (100/$VT)*$VU&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	SPF=`echo &quot;scale=5; (100/$ST)*$SU&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	#still needs to be done in an nice syntax.
	if [ &quot;$P&quot; = &quot;yes&quot; ]; then
        	#not sure about the syntax...
		PD=&quot;|Ph=$PPF%;$U;$V; Vi=$VPF%;$W;$X; Sw=$SPF%;$Y;$Z;&quot;
	else
        	PD=&quot;&quot;
	fi

	MSG=&quot;Ph:$PU/$PT($PPF%), Vi:$VU/$VT($VPF%), Sw:$SU/$ST($SPF%) $PD&quot;

	#Validate Physical Memory
	if [ &quot;$PPF&quot; -gt &quot;$U&quot; -a &quot;$PPF&quot; -gt &quot;$V&quot; ]; then
		NPE=2
	elif [ &quot;$PPF&quot; -gt &quot;$U&quot; -a &quot;$PPF&quot; -lt &quot;$V&quot; ]; then
		NPE=1
	elif [ &quot;$PPF&quot; -lt &quot;$U&quot; -a &quot;$PPF&quot; -lt &quot;$V&quot; ]; then
		NPE=0
	else
		#unknown crit and warn the same?
		NPE=3
	fi 
	#Validate Virtual Memory
	if [ &quot;$VPF&quot; -gt &quot;$W&quot; -a &quot;$VPF&quot; -gt &quot;$X&quot; ]; then
       	        NVE=2
        elif [ &quot;$VPF&quot; -gt &quot;$W&quot; -a &quot;$VPF&quot; -lt &quot;$X&quot; ]; then
       		NVE=1
   	elif [ &quot;$VPF&quot; -lt &quot;$W&quot; -a &quot;$VPF&quot; -lt &quot;$X&quot; ]; then
               	NVE=0
       	else
               	#unknown crit and warn the same?
               	NVE=3
       	fi
	#Validate Swap memory
	if [ &quot;$SPF&quot; -gt &quot;$W&quot; -a &quot;$SPF&quot; -gt &quot;$X&quot; ]; then
                NSE=2
        elif [ &quot;$SPF&quot; -gt &quot;$W&quot; -a &quot;$SPF&quot; -lt &quot;$X&quot; ]; then
                NSE=1
        elif [ &quot;$SPF&quot; -lt &quot;$W&quot; -a &quot;$SPF&quot; -lt &quot;$X&quot; ]; then
                NSE=0
        else
                #unknown crit and warn the same?
                NSE=3
        fi
	#We only want to see the most critical,...
	if [ &quot;$NPE&quot; -eq &quot;2&quot; -o &quot;$NVE&quot; -eq &quot;2&quot; -o &quot;$NSE&quot; -eq &quot;2&quot; ]; then
		echo &quot;Critical - $MSG&quot;
		exit 2
	elif [ &quot;$NPE&quot; -eq &quot;1&quot; -o &quot;$NVE&quot; -eq &quot;1&quot; -o &quot;$NSE&quot; -eq &quot;1&quot; ]; then
		echo &quot;Warning - $MSG&quot;
		exit 1
	elif [ &quot;$NPE&quot; -eq &quot;0&quot; -a &quot;$NVE&quot; -eq &quot;0&quot; -a &quot;$NSE&quot; -eq &quot;0&quot; ]; then
                echo &quot;Ok - $MSG&quot;
                exit 0
	else
		echo &quot;Unknown - $MSG&quot;
		exit 3
	fi
elif [ &quot;$FR&quot; = &quot;yes&quot; ]; then
	#calculate free precentages
	PPF=`echo &quot;scale=5; (100/$PT)*$FP&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	VPF=`echo &quot;scale=5; (100/$VT)*$VF&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	SPF=`echo &quot;scale=5; (100/$ST)*$SF&quot; | bc -l | awk -F &#39;.&#39; &#39;{ print $1; exit; }&#39;`
	
	#still needs to be done in an nice syntax.
	if [ &quot;$P&quot; = &quot;yes&quot; ]; then
			#not sure about the syntax...
			PD=&quot;|Ph=$PPF%;$U;$V; Vi=$VPF%;$W;$X; Sw=$SPF%;$Y;$Z;&quot;
	else
			PD=&quot;&quot;
	fi

	MSG=&quot;Ph:$FP/$PT($PPF%), Vi:$VF/$VT($VPF%), Sw:$SF/$ST($SPF%) $PD&quot;

        #Validate Physical Memory
        if [ &quot;$PPF&quot; -lt &quot;$U&quot; -a &quot;$PPF&quot; -lt &quot;$V&quot; ]; then
                NPE=2
        elif [ &quot;$PPF&quot; -lt &quot;$U&quot; -a &quot;$PPF&quot; -gt &quot;$V&quot; ]; then
                NPE=1
        elif [ &quot;$PPF&quot; -gt &quot;$U&quot; -a &quot;$PPF&quot; -gt &quot;$V&quot; ]; then
                NPE=0
        else
                #unknown crit and warn the same?
                NPE=3
        fi
        #Validate Virtual Memory
        if [ &quot;$VPF&quot; -lt &quot;$W&quot; -a &quot;$VPF&quot; -lt &quot;$X&quot; ]; then
                NVE=2
        elif [ &quot;$VPF&quot; -lt &quot;$W&quot; -a &quot;$VPF&quot; -gt &quot;$X&quot; ]; then
                NVE=1
        elif [ &quot;$VPF&quot; -gt &quot;$W&quot; -a &quot;$VPF&quot; -gt &quot;$X&quot; ]; then
                NVE=0
        else
                #unknown crit and warn the same?
                NVE=3
        fi
        #Validate Swap memory
        if [ &quot;$SPF&quot; -lt &quot;$W&quot; -a &quot;$SPF&quot; -lt &quot;$X&quot; ]; then
                NSE=2
        elif [ &quot;$SPF&quot; -lt &quot;$W&quot; -a &quot;$SPF&quot; -gt &quot;$X&quot; ]; then
                NSE=1
        elif [ &quot;$SPF&quot; -gt &quot;$W&quot; -a &quot;$SPF&quot; -gt &quot;$X&quot; ]; then
                NSE=0
        else
                #unknown crit and warn the same?
                NSE=3
        fi
        #We only want to see the most critical,...
        if [ &quot;$NPE&quot; -eq &quot;2&quot; -o &quot;$NVE&quot; -eq &quot;2&quot; -o &quot;$NSE&quot; -eq &quot;2&quot; ]; then
                echo &quot;Critical - $MSG&quot;
                exit 2
        elif [ &quot;$NPE&quot; -eq &quot;1&quot; -o &quot;$NVE&quot; -eq &quot;1&quot; -o &quot;$NSE&quot; -eq &quot;1&quot; ]; then
                echo &quot;Warning - $MSG&quot;
                exit 1
        elif [ &quot;$NPE&quot; -eq &quot;0&quot; -a &quot;$NVE&quot; -eq &quot;0&quot; -a &quot;$NSE&quot; -eq &quot;0&quot; ]; then
                echo &quot;Ok - $MSG&quot;
                exit 0
        else
		 echo &quot;Unknown - $MSG&quot;
                exit 3
        fi
else
	echo &quot;Something is very off..... please review all the settings, or report this as a bug&quot;
	exit 3
fi

Rgrds Chris