#!/usr/bin/perl -w # vim:ts=4 # check_esx Version 2.0 # # Check the status of a virtual machine on a VMware ESX server, via SNMP # Return status in format for either Nagios or MRTG # # Steve Shipway (www.steveshipway.org) Nov 2004 # Released under GNU GPL # # Usage: # check_esx [-N|-M] [-C community] -H hostname [-v virtualhost] [-l thing [-w warn -c crit]] # -N nagios mode (need -w and -c for CPU, MEM), -M MRTG mode # -l thing can be CPU, MEM, STATE, LIST, LISTNET, NET # -v virtualhost if not specified uses total ESX system stats. Required for STATE # default community is public # default mode is Nagios use Net::SNMP; use Getopt::Std; my($STATEFILE) = "/var/tmp/esx_state"; # For rate counter (if not agent) my($VMOID) = "1.3.6.1.4.1.6876"; # VMware MIB my($UCDOID) = "1.3.6.1.4.1.2021.1000.10"; # where to find the agent plugin my($SYSOID) = "1.3.6.1.2.1.1.1.0"; # system object to test SNMP working my($OK,$WARNING,$CRITICAL,$UNKNOWN) = (0,1,2,3); my($DEBUG) = 0; my($TIMEOUT) = 10; my($from,$to) = (0,99999); my($snmp,$resp,$snmperr); my($hostname) = ''; my($community) = 'public'; # Default community string my($vhost) = ''; my($A, $B, $MSG) = ('U','U',''); my($STATUS) = $UNKNOWN; my($MODE) = 0; my($VMID) = -1; # set to -1 if not running my($VMNO) = -1; # set to -1 if not defined my($warn,$crit) = (-1,-1); # usage warn/crit my($rwarn,$rcrit) = (10,15); # cpu readytime warn/crit my(%lookup) = (); my(%states) = (); my(%tmpnet) = (); use vars qw($opt_C $opt_H $opt_N $opt_M $opt_h $opt_c $opt_t $opt_i $opt_d $opt_w $opt_l $opt_v); sub base($) { return $1 if( $_[0]=~/^(\S+)/ ); return $_[0]; } sub dohelp { print "Usage: check_esx [-d][-h] -H host [-C community] [-N | -M [-r]]\n -l check [-v vhost] [-i interface] [-c crit -w warn]]\n"; print "-l can be CPU MEM STATE LIST NET LISTNET\n-N : Nagios mode\n-M : MRTG mode ( -r specifies rate rather than counter)\n-c -w : Nagios thresholds\n-i : Only valid for NET\n\n"; print "\nFor MRTG, \nCPU is total seconds (counter) for vhost or total over all if no vhost given.\nMEM is memory remaining in K. \nSTATE is 1 for up, 0 for down. \nLIST is number of vhosts. \nNET is network throughput in bytes for specified vhost and/or interface (total\nof all if not specified).\n"; print "\nFor Nagios, specify thresholds as follows.\nCPU is percentage since last check, if possible (gives UNKNOWN otherwise).\nMEM is memory remaining in K or %.\nSTATE is CRITICAL if vhost is down.\nLIST is WARN if some are down, CRIT is all vhosts are down.\nNET is bytes/sec since last check, if possible (otherwise UNKNOWN).\n\n"; print "Thresholds for MEM or LIST under Nagios, can be in K or %\n"; print "eg: -w 1024K -w 80%\n"; exit 0; } sub readstate { return if(! -r $STATEFILE); open STATE, "<$STATEFILE"; flock STATE,1; # read lock while( ) { $states{$1}=$2 if( /^(\S+)=(\d+)/ ); } flock STATE,8; # unlock close STATE; } sub writestate { my(%new) = @_; if(-r $STATEFILE) { open STATE, "<$STATEFILE"; flock STATE,1; # read lock while( ) { $states{$1}=$2 if( /^(\S+)=(\d+)/ ); } flock STATE,8; # unlock close STATE; } # Eek, a race condition... open STATE, ">$STATEFILE"; flock STATE,2; # write lock foreach ( keys %new ) { $states{$_} = $new{$_}; } foreach ( keys %states ) { print STATE "$_=".$states{$_}."\n"; } flock STATE,8; # unlock close STATE; } sub dooutput { if( $MODE ) { # MRTG $A = 'U' if(!defined $A); $B = $A if(!defined $B); $MSG = "Returned values: $A, $B\n" if(!$MSG); print "$A\n$B\n\n$MSG\n"; exit 0; } else { # Nagios print "$MSG\n"; exit $STATUS; } # should never get here } # Read all the VM IDs from the vmware-snmpd MIB sub getvmid { print "(snmp lookup)\n" if($DEBUG); ($snmp,$snmperr) = Net::SNMP->session( -hostname=>$hostname, -community=>$community, -timeout=>$TIMEOUT ); if($snmperr) { print "($snmperr)\n" if($DEBUG); $MSG = "Error: $snmperr"; $STATUS = $UNKNOWN; dooutput; # exit exit(0); } $resp = $snmp->get_table( -baseoid=>"$VMOID.2.1.1"); if(!$resp) { $resp = $snmp->get_request( -varbindlist=>[ "$VMOID.1.1.0" ] ); if(!$resp) { $MSG = "Error: No VMWare SNMP agent running on this server"; $STATUS = $UNKNOWN; } else { print "No guests are defined on this server\n" if($DEBUG); $MSG = "No guests defined on this server"; return; } dooutput; # exit exit(0); } foreach my $oid ( keys %$resp ) { $oid =~ /(\d+)\.(\d+)$/; if( $1 == 2 ) { $lookup{$resp->{$oid}} = $2; $lookup{$2} = $resp->{"$VMOID.2.1.1.7.$2"}; $lookup{$resp->{"$VMOID.2.1.1.7.$2"}} = $resp->{$oid}; # } elsif( $1 == 7 ) { # $lookup{$2} = $resp->{$oid}; } } return if(!$vhost); # we're just getting the table if(defined $lookup{$vhost}) { $VMNO = $lookup{$vhost}; if( defined $lookup{$VMNO} ) { $VMID = $lookup{$VMNO}; } else { $STATUS = $CRITICAL; $MSG = "Virtual host $vhost($VMNO) is not running!"; } } else { # lets see if they just gave part of the vhost name? foreach ( keys %lookup ) { if( /^$vhost/i ) { $VMNO = $lookup{$_}; if( defined $lookup{$VMNO} ) { $VMID = $lookup{$VMNO}; } else { $STATUS = $CRITICAL; $MSG = "Virtual host $vhost($VMNO) is not running!"; } last; } } if($VMNO<0) { $STATUS = $UNKNOWN; $MSG = "Virtual host $vhost is not defined!"; dooutput; # exit exit(0); } } print "(hostno=$VMNO, ID=$VMID)\n" if($DEBUG); } sub listvm { my(@vh); %lookup = (); @vh = (); print "(snmp lookup)\n" if($DEBUG); ($snmp,$snmperr) = Net::SNMP->session( -hostname=>$hostname, -community=>$community, -timeout=>$TIMEOUT ); if($snmperr) { $A = $B = 'U'; print "($snmperr)\n" if($DEBUG); $MSG = "Error: $snmperr"; $STATUS = $UNKNOWN; dooutput; # exit exit(0); } $resp = $snmp->get_table( -baseoid=>"$VMOID.2.1.1"); if(!$resp) { $resp = $snmp->get_request( -varbindlist=>[ "$VMOID.1.1.0" ] ); if(!$resp) { $A = $B = 'U'; $MSG = "Error: No VMWare SNMP agent running"; $STATUS = $UNKNOWN; } else { $A = $B = 0; $MSG = "No VHosts are defined on this server"; $STATUS = $OK; } dooutput; # exit exit(0); } foreach my $oid ( keys %$resp ) { $oid =~ /(\d+)\.(\d+)$/; if( $1 == 2 ) { $lookup{$resp->{$oid}} = $2; push @vh, $resp->{$oid}; } elsif( $1 == 7 ) { $lookup{$2} = $resp->{$oid}; } } $A = $B = 0; foreach ( @vh ) { $B++; if( defined $lookup{$lookup{$_}} ) { $_ .= "(up)"; $A++; } } $MSG = "VHosts: $A/$B up: ".(join ", ",@vh); $STATUS = $OK; } sub readnet { my($found); $resp = $snmp->get_table( -baseoid=>"$VMOID.3.4.1"); if(!$resp) { $resp = $snmp->get_request( -varbindlist=>[ "$VMOID.1.1" ] ); if($resp) { $A = $B = 0; $MSG = "No VHosts defined"; $STATUS = $OK; return; } $MSG = "Error: Unable to retrieve SNMP data"; $STATUS = $UNKNOWN; return; } foreach my $oid ( keys %$resp ) { $oid =~ /(\d+)\.(\d+)$/; # Type, index. if( $1 == 3 ) { $tmpnet{$2} = [ $resp->{$oid}, $resp->{"$VMOID.3.4.1.2.$2"}, ($resp->{"$VMOID.3.4.1.7.$2"}*1024), ($resp->{"$VMOID.3.4.1.9.$2"}*1024) ]; } } return if($opt_l =~ /LIST/); # We now have all the network statistics indexed by card or VMID $A = $B = 0; $found = 0; foreach ( keys %tmpnet ) { if((($VMID<0) or ($VMID == $tmpnet{$_}[0])) # vm matches and ((!$opt_i) or ($opt_i eq $tmpnet{$_}[1]))) { # net matches $A += $tmpnet{$_}[2]; $B += $tmpnet{$_}[3]; $found = 1; } } if(!$found) { $MSG = "No network interfaces exist for "; $MSG .= "vhost $vhost" if($VMID>-1); $MSG .= " and " if($VMID>-1 and $opt_i); $MSG .= " interface $opt_i" if ($opt_i); $STATUS = $UNKNOWN; } } ########################################################################### # Read general memory and CPU data from vmware-snmpd # This is what we do if we can't get the detailed information. sub readcpu { my($k,@k); my($t1,$t2,$a1); $MSG = ""; $A = 0; $B = 0; if( !$MODE or $opt_r ) { readstate; $t1 = $states{"$hostname-CPU-$vhost-time"}; $a1 = $states{"$hostname-CPU-$vhost"}; $t2 = time; } @k = (); if( $VMID < 0 ) { foreach ( keys %lookup ) { push @k, "$VMOID.3.1.2.1.3.".$_ if( /^\d+$/ and $_>99); } } else { $k = "$VMOID.3.1.2.1.3.$VMID"; @k = ( $k ); } foreach $k ( @k ) { print "(retrieving $k)\n" if($DEBUG); } $resp = $snmp->get_request( -varbindlist=>\@k ); if( $resp ) { if($VMID<0){ $A = 0; foreach ( keys %$resp ) { $A += $resp->{$_}; print "$_: ".$resp->{$_}."\n" if($DEBUG); } } else { $A = $resp->{$k}; } $B = 0; } else { $A = $B = 'U'; if($VMID<0){ $MSG = "Unable to retrieve CPU statistics for ESX server: ".$snmp->error; } else { $MSG = "Unable to retrieve CPU statistics for $vhost: ".$snmp->error; } $STATUS = $UNKNOWN; } if(!$MSG){ # IE, no errors $MSG = "CPU has used $A seconds"; $MSG .= " on $vhost" if($vhost); if( !$MODE or $opt_r ) { writestate( "$hostname-CPU-$vhost"=>$A, "$hostname-CPU-$vhost-time"=>$t2 ) if(!$t1 or ($t2-$t1)>30); if(!$t1 or !$a1 or ($t1 >= $t2) or ( ($t2-$t1)>1000 ) ) { if($vhost) { $MSG = "No saved state for $vhost CPU time yet - wait for next poll."; } else { $MSG = "No saved state for ESX system CPU time yet - wait for next poll."; } $A = $B = "U"; $STATUS = $UNKNOWN; } else { print "Usage: $A-$a1 in $t2-$t1 = ".($A-$a1)." in ".($t2-$t1) if($DEBUG); $A = int((($A - $a1)/($t2 - $t1))*10000)/100; print " = $A\n" if($DEBUG); $B = 0; $MSG = "CPU usage is $A% "; $MSG .= "on $vhost" if($vhost); $MSG .= " (".($t2-$t1)."s average)"; if($A>110 or $A<0) { $B = $A = 0; $MSG = "Error reading CPU usage information." } } } } } sub readmem { my($k1,$k2); if($VMID < 0) { $k1 = "$VMOID.3.2.1.0"; # Total physical present $k2 = "$VMOID.3.2.3.0"; # Memory free } else { $k1 = "$VMOID.3.2.4.1.3.$VMID"; # VM memory max $k2 = "$VMOID.3.2.4.1.4.$VMID"; # VM memory used } print "(retrieving $k1,$k2)\n" if($DEBUG); $resp = $snmp->get_request( -varbindlist=>[$k1,$k2] ); if( $resp ) { if($VMID < 0 ) { $A = $resp->{$k2}; $B = $resp->{$k1}; } else { $A = $resp->{$k2}; $B = $resp->{$k1}*1024; $A = $B - $A; # memory remaining } } else { $A = $B = 'U'; if($VMID<0) { $MSG = "Unable to retrieve memory statistics for ESX server: ".$snmp->error; } else { $MSG = "Unable to retrieve memory statistics for $vhost: ".$snmp->error; } $STATUS = $UNKNOWN; } } ########################################################################### # Read detailed memory and CPU data from extended snmp daemon, if possible my(%stats) = (); sub readagent { $MSG = ""; $resp = $snmp->get_table( -baseoid=>"$UCDOID" ); return 1 if(!$resp); # Fall back to the old way if( $resp->{"$UCDOID.2.1"} ne 'vmware' ) { $MSG = "Incorrect SNMPD configuration: found '".$resp->{"$UCDOID.2.1"}."' when expected 'vmware'"; $STATUS = $UNKNOWN; return 1; } # Convert the retrieved values to lookup hash foreach my $oid ( keys %$resp ) { if(( $oid =~ /\.101\.\d+$/ ) and ( $resp->{$oid}=~/^(\S+)=(.*)$/)) { $stats{$1}=$2; } } return ""; } sub readxcpu { my($k,$C); $MSG = ""; $A = 0; $B = 0; $STATUS = 0; if( readagent ) { print "(readagent failed: $MSG)\n" if($DEBUG); readcpu if(!$MSG); # no vmware agent, no error return; } if($vhost) { $k = "vhost-$VMID"; $A = $stats{"$k-cpu-used-pc"}; $B = $stats{"$k-cpu-ready-pc"}; $C = $A; } else { $k = "sys"; $A = $stats{"sys-cpu-used-pc"}; $B = $stats{"allvms-cpu-used-pc"}; $C = $A + $B if(defined $A and defined $B); } if(!defined $A or !defined $B) { $A=$B='U'; $MSG="Gathering statistics, please wait."; $STATUS = 3; dooutput; exit 3; } if($vhost) { $MSG = "vhost CPU used=$A% ready=$B%"; } else { $MSG = "CPU used sys=$A% vhosts=$B% readytime=" .$stats{'sys-cpu-ready-pc'}."%"; } # MRTG only if($MODE) { dooutput; exit 0; } # Nagios only if( $C >= $crit ) { $MSG .= "
" if($MSG); $MSG .= "CPU usage is CRITICAL ($C%)"; $STATUS = 2; } elsif( $C >= $warn ) { $MSG .= "
" if($MSG); $MSG .= "CPU usage is WARNING ($C%)"; $STATUS = 1 if($STATUS<2); } # Ready time if( $stats{"$k-cpu-ready-pc"} >= $rcrit ) { $MSG .= "
" if($MSG); $MSG .= "Ready time is CRITICAL (".$stats{"$k-cpu-ready-pc"}."%)"; $STATUS = 2; } elsif( $stats{"$k-cpu-ready-pc"} >= $rwarn ) { $MSG .= "
" if($MSG); $MSG .= "Ready time is WARNING (".$stats{"$k-cpu-ready-pc"}."%)"; $STATUS = 1 if($STATUS<2); } if(!$vhost) { # check all vhosts foreach ( keys %lookup ) { next if(!defined $stats{"vhost-$_-cpu-used-pc"}); $C=$stats{"vhost-$_-cpu-used-pc"}; if( $C >= $crit ) { $MSG .= "
" if($MSG); $MSG .= "CPU usage for '".base($lookup{$_})."' is CRITICAL ($C%)"; $STATUS = 2; } elsif( $C >= $warn ) { $MSG .= "
" if($MSG); $MSG .= "CPU usage for '".base($lookup{$_})."' is WARNING ($C%)"; $STATUS = 1 if($STATUS<2); } if( $stats{"vhost-$_-cpu-ready-pc"} >= $rcrit ) { $MSG .= "
" if($MSG); $MSG .= "Ready time for '".base($lookup{$_})."' is CRITICAL (".$stats{"vhost-$_-cpu-ready-pc"}."%)"; $STATUS = 2; } elsif( $stats{"vhost-$_-cpu-ready-pc"} >= $rwarn ) { $MSG .= "
" if($MSG); $MSG .= "Ready time for '".base($lookup{$_})."' is WARNING (".$stats{"vhost-$_-cpu-ready-pc"}."%)"; $STATUS = 1 if($STATUS<2); } } } dooutput; exit 3; # not reached } sub readxmem { my($pc,$max); $MSG = ""; $A = 0; $B = 0; if( readagent() ) { print "(readagent failed: $MSG)\n" if($DEBUG); readmem if(!$MSG); # no vmware agent, no error return; } if( $vhost ) { $A = $stats{"vhost-$VMID-mem-active"}; $B = $stats{"vhost-$VMID-mem-max"}; if(!defined $A or !defined $B) { $A=$B='U'; $MSG="Please wait, data being gathered."; $STATUS=3; dooutput; exit 0; } $pc = int($A/$B*10000)/100.0; $MSG = "Memory active: ".int($A/1024000)."Mb ($pc%) [Total available ".int($B/1024000)."Mb]"; $max = $stats{"vhost-$VMID-mem-max"}; $k = "vhost-$VMID"; if($pc>=$crit) { $STATUS=2; $MSG = "CRIT: $MSG"; } elsif($pc>=$warn) { $STATUS=1; $MSG = "WARN: $MSG"; } } else { $A = $stats{'mem-free'}; $B = $stats{'mem-total'}; if(!defined $A or !defined $B) { $A=$B='U'; $MSG="Please wait, data being gathered."; $STATUS=3; dooutput; exit 0; } $pc = int($A/$B*10000)/100.0; $MSG = "Memory free: ".int($A/1024000)."Mb ($pc%) [Total available ".int($B/1024000)."Mb]"; $max = $stats{'allvms-mem-max'}; $k = "allvms"; if($pc<=$crit) { $STATUS=2; $MSG = "CRIT: $MSG"; } elsif($pc<=$warn) { $STATUS=1; $MSG = "WARN: $MSG"; } } # MRTG if($MODE) { dooutput; exit 0; } # Nagios if($max) { $MSG .= "
Memory split: pvt/shr/bal/swp = " .(int(10000*$stats{"$k-mem-private"}/$max)/100.0)."%/" .(int(10000*$stats{"$k-mem-shared"}/$max)/100.0)."%/" .(int(10000*$stats{"$k-mem-balloon"}/$max)/100.0)."%/" .(int(10000*$stats{"$k-mem-swap"}/$max)/100.0)."%"; if($stats{"$k-mem-balloon"}) { $pc = int(100000*$stats{"$k-mem-balloon"}/$max)/1000.0; if($pc>5) { $MSG .= "
CRIT: Balloon drivers in action! ($pc%)"; $STATUS = 2; } else { $MSG .= "
WARN: Balloon drivers in action! ($pc%)"; $STATUS = 1 if($STATUS<2); } } } if($stats{"$k-swap-in-bps"} and $stats{"$k-swap-in-bps"}>0) { $MSG .= "
CRIT: VMware swapping in action! (".$stats{"$k-swap-in-bps"}."Bps)"; $STATUS = 2; } elsif($max and $stats{"$k-mem-swap"}) { $pc = int(100000*$stats{"$k-mem-swap"}/$max)/1000.0; if($pc>=5) { $MSG .= "
CRIT: VMWare swap space in use! ($pc%)"; $STATUS = 2; } else { $MSG .= "
WARN: VMWare swap space in use! ($pc%)"; $STATUS = 1 if($STATUS<2); } } dooutput; exit 3; # not reached } ########################################################################### getopts('hrdNMH:c:t:v:w:C:l:i:'); $hostname = $opt_H if($opt_H); $vhost = $opt_v if($opt_v); $warn = $opt_w if($opt_w); $crit = $opt_c if($opt_c); $TIMEOUT = $opt_t if($opt_t); $MODE = 1 if($opt_M); $community = $opt_C if($opt_C); $DEBUG = 1 if($opt_d); dohelp if($opt_h); if(!$hostname) { $MSG = "No ESX server hostname specified with -H"; dooutput; exit 0; } if( !$opt_l ) { # $MSG = "You need to specify a command with -l"; # dooutput; # exit 0; $opt_l = "LIST"; } if( $opt_l =~ /LISTNET/i ) { getvmid; $MSG = ""; readnet; if(!$MSG) { foreach ( keys %tmpnet ) { if(!$opt_v or ($opt_v eq $lookup{$tmpnet{$_}[0]})) { $MSG .= $lookup{$tmpnet{$_}[0]}."/" if(!$opt_v); $MSG .= $tmpnet{$_}[1]." "; } } $STATUS = $OK; } dooutput; exit 0; } if( $opt_l =~ /LIST/i ) { listvm; if($warn =~ /(\d+)%/) { $warn = $B * $1 / 100; } elsif( $warn < 0 ) { $warn = $B - 1; } if($crit =~ /(\d+)%/) { $crit = $B * $1 / 100; } elsif( $crit < 0 ) { $crit = 0; } $STATUS = $WARNING if($A<=$warn); # If SOME are down $STATUS = $CRITICAL if($A<=$crit); # If NONE are up $STATUS = $OK if(!$B); # No guests at all dooutput; exit 3; } if( $opt_l !~ /NET|CPU|MEM|STAT/i ) { $MSG = "Bad command $opt_l!"; dooutput; exit 3; } if( $opt_l =~ /MEM|CPU|NET/ and !$MODE and ($crit<0 or $warn<0)) { $MSG = "Invalid warn/critical thresholds for '$opt_l' (need -w and -c)"; dooutput; exit 3; } # Now, we have host, vhost, community, and command getvmid; # also opens SNMP object if( $opt_l =~ /STAT/i ) { if(!$vhost) { $MSG = "No virtual hostname specified with -v"; dooutput; exit 0; } if( $VMID < 0 ) { $STATUS = $CRITICAL; ($A,$B) = (0,0); } else { $STATUS = $OK; ($A,$B) = (1,1); $MSG = "VHost $vhost is up (ID: $VMID)"; } dooutput; exit 0; } if($vhost and ( $VMID < 0 )) { $STATUS = $CRITICAL; $MSG = "$vhost is not running." if(!$MSG); dooutput; exit 0; } $STATUS = $OK; if( $opt_l =~ /CPU/i ) { $MSG = ""; readxcpu; # attempt to use extended MIB, else use VMWare MIB } elsif( $opt_l =~ /NET/i ) { my($t1,$t2,$a1,$b1); if( !$MODE or $opt_r ) { readstate; $t1 = $states{"$hostname-NET-$vhost-$opt_i-time"}; $a1 = $states{"$hostname-NET-$vhost-$opt_i-r"}; $b1 = $states{"$hostname-NET-$vhost-$opt_i-w"}; $t2 = time; } $MSG = ""; readnet; if(!$MSG){ # IE, no errors $MSG = "Network counters Read=$A Write=$B"; $MSG .= " on $vhost" if($vhost); if( $opt_i ) { if( $vhost ) { $MSG .= '/'; } else { $MSG .= ' on '; } $MSG .= $opt_i; } if( !$MODE or $opt_r ) { writestate( "$hostname-NET-$vhost-$opt_i-r"=>$A, "$hostname-NET-$vhost-$opt_i-w"=>$B, "$hostname-NET-$vhost-$opt_i-time"=>$t2 ) if(!$t1 or ($t2-$t1)>30); if(!$t1 or (!$a1 and !$b1) or ($t1 >= $t2) or (($t2 - $t1)>3600)) { $MSG = "No saved state available yet - wait for next poll."; $A = $B = "U"; $STATUS = $UNKNOWN; } else { $A = ($A - $a1)/($t2 - $t1); $B = ($B - $b1)/($t2 - $t1); ($fa,$sa,$fb,$sb) = ( $A, "", $B, "" ); if($fa >= 1024000) { $fa /= 1024000; $sa = 'M'; } elsif($fa >= 1024) { $fa /= 1024; $sa = 'K'; } if($fb >= 1024000) { $fb /= 1024000; $sb = 'M'; } elsif($fb >= 1024) { $fb /= 1024; $sb = 'K'; } $fa = int($fa * 100)/100; $fb = int($fb * 100)/100; $MSG = "Network traffic $fa ".$sa."B/s read, $fb ".$sb."B/s write "; $MSG .= "on $vhost" if($vhost); if( $opt_i ) { if( $vhost ) { $MSG .= '/'; } else { $MSG .= 'on '; } $MSG .= $opt_i; } $MSG .= " (".($t2-$t1)."s average)"; } } } } elsif( $opt_l =~ /MEM/i ) { my($pc,$tot,$av,$sfx); $MSG = ""; readxmem; if(!$MSG) { $pc = int($A/$B*10000.0)/100.0; $sfx = "Kb"; $av = $A; if($av>2047) { $av = int($av/10.24)/100.0; $sfx="Mb"; } $av .= $sfx; $sfx = "Kb"; $tot = $B; if($tot>2047) { $tot = int($tot/10.24)/100.0; $sfx="Mb"; } $tot .= $sfx; $MSG = "Memory free: $av ($pc%) [Total available $tot]" ; $MSG .= " on vhost $vhost" if($vhost); } } else { $MSG = "Invalid command $opt_l"; $STATUS = $UNKNOWN; } if( !$MODE and $STATUS==$OK ) { # Set Nagios thresholds if( $opt_l=~/MEM/i and $warn =~ /([\d\.]+)%/ ) { $warn = $B * $1 / 100.0; } elsif( $warn =~ /([\d\.]+)M/i ) { $warn = $1 * 1024; } elsif( $warn =~ /([\d\.]+)/i ) { $warn = $1; } if( $opt_l=~/MEM/i and $crit =~ /([\d\.]+)%/ ) { $crit = $B * $1 / 100.0; } elsif( $crit =~ /([\d\.]+)M/i ) { $crit = $1 * 1024; } elsif( $crit =~ /([\d\.]+)/i ) { $crit = $1; } if( $opt_l =~ /MEM/i ) { $STATUS = $WARNING if( $A <= $warn ); $STATUS = $CRITICAL if( $A <= $crit ); } elsif( $opt_l =~ /CPU/i ) { $STATUS = $WARNING if( ($A+$B) >= $warn ); $STATUS = $CRITICAL if( ($A+$B) >= $crit ); } elsif( $opt_l =~ /NET/i ) { $STATUS = $WARNING if( $A >= $warn ); $STATUS = $WARNING if( $B >= $warn ); $STATUS = $CRITICAL if( $A >= $crit ); $STATUS = $CRITICAL if( $B >= $crit ); } else { $STATUS = $WARNING if( $A <= $warn ); $STATUS = $CRITICAL if( $A <= $crit ); } } $snmp->close; dooutput; exit 0;