commit c49bbdd106c0de1031201cb5f851db0c641fab10 Author: Thomas Constans Date: Fri Jun 23 12:12:11 2023 +0200 initial commit diff --git a/check_snmp_load.pl b/check_snmp_load.pl new file mode 100755 index 0000000..2a596ce --- /dev/null +++ b/check_snmp_load.pl @@ -0,0 +1,713 @@ +#!/usr/bin/perl -w +############################## check_snmp_load ################# +my $Version='1.12'; +# Date : Oct 12 2007 +# Author : Patrick Proy ( patrick at proy.org) +# Help : http://nagios.manubulon.com/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Contributors : F. Lacroix and many others !!! +################################################################# +# +# Help : ./check_snmp_load.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +my $TIMEOUT = 15; +my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +# Generic with host-ressource-mib +my $base_proc = "1.3.6.1.2.1.25.3.3.1"; # oid for all proc info +my $proc_id = "1.3.6.1.2.1.25.3.3.1.1"; # list of processors (product ID) +my $proc_load = "1.3.6.1.2.1.25.3.3.1.2"; # %time the proc was not idle over last minute + +# Linux load + +my $linload_table= "1.3.6.1.4.1.2021.10.1"; # net-snmp load table +my $linload_name = "1.3.6.1.4.1.2021.10.1.2"; # text 'Load-1','Load-5', 'Load-15' +my $linload_load = "1.3.6.1.4.1.2021.10.1.3"; # effective load table + +# Cisco cpu/load + +my $cisco_cpu_5m = "1.3.6.1.4.1.9.2.1.58.0"; # Cisco CPU load (5min %) +my $cisco_cpu_1m = "1.3.6.1.4.1.9.2.1.57.0"; # Cisco CPU load (1min %) +my $cisco_cpu_5s = "1.3.6.1.4.1.9.2.1.56.0"; # Cisco CPU load (5sec %) + +# Cisco catalyst cpu/load + +my $ciscocata_cpu_5m = ".1.3.6.1.4.1.9.9.109.1.1.1.1.5.9"; # Cisco CPU load (5min %) +my $ciscocata_cpu_1m = ".1.3.6.1.4.1.9.9.109.1.1.1.1.3.9"; # Cisco CPU load (1min %) +my $ciscocata_cpu_5s = ".1.3.6.1.4.1.9.9.109.1.1.1.1.4.9"; # Cisco CPU load (5sec %) + +# Netscreen cpu/load + +my $nsc_cpu_5m = "1.3.6.1.4.1.3224.16.1.4.0"; # NS CPU load (5min %) +my $nsc_cpu_1m = "1.3.6.1.4.1.3224.16.1.2.0"; # NS CPU load (1min %) +my $nsc_cpu_5s = "1.3.6.1.4.1.3224.16.1.3.0"; # NS CPU load (5sec %) + +# AS/400 CPU + +my $as400_cpu = "1.3.6.1.4.1.2.6.4.5.1.0"; # AS400 CPU load (10000=100%); + +# Net-SNMP CPU + +my $ns_cpu_idle = "1.3.6.1.4.1.2021.11.11.0"; # Net-snmp cpu idle +my $ns_cpu_user = "1.3.6.1.4.1.2021.11.9.0"; # Net-snmp user cpu usage +my $ns_cpu_system = "1.3.6.1.4.1.2021.11.10.0"; # Net-snmp system cpu usage + +# Procurve CPU +my $procurve_cpu = "1.3.6.1.4.1.11.2.14.11.5.1.9.6.1.0"; # Procurve CPU Counter + +# Nokia CPU +my $nokia_cpu = "1.3.6.1.4.1.94.1.21.1.7.1.0"; # Nokia CPU % usage + +# Bluecoat Appliance +my $bluecoat_cpu = "1.3.6.1.4.1.3417.2.4.1.1.1.4.1"; # Bluecoat %cpu usage. + +# Fortigate CPU +my $fortigate_cpu = ".1.3.6.1.4.1.12356.1.8.0"; # Fortigate CPU % usage + +# Linkproof Appliance +my $linkproof_cpu= "1.3.6.1.4.1.89.35.1.55.0"; # CPU RE (Routing Engine Tasks) +# 1.3.6.1.4.1.89.35.1.53.0 : Ressource utilisation (%) Considers network utilization and internal CPU utilization +# 1.3.6.1.4.1.89.35.1.54 : CPU only (%) +# 1.3.6.1.4.1.89.35.1.55 : network only (%) + +# HP-UX cpu usage (thanks to krizb for the OIDs). +my $hpux_load_1_min="1.3.6.1.4.1.11.2.3.1.1.3.0"; +my $hpux_load_5_min="1.3.6.1.4.1.11.2.3.1.1.4.0"; +my $hpux_load_15_min="1.3.6.1.4.1.11.2.3.1.1.5.0"; + +# valid values +my @valid_types = ("stand","netsc","netsl","as400","cisco","cata","nsc","fg","bc","nokia","hp","lp","hpux"); +# CPU OID array +my %cpu_oid = ("netsc",$ns_cpu_idle,"as400",$as400_cpu,"bc",$bluecoat_cpu,"nokia",$nokia_cpu,"hp",$procurve_cpu,"lp",$linkproof_cpu,"fg",$fortigate_cpu); + +# Globals + + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +# check type : stand | netsc | netsl | as400 | cisco | cata | nsc | fg | bc | nokia | hp | lp | hpux +my $o_check_type= "stand"; +# End compatibility +my $o_warn= undef; # warning level +my @o_warnL= undef; # warning levels for Linux Load or Cisco CPU +my $o_crit= undef; # critical level +my @o_critL= undef; # critical level for Linux Load or Cisco CPU +my $o_timeout= undef; # Timeout (Default 5) +my $o_perf= undef; # Output performance data +my $o_version2= undef; # use snmp v2c +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_load version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] -w -c -T=[stand|netsl|netsc|as400|cisco|cata|nsc|fg|bc|nokia|hp|lp|hpux] [-f] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub help { + print "\nSNMP Load & CPU Monitor for Nagios version ",$Version,"\n"; + print "GPL licence, (c)2004-2007 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-w, --warn=INTEGER | INT,INT,INT + 1 value check : warning level for cpu in percent (on one minute) + 3 value check : comma separated level for load or cpu for 1min, 5min, 15min +-c, --crit=INTEGER | INT,INT,INT + critical level for cpu in percent (on one minute) + 1 value check : critical level for cpu in percent (on one minute) + 3 value check : comma separated level for load or cpu for 1min, 5min, 15min +-T, --type=stand|netsl|netsc|as400|cisco|bc|nokia|hp|lp + CPU check : + stand : standard MIBII (works with Windows), + can handle multiple CPU. + netsl : linux load provided by Net SNMP (1,5 & 15 minutes values) + netsc : cpu usage given by net-snmp (100-idle) + as400 : as400 CPU usage + cisco : Cisco CPU usage + cata : Cisco catalyst CPU usage + nsc : NetScreen CPU usage + fg : Fortigate CPU usage + bc : Bluecoat CPU usage + nokia : Nokia CPU usage + hp : HP procurve switch CPU usage + lp : Linkproof CPU usage + hpux : HP-UX load (1,5 & 15 minutes values) +-f, --perfparse + Perfparse compatible output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'c:s' => \$o_crit, 'critical:s' => \$o_crit, + 'w:s' => \$o_warn, 'warn:s' => \$o_warn, + 'f' => \$o_perf, 'perfparse' => \$o_perf, + 'T:s' => \$o_check_type, 'type:s' => \$o_check_type + ); + # check the -T option + my $T_option_valid=0; + foreach (@valid_types) { if ($_ eq $o_check_type) {$T_option_valid=1} }; + if ( $T_option_valid == 0 ) + {print "Invalid check type (-T)!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Basic checks + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + # Check warnings and critical + if (!defined($o_warn) || !defined($o_crit)) + { print "put warning and critical info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Get rid of % sign + $o_warn =~ s/\%//g; + $o_crit =~ s/\%//g; + # Check for multiple warning and crit in case of -L + if (($o_check_type eq "netsl") || ($o_check_type eq "cisco") || ($o_check_type eq "cata") || + ($o_check_type eq "nsc") || ($o_check_type eq "hpux")) { + @o_warnL=split(/,/ , $o_warn); + @o_critL=split(/,/ , $o_crit); + if (($#o_warnL != 2) || ($#o_critL != 2)) + { print "3 warnings and critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + for (my $i=0;$i<3;$i++) { + if ( isnnum($o_warnL[$i]) || isnnum($o_critL[$i])) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_warnL[$i] > $o_critL[$i]) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + } else { + if (($o_warn =~ /,/) || ($o_crit =~ /,/)) { + { print "Multiple warning/critical levels not available for this check\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if ( isnnum($o_warn) || isnnum($o_crit) ) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ($o_warn > $o_crit) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT + 5"); + alarm($TIMEOUT+5); +} else { + verb("no global timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +$SIG{'ALRM'} = sub { + print "No answer from host\n"; + exit $ERRORS{"UNKNOWN"}; +}; + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + verb("SNMPv3 login"); + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +my $exit_val=undef; +########### Linux load check ############## + +if ($o_check_type eq "netsl") { + +verb("Checking linux load"); +# Get load table +my $resultat = $session->get_table(Baseoid => $linload_table); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +my @load = undef; +my @iload = undef; +my @oid=undef; +my $exist=0; +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$linload_name/ ) { + @oid=split (/\./,$key); + $iload[0]= pop(@oid) if ($$resultat{$key} eq "Load-1"); + $iload[1]= pop(@oid) if ($$resultat{$key} eq "Load-5"); + $iload[2]= pop(@oid) if ($$resultat{$key} eq "Load-15"); + $exist=1 + } +} + +if ($exist == 0) { + print "Can't find snmp information on load : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +for (my $i=0;$i<3;$i++) { $load[$i] = $$resultat{$linload_load . "." . $iload[$i]}}; + +print "Load : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_1_min=$load[0];$o_warnL[0];$o_critL[0] "; + print "load_5_min=$load[1];$o_warnL[1];$o_critL[1] "; + print "load_15_min=$load[2];$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} +exit $exit_val; +} + +############## Cisco CPU check ################ + +if ($o_check_type eq "cisco") { +my @oidlists = ($cisco_cpu_5m, $cisco_cpu_1m, $cisco_cpu_5s); +my $resultat = $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$cisco_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$cisco_cpu_5s}; +$load[1]=$$resultat{$cisco_cpu_1m}; +$load[2]=$$resultat{$cisco_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_5_sec=$load[0]%;$o_warnL[0];$o_critL[0] "; + print "load_1_min=$load[1]%;$o_warnL[1];$o_critL[1] "; + print "load_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +############## Cisco Catalyst CPU check ################ + +if ($o_check_type eq "cata") { +my @oidlists = ($ciscocata_cpu_5m, $ciscocata_cpu_1m, $ciscocata_cpu_5s); +my $resultat = $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$ciscocata_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$ciscocata_cpu_5s}; +$load[1]=$$resultat{$ciscocata_cpu_1m}; +$load[2]=$$resultat{$ciscocata_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_5_sec=$load[0]%;$o_warnL[0];$o_critL[0] "; + print "load_1_min=$load[1]%;$o_warnL[1];$o_critL[1] "; + print "load_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +############## Netscreen CPU check ################ + +if ($o_check_type eq "nsc") { +my @oidlists = ($nsc_cpu_5m, $nsc_cpu_1m, $nsc_cpu_5s); +my $resultat = $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$nsc_cpu_5s})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$nsc_cpu_5s}; +$load[1]=$$resultat{$nsc_cpu_1m}; +$load[2]=$$resultat{$nsc_cpu_5m}; + +print "CPU : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | cpu_5_sec=$load[0]%;$o_warnL[0];$o_critL[0] "; + print "cpu_1_min=$load[1]%;$o_warnL[1];$o_critL[1] "; + print "cpu_5_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +################## CPU for : AS/400 , Netsnmp, HP, Bluecoat, linkproof, fortigate ########### +if ( $o_check_type =~ /netsc|as400|bc|nokia|^hp$|lp|fg/ ) { + +# Get load table +my @oidlist = $cpu_oid{$o_check_type}; +verb("Checking OID : @oidlist"); +my $resultat = $session->get_request(-varbindlist => \@oidlist); +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} +$session->close; + +if (!defined ($$resultat{$cpu_oid{$o_check_type}})) { + print "No CPU information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my $load=$$resultat{$cpu_oid{$o_check_type}}; +verb("OID returned $load"); +# for AS400, divide by 100 +if ($o_check_type eq "as400") {$load /= 100; }; +# for Net-snmp : oid returned idle time so load = 100-idle. +if ($o_check_type eq "netsc") {$load = 100 - $load; }; + +printf("CPU used %.1f%% (",$load); + +$exit_val=$ERRORS{"OK"}; +if ($load > $o_crit) { + print ">$o_crit) : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; +} else { + if ($load > $o_warn) { + print ">$o_warn) : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } +} +print "<$o_warn) : OK" if ($exit_val eq $ERRORS{"OK"}); +(defined($o_perf)) ? + print " | cpu_prct_used=$load%;$o_warn;$o_crit\n" + : print "\n"; +exit $exit_val; + +} + +##### Checking hpux load +if ($o_check_type eq "hpux") { + +verb("Checking hpux load"); + +my @oidlists = ($hpux_load_1_min, $hpux_load_5_min, $hpux_load_15_min); +my $resultat = $session->get_request(-varbindlist => \@oidlists); + +if (!defined($resultat)) { + printf("ERROR: Load table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +if (!defined ($$resultat{$hpux_load_1_min})) { + print "No Load information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +my @load = undef; + +$load[0]=$$resultat{$hpux_load_1_min}/100; +$load[1]=$$resultat{$hpux_load_5_min}/100; +$load[2]=$$resultat{$hpux_load_15_min}/100; + +print "Load : $load[0] $load[1] $load[2] :"; + +$exit_val=$ERRORS{"OK"}; +for (my $i=0;$i<3;$i++) { + if ( $load[$i] > $o_critL[$i] ) { + print " $load[$i] > $o_critL[$i] : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; + } + if ( $load[$i] > $o_warnL[$i] ) { + # output warn error only if no critical was found + if ($exit_val eq $ERRORS{"OK"}) { + print " $load[$i] > $o_warnL[$i] : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } + } +} +print " OK" if ($exit_val eq $ERRORS{"OK"}); +if (defined($o_perf)) { + print " | load_1_min=$load[0]%;$o_warnL[0];$o_critL[0] "; + print "load_5_min=$load[1]%;$o_warnL[1];$o_critL[1] "; + print "load_15_min=$load[2]%;$o_warnL[2];$o_critL[2]\n"; +} else { + print "\n"; +} + +exit $exit_val; +} + +########## Standard cpu usage check ############ +# Get desctiption table + my $resultat= $session->get_table(Baseoid => $base_proc); + +if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; +} + +$session->close; + +my ($cpu_used,$ncpu)=(0,0); +foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$proc_load/) { + $cpu_used += $$resultat{$key}; + $ncpu++; + } +} + +if ($ncpu==0) { + print "Can't find CPU usage information : UNKNOWN\n"; + exit $ERRORS{"UNKNOWN"}; +} + +$cpu_used /= $ncpu; + +print "$ncpu CPU, ", $ncpu==1 ? "load" : "average load"; +printf(" %.1f%%",$cpu_used); +$exit_val=$ERRORS{"OK"}; + +if ($cpu_used > $o_crit) { + print " > $o_crit% : CRITICAL"; + $exit_val=$ERRORS{"CRITICAL"}; +} else { + if ($cpu_used > $o_warn) { + print " > $o_warn% : WARNING"; + $exit_val=$ERRORS{"WARNING"}; + } +} +print " < $o_warn% : OK" if ($exit_val eq $ERRORS{"OK"}); +(defined($o_perf)) ? + print " | cpu_prct_used=$cpu_used%;$o_warn;$o_crit\n" + : print "\n"; +exit $exit_val; + diff --git a/check_snmp_mem.pl b/check_snmp_mem.pl new file mode 100755 index 0000000..ef470ad --- /dev/null +++ b/check_snmp_mem.pl @@ -0,0 +1,519 @@ +#!/usr/bin/perl -w +############################## check_snmp_mem ############## +# Version : 1.1 +# Date : Jul 09 2006 +# Author : Patrick Proy (nagios at proy.org) +# Help : http://www.manubulon.com/nagios/ +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Contrib : Jan Jungmann +# TODO : +################################################################# +# +# Help : ./check_snmp_mem.pl -h +# + +use strict; +use Net::SNMP; +use Getopt::Long; + +# Nagios specific + +use lib "/usr/lib64/nagios/plugins"; +use utils qw(%ERRORS $TIMEOUT); +#my $TIMEOUT = 15; +#my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas + +# Net-snmp memory + +my $nets_ram_free = "1.3.6.1.4.1.2021.4.6.0"; # Real memory free +my $nets_ram_total = "1.3.6.1.4.1.2021.4.5.0"; # Real memory total +my $nets_ram_cache = "1.3.6.1.4.1.2021.4.15.0"; # Real memory cached +my $nets_swap_free = "1.3.6.1.4.1.2021.4.4.0"; # swap memory free +my $nets_swap_total = "1.3.6.1.4.1.2021.4.3.0"; # Swap memory total +my @nets_oids = ($nets_ram_free,$nets_ram_total,$nets_swap_free,$nets_swap_total,$nets_ram_cache); + +# Cisco + +my $cisco_mem_pool = "1.3.6.1.4.1.9.9.48.1.1.1"; # Cisco memory pool +my $cisco_index = "1.3.6.1.4.1.9.9.48.1.1.1.2"; # memory pool name and index +my $cisco_valid = "1.3.6.1.4.1.9.9.48.1.1.1.4"; # Valid memory if 1 +my $cisco_used = "1.3.6.1.4.1.9.9.48.1.1.1.5"; # Used memory +my $cisco_free = "1.3.6.1.4.1.9.9.48.1.1.1.6"; # Free memory +# .1 : type, .2 : name, .3 : alternate, .4 : valid, .5 : used, .6 : free, .7 : max free + +# HP Procurve + +my $hp_mem_pool = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1"; # HP memory pool +my $hp_mem_index = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.1"; # memory slot index +my $hp_mem_total = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.5"; # Total Bytes +my $hp_mem_free = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.6"; # Free Bytes +my $hp_mem_free_seg = "1.3.6.1.4.1.11.2.14.11.5.1.1.2.2.1.1.3"; # Free segments + +# AS/400 + +# Windows NT/2K/(XP?) + +# check_snmp_storage.pl -C -H -m "^Virtual Memory$" -w -c + + +# Globals + +my $Version='1.1'; + +my $o_host = undef; # hostname +my $o_community = undef; # community +my $o_port = 161; # port +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_netsnmp= 1; # Check with netsnmp (default) +my $o_cisco= undef; # Check cisco router mem +my $o_hp= undef; # Check hp procurve mem +my $o_warn= undef; # warning level option +my $o_warnR= undef; # warning level for Real memory +my $o_warnS= undef; # warning levels for swap +my $o_crit= undef; # Critical level option +my $o_critR= undef; # critical level for Real memory +my $o_critS= undef; # critical level for swap +my $o_perf= undef; # Performance data option +my $o_cache= undef; # Include cached memory as used memory +my $o_timeout= undef; # Timeout (Default 5) +my $o_version2= undef; # use snmp v2c +# SNMPv3 specific +my $o_login= undef; # Login for snmpv3 +my $o_passwd= undef; # Pass for snmpv3 +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password + +# functions + +sub p_version { print "check_snmp_mem version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd [-X pass -L ,]) [-p ] -w -c [-I|-N|-E] [-f] [-m] [-t ] [-V]\n"; +} + +sub isnnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +sub round ($$) { + sprintf "%.$_[1]f", $_[0]; +} + +sub help { + print "\nSNMP Memory Monitor for Nagios version ",$Version,"\n"; + print "(c)2004-2006 to my cat Ratoune - Author: Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-P, --port=PORT + SNMP port (Default 161) +-w, --warn=INTEGER | INT,INT + warning level for memory in percent (0 for no checks) + Default (-N switch) : comma separated level for Real Memory and Swap + -I switch : warning level +-c, --crit=INTEGER | INT,INT + critical level for memory in percent (0 for no checks) + Default (-N switch) : comma separated level for Real Memory and Swap + -I switch : critical level +-N, --netsnmp (default) + check linux memory & swap provided by Net SNMP +-m, --memcache + include cached memory in used memory (only with Net-SNMP) +-I, --cisco + check cisco memory (sum of all memory pools) +-E, --hp + check HP proccurve memory +-f, --perfdata + Performance data output +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +EOT +} + +# For verbose output +sub verb { my $t=shift; print $t,"\n" if defined($o_verb) ; } + +# Get the alarm signal (just in case snmp timout screws up) +$SIG{'ALRM'} = sub { + print ("ERROR: Alarm signal (Nagios time-out)\n"); + exit $ERRORS{"UNKNOWN"}; +}; + +sub check_options { + Getopt::Long::Configure ("bundling"); + GetOptions( + 'v' => \$o_verb, 'verbose' => \$o_verb, + 'h' => \$o_help, 'help' => \$o_help, + 'H:s' => \$o_host, 'hostname:s' => \$o_host, + 'p:i' => \$o_port, 'port:i' => \$o_port, + 'C:s' => \$o_community, 'community:s' => \$o_community, + 'l:s' => \$o_login, 'login:s' => \$o_login, + 'x:s' => \$o_passwd, 'passwd:s' => \$o_passwd, + 'X:s' => \$o_privpass, 'privpass:s' => \$o_privpass, + 'L:s' => \$v3protocols, 'protocols:s' => \$v3protocols, + 't:i' => \$o_timeout, 'timeout:i' => \$o_timeout, + 'V' => \$o_version, 'version' => \$o_version, + 'I' => \$o_cisco, 'cisco' => \$o_cisco, + 'N' => \$o_netsnmp, 'netsnmp' => \$o_netsnmp, + 'E' => \$o_hp, 'hp' => \$o_hp, + '2' => \$o_version2, 'v2c' => \$o_version2, + 'c:s' => \$o_crit, 'critical:s' => \$o_crit, + 'w:s' => \$o_warn, 'warn:s' => \$o_warn, + 'm' => \$o_cache, 'memcache' => \$o_cache, + 'f' => \$o_perf, 'perfdata' => \$o_perf + ); + if (defined ($o_help) ) { help(); exit $ERRORS{"UNKNOWN"}}; + if (defined($o_version)) { p_version(); exit $ERRORS{"UNKNOWN"}}; + if ( ! defined($o_host) ) # check host and filter + { print "No host defined!\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + # check snmp information + if ( !defined($o_community) && (!defined($o_login) || !defined($o_passwd)) ) + { print "Put snmp login info!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if ((defined($o_login) || defined($o_passwd)) && (defined($o_community) || defined($o_version2)) ) + { print "Can't mix snmp v1,2c,3 protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (defined ($v3protocols)) { + if (!defined($o_login)) { print "Put snmp V3 login info with protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + my @v3proto=split(/,/,$v3protocols); + if ((defined ($v3proto[0])) && ($v3proto[0] ne "")) {$o_authproto=$v3proto[0]; } # Auth protocol + if (defined ($v3proto[1])) {$o_privproto=$v3proto[1]; } # Priv protocol + if ((defined ($v3proto[1])) && (!defined($o_privpass))) { + print "Put snmp V3 priv login info with priv protocols!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_timeout) && (isnnum($o_timeout) || ($o_timeout < 2) || ($o_timeout > 60))) + { print "Timeout must be >1 and <60 !\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + if (!defined($o_timeout)) {$o_timeout=5;} + #Check Warning and crit are present + if ( ! defined($o_warn) || ! defined($o_crit)) + { print "Put warning and critical values!\n"; print_usage(); exit $ERRORS{"UNKNOWN"}} + # Get rid of % sign + $o_warn =~ s/\%//g; + $o_crit =~ s/\%//g; + # if -N or -E switch , undef $o_netsnmp + if (defined($o_cisco) || defined($o_hp) ) { + $o_netsnmp=undef; + if ( isnnum($o_warn) || isnnum($o_crit)) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"} } + if ( ($o_crit != 0) && ($o_warn > $o_crit) ) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + if (defined($o_netsnmp)) { + my @o_warnL=split(/,/ , $o_warn); + my @o_critL=split(/,/ , $o_crit); + if (($#o_warnL != 1) || ($#o_critL != 1)) + { print "2 warnings and critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + for (my $i=0;$i<2;$i++) { + if ( isnnum($o_warnL[$i]) || isnnum($o_critL[$i])) + { print "Numeric value for warning or critical !\n";print_usage(); exit $ERRORS{"UNKNOWN"} } + if (($o_critL[$i]!= 0) && ($o_warnL[$i] > $o_critL[$i])) + { print "warning <= critical ! \n";print_usage(); exit $ERRORS{"UNKNOWN"}} + if ( $o_critL[$i] > 100) + { print "critical percent must be < 100 !\n";print_usage(); exit $ERRORS{"UNKNOWN"}} + } + $o_warnR=$o_warnL[0];$o_warnS=$o_warnL[1]; + $o_critR=$o_critL[0];$o_critS=$o_critL[1]; + } + +} + +########## MAIN ####### + +check_options(); + +# Check gobal timeout if snmp screws up +if (defined($TIMEOUT)) { + verb("Alarm at $TIMEOUT"); + alarm($TIMEOUT); +} else { + verb("no timeout defined : $o_timeout + 10"); + alarm ($o_timeout+10); +} + +# Connect to host +my ($session,$error); +if ( defined($o_login) && defined($o_passwd)) { + # SNMPv3 login + if (!defined ($o_privpass)) { + verb("SNMPv3 AuthNoPriv login : $o_login, $o_authproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -timeout => $o_timeout + ); + } else { + verb("SNMPv3 AuthPriv login : $o_login, $o_authproto, $o_privproto"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => '3', + -username => $o_login, + -authpassword => $o_passwd, + -authprotocol => $o_authproto, + -privpassword => $o_privpass, + -privprotocol => $o_privproto, + -timeout => $o_timeout + ); + } +} else { + if (defined ($o_version2)) { + # SNMPv2 Login + verb("SNMP v2c login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -version => 2, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } else { + # SNMPV1 login + verb("SNMP v1 login"); + ($session, $error) = Net::SNMP->session( + -hostname => $o_host, + -community => $o_community, + -port => $o_port, + -timeout => $o_timeout + ); + } +} +if (!defined($session)) { + printf("ERROR opening session: %s.\n", $error); + exit $ERRORS{"UNKNOWN"}; +} + +# Global variable +my $resultat=undef; + +########### Cisco memory check ############ +if (defined ($o_cisco)) { + + # Get Cisco memory table + $resultat = $session->get_table(Baseoid => $cisco_mem_pool); + + if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + my (@oid,@index)=(undef,undef); + my $nindex=0; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$cisco_index/ ) { + @oid=split (/\./,$key); + $index[$nindex++] = pop(@oid); + } + } + + # Check if at least 1 memory pool exists + if ($nindex == 0) { + printf("ERROR: No memory pools found"); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + # Test every memory pool + my ($c_output,$prct_free)=(undef,undef); + my ($warn_s,$crit_s)=(0,0); + my ($used,$free)=(0,0); + foreach (@index) { + $c_output .="," if defined ($c_output); + if ( $$resultat{$cisco_valid . "." . $_} == 1 ) { + $used += $$resultat{$cisco_used . "." . $_}; + $free += $$resultat{$cisco_free . "." . $_}; + $prct_free=round($$resultat{$cisco_used . "." . $_}*100/($$resultat{$cisco_free . "." . $_}+$$resultat{$cisco_used . "." . $_}) ,0); + $c_output .= $$resultat{$cisco_index . "." . $_} . ":" . $prct_free . "%"; + if (($o_crit!=0)&&($o_crit <= $prct_free)) { + $crit_s =1; + } elsif (($o_warn!=0)&&($o_warn <= $prct_free)) { + $warn_s=1; + } + } else { + $c_output .= $$resultat{$cisco_index . "." . $_} . ": INVALID"; + $crit_s =1; + } + } + my $total=$used+$free; + $prct_free=round($used*100/($total),0); + verb("Total used : $used, free: $free, output : $c_output"); + my $c_status="OK"; + $c_output .=" : " . $prct_free ."% : "; + if ($crit_s == 1 ) { + $c_output .= " > " . $o_crit ; + $c_status="CRITICAL"; + } else { + if ($warn_s == 1 ) { + $c_output.=" > " . $o_warn; + $c_status="WARNING"; + } + } + $c_output .= " ; ".$c_status; + if (defined ($o_perf)) { + $c_output .= " | ram_used=" . $used.";"; + $c_output .= ($o_warn ==0)? ";" : round($o_warn * $total/100,0).";"; + $c_output .= ($o_crit ==0)? ";" : round($o_crit * $total/100,0).";"; + $c_output .= "0;" . $total ; + } + $session->close; + print "$c_output \n"; + exit $ERRORS{$c_status}; +} + +########### HP Procurve memory check ############ +if (defined ($o_hp)) { + + # Get hp memory table + $resultat = $session->get_table(Baseoid => $hp_mem_pool); + + if (!defined($resultat)) { + printf("ERROR: Description table : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + my (@oid,@index)=(undef,undef); + my $nindex=0; + foreach my $key ( keys %$resultat) { + verb("OID : $key, Desc : $$resultat{$key}"); + if ( $key =~ /$hp_mem_index/ ) { + @oid=split (/\./,$key); + $index[$nindex++] = pop(@oid); + } + } + + # Check if at least 1 memory slots exists + if ($nindex == 0) { + printf("ERROR: No memory slots found"); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + # Consolidate the datas + my ($total,$free)=(0,0); + my ($c_output,$prct_free)=(undef,undef); + foreach (@index) { + $c_output .="," if defined ($c_output); + $total += $$resultat{$hp_mem_total . "." . $_}; + $free += $$resultat{$hp_mem_free . "." . $_}; + $c_output .= "Slot " . $$resultat{$hp_mem_index . "." . $_} . ":" + .round( + 100 - ($$resultat{$hp_mem_free . "." . $_} *100 / + $$resultat{$hp_mem_total . "." . $_}) ,0) + . "%"; + } + my $used = $total - $free; + $prct_free=round($used*100/($total),0); + verb("Used : $used, Free: $free, Output : $c_output"); + my $c_status="OK"; + $c_output .=" : " . $prct_free ."% : "; + if (($o_crit!=0)&&($o_crit <= $prct_free)) { + $c_output .= " > " . $o_crit ; + $c_status="CRITICAL"; + } else { + if (($o_warn!=0)&&($o_warn <= $prct_free)) { + $c_output.=" > " . $o_warn; + $c_status="WARNING"; + } + } + $c_output .= " ; ".$c_status; + if (defined ($o_perf)) { + $c_output .= " | ram_used=" . $used.";"; + $c_output .= ($o_warn ==0)? ";" : round($o_warn * $total/100,0).";"; + $c_output .= ($o_crit ==0)? ";" : round($o_crit * $total/100,0).";"; + $c_output .= "0;" . $total ; + } + $session->close; + print "$c_output \n"; + exit $ERRORS{$c_status}; +} + +########### Net snmp memory check ############ +if (defined ($o_netsnmp)) { + + # Get NetSNMP memory values + $resultat = $session->get_request(-varbindlist => \@nets_oids); + + if (!defined($resultat)) { + printf("ERROR: netsnmp : %s.\n", $session->error); + $session->close; + exit $ERRORS{"UNKNOWN"}; + } + + my ($realused,$swapused)=(undef,undef); + + $realused= defined($o_cache) ? + ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free})/$$resultat{$nets_ram_total} + : + ($$resultat{$nets_ram_total}-($$resultat{$nets_ram_free}+$$resultat{$nets_ram_cache}))/$$resultat{$nets_ram_total}; + + if($$resultat{$nets_ram_total} == 0) { $realused = 0; } + + $swapused= ($$resultat{$nets_swap_total} == 0) ? 0 : + ($$resultat{$nets_swap_total}-$$resultat{$nets_swap_free})/$$resultat{$nets_swap_total}; + $realused=round($realused*100,0); + $swapused=round($swapused*100,0); + defined($o_cache) ? + verb ("Ram : $$resultat{$nets_ram_free} / $$resultat{$nets_ram_total} : $realused") + : + verb ("Ram : $$resultat{$nets_ram_free} ($$resultat{$nets_ram_cache} cached) / $$resultat{$nets_ram_total} : $realused"); + verb ("Swap : $$resultat{$nets_swap_free} / $$resultat{$nets_swap_total} : $swapused"); + + my $n_status="OK"; + my $n_output="Ram : " . $realused . "%, Swap : " . $swapused . "% :"; + if ((($o_critR!=0)&&($o_critR <= $realused)) || (($o_critS!=0)&&($o_critS <= $swapused))) { + $n_output .= " > " . $o_critR . ", " . $o_critS; + $n_status="CRITICAL"; + } else { + if ((($o_warnR!=0)&&($o_warnR <= $realused)) || (($o_warnS!=0)&&($o_warnS <= $swapused))) { + $n_output.=" > " . $o_warnR . ", " . $o_warnS; + $n_status="WARNING"; + } + } + $n_output .= " ; ".$n_status; + if (defined ($o_perf)) { + if (defined ($o_cache)) { + $n_output .= " | ram_used=" . ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free}).";"; + } + else { + $n_output .= " | ram_used=" . ($$resultat{$nets_ram_total}-$$resultat{$nets_ram_free}-$$resultat{$nets_ram_cache}).";"; + } + $n_output .= ($o_warnR ==0)? ";" : round($o_warnR * $$resultat{$nets_ram_total}/100,0).";"; + $n_output .= ($o_critR ==0)? ";" : round($o_critR * $$resultat{$nets_ram_total}/100,0).";"; + $n_output .= "0;" . $$resultat{$nets_ram_total}. " "; + $n_output .= "swap_used=" . ($$resultat{$nets_swap_total}-$$resultat{$nets_swap_free}).";"; + $n_output .= ($o_warnS ==0)? ";" : round($o_warnS * $$resultat{$nets_swap_total}/100,0).";"; + $n_output .= ($o_critS ==0)? ";" : round($o_critS * $$resultat{$nets_swap_total}/100,0).";"; + $n_output .= "0;" . $$resultat{$nets_swap_total}; + } + $session->close; + print "$n_output \n"; + exit $ERRORS{$n_status}; + +} diff --git a/check_snmp_process.pl b/check_snmp_process.pl new file mode 100755 index 0000000..6c8477b --- /dev/null +++ b/check_snmp_process.pl @@ -0,0 +1,702 @@ +#!/usr/bin/perl -w +############################## check_snmp_process ############## +my $Version='1.10'; +# Date : Oct 12 2007 +# Author : Patrick Proy (patrick at proy dot org) +# Help : http://nagios.manubulon.com +# Licence : GPL - http://www.fsf.org/licenses/gpl.txt +# Contrib : Makina Corpus, adam At greekattic d0t com +# TODO : put $o_delta as an option +# If testing on localhost, selects itself.... +############################################################### +# +# help : ./check_snmp_process -h + +use strict; +use Net::SNMP; +use Getopt::Long; + +############### BASE DIRECTORY FOR TEMP FILE ######## +my $o_base_dir="/tmp/tmp_Nagios_proc."; +my $file_history=200; # number of data to keep in files. +my $delta_of_time_to_make_average=300; # 5minutes by default + +# Nagios specific + +my $TIMEOUT = 15; +my %ERRORS=('OK'=>0,'WARNING'=>1,'CRITICAL'=>2,'UNKNOWN'=>3,'DEPENDENT'=>4); + +# SNMP Datas +my $process_table= '1.3.6.1.2.1.25.4.2.1'; +my $index_table = '1.3.6.1.2.1.25.4.2.1.1'; +my $run_name_table = '1.3.6.1.2.1.25.4.2.1.2'; +my $run_path_table = '1.3.6.1.2.1.25.4.2.1.4'; +my $run_param_table = '1.3.6.1.2.1.25.4.2.1.5'; +my $proc_mem_table = '1.3.6.1.2.1.25.5.1.1.2'; # Kbytes +my $proc_cpu_table = '1.3.6.1.2.1.25.5.1.1.1'; # Centi sec of CPU +my $proc_run_state = '1.3.6.1.2.1.25.4.2.1.7'; + +# Globals + + +my $o_host = undef; # hostname +my $o_community =undef; # community +my $o_port = 161; # port +my $o_version2 = undef; #use snmp v2c +my $o_descr = undef; # description filter +my $o_warn = 0; # warning limit +my @o_warnL= undef; # warning limits (min,max) +my $o_crit= 0; # critical limit +my @o_critL= undef; # critical limits (min,max) +my $o_help= undef; # wan't some help ? +my $o_verb= undef; # verbose mode +my $o_version= undef; # print version +my $o_noreg= undef; # Do not use Regexp for name +my $o_path= undef; # check path instead of name +my $o_inverse= undef; # checks max instead of min number of process +my $o_get_all= undef; # get all tables at once +my $o_param= undef; # Add process parameters for selection +my $o_perf= undef; # Add performance output +my $o_timeout= 5; # Default 5s Timeout +# SNMP V3 specific +my $o_login= undef; # snmp v3 login +my $o_passwd= undef; # snmp v3 passwd +my $v3protocols=undef; # V3 protocol list. +my $o_authproto='md5'; # Auth protocol +my $o_privproto='des'; # Priv protocol +my $o_privpass= undef; # priv password +# SNMP Message size parameter (Makina Corpus contrib) +my $o_octetlength=undef; +# Memory & CPU +my $o_mem= undef; # checks memory (max) +my @o_memL= undef; # warn and crit level for mem +my $o_mem_avg= undef; # cheks memory average +my $o_cpu= undef; # checks CPU usage +my @o_cpuL= undef; # warn and crit level for cpu +my $o_delta= $delta_of_time_to_make_average; # delta time for CPU check + +# functions + +sub p_version { print "check_snmp_process version : $Version\n"; } + +sub print_usage { + print "Usage: $0 [-v] -H -C [-2] | (-l login -x passwd) [-p ] -n [-w [,] -c [,max_proc] ] [-m, -a -u, -d ] [-t ] [-o ] [-f -A -F ] [-r] [-V] [-g]\n"; +} + +sub isnotnum { # Return true if arg is not a number + my $num = shift; + if ( $num =~ /^-?(\d+\.?\d*)|(^\.\d+)$/ ) { return 0 ;} + return 1; +} + +# Get the alarm signal (just in case snmp timout screws up) +$SIG{'ALRM'} = sub { + print ("ERROR: Alarm signal (Nagios time-out)\n"); + exit $ERRORS{"UNKNOWN"}; +}; + +sub read_file { + # Input : File, items_number + # Returns : array of value : [line][item] + my ($traffic_file,$items_number)=@_; + my ($ligne,$n_rows)=(undef,0); + my (@last_values,@file_values,$i); + open(FILE,"<".$traffic_file) || return (1,0,0); + + while($ligne = ) + { + chomp($ligne); + @file_values = split(":",$ligne); + #verb("@file_values"); + if ($#file_values >= ($items_number-1)) { + # check if there is enough data, else ignore line + for ( $i=0 ; $i< $items_number ; $i++ ) {$last_values[$n_rows][$i]=$file_values[$i]; } + $n_rows++; + } + } + close FILE; + if ($n_rows != 0) { + return (0,$n_rows,@last_values); + } else { + return (1,0,0); + } +} + +sub write_file { + # Input : file , rows, items, array of value : [line][item] + # Returns : 0 / OK, 1 / error + my ($file_out,$rows,$item,@file_values)=@_; + my $start_line= ($rows > $file_history) ? $rows - $file_history : 0; + if ( open(FILE2,">".$file_out) ) { + for (my $i=$start_line;$i<$rows;$i++) { + for (my $j=0;$j<$item;$j++) { + print FILE2 $file_values[$i][$j]; + if ($j != ($item -1)) { print FILE2 ":" }; + } + print FILE2 "\n"; + } + close FILE2; + return 0; + } else { + return 1; + } +} + +sub help { + print "\nSNMP Process Monitor for Nagios version ",$Version,"\n"; + print "GPL licence, (c)2004-2006 Patrick Proy\n\n"; + print_usage(); + print <, + : Authentication protocol (md5|sha : default md5) + : Priv protocole (des|aes : default des) +-p, --port=PORT + SNMP port (Default 161) +-n, --name=NAME + Name of the process (regexp) + No trailing slash ! +-r, --noregexp + Do not use regexp to match NAME in description OID +-f, --fullpath + Use full path name instead of process name + (Windows doesn't provide full path name) +-A, --param + Add parameters to select processes. + ex : "named.*-t /var/named/chroot" will only select named process with this parameter +-F, --perfout + Add performance output + outputs : memory_usage, num_process, cpu_usage +-w, --warn=MIN[,MAX] + Number of process that will cause a warning + -1 for no warning, MAX must be >0. Ex : -w-1,50 +-c, --critical=MIN[,MAX] + number of process that will cause an error ( + -1 for no critical, MAX must be >0. Ex : -c-1,50 +Notes on warning and critical : + with the following options : -w m1,x1 -c m2,x2 + you must have : m2 <= m1 < x1 <= x2 + you can omit x1 or x2 or both +-m, --memory=WARN,CRIT + checks memory usage (default max of all process) + values are warning and critical values in Mb +-a, --average + makes an average of memory used by process instead of max +-u, --cpu=WARN,CRIT + checks cpu usage of all process + values are warning and critical values in % of CPU usage + if more than one CPU, value can be > 100% : 100%=1 CPU +-d, --delta=seconds + make an average of seconds for CPU (default 300=5min) +-g, --getall + In some cases, it is necessary to get all data at once because + process die very frequently. + This option eats bandwidth an cpu (for remote host) at breakfast. +-o, --octetlength=INTEGER + max-size of the SNMP message, usefull in case of Too Long responses. + Be carefull with network filters. Range 484 - 65535, default are + usually 1472,1452,1460 or 1440. +-t, --timeout=INTEGER + timeout for SNMP in seconds (Default: 5) +-V, --version + prints version number +Note : + CPU usage is in % of one cpu, so maximum can be 100% * number of CPU + example : + Browse process list :