Code

new plugins contrib
authorSubhendu Ghosh <sghosh@users.sourceforge.net>
Thu, 22 Aug 2002 14:42:43 +0000 (14:42 +0000)
committerSubhendu Ghosh <sghosh@users.sourceforge.net>
Thu, 22 Aug 2002 14:42:43 +0000 (14:42 +0000)
git-svn-id: https://nagiosplug.svn.sourceforge.net/svnroot/nagiosplug/nagiosplug/trunk@82 f882894a-f735-0410-b71e-b25c423dba1c

contrib/check_snmp_disk_monitor.pl [new file with mode: 0644]
contrib/check_snmp_process_monitor.pl [new file with mode: 0644]

diff --git a/contrib/check_snmp_disk_monitor.pl b/contrib/check_snmp_disk_monitor.pl
new file mode 100644 (file)
index 0000000..7a70f71
--- /dev/null
@@ -0,0 +1,185 @@
+#!/usr/local/bin/perl
+# author: Al Tobey <albert.tobey@priority-health.com>
+# what:    monitor diskspace using the host-resources mib
+# license: GPL - http://www.fsf.org/licenses/gpl.txt
+#
+# Todo:
+
+use strict;
+require 5.6.0;
+use lib qw( /opt/nagios/libexec );
+use utils qw(%ERRORS $TIMEOUT &print_revision &support &usage);
+use SNMP 5.0;
+use Getopt::Long;
+use vars qw( $exit $message $opt_version $opt_timeout $opt_help $opt_command $opt_host $opt_community $opt_verbose $opt_warning $opt_critical $opt_port $opt_mountpoint $opt_stats $snmp_session $PROGNAME $TIMEOUT %mounts );
+
+$PROGNAME      = "snmp_disk_monitor.pl";
+$opt_verbose   = undef;
+$opt_host      = undef;
+$opt_community = 'public';
+$opt_command   = undef;
+$opt_warning   = 99;
+$opt_critical  = 100;
+$opt_port      = 161;
+$opt_stats     = undef;
+$message       = undef;
+$exit          = 'OK';
+%mounts        = ();
+
+sub process_options {
+    my( $opt_crit, $opt_warn ) = ();
+    Getopt::Long::Configure( 'bundling' );
+    GetOptions(
+        'V'     => \$opt_version,       'version'     => \$opt_version,
+        'v'     => \$opt_verbose,       'verbose'     => \$opt_verbose,
+        'h'     => \$opt_help,          'help'        => \$opt_help,
+        's'     => \$opt_stats,         'statistics'  => \$opt_stats,
+        'H:s'   => \$opt_host,          'hostname:s'  => \$opt_host,
+        'p:i'   => \$opt_port,          'port:i'      => \$opt_port,
+        'C:s'   => \$opt_community,     'community:s' => \$opt_community,
+        'c:i'   => \$opt_crit,          'critical:i'  => \$opt_crit,
+        'w:i'   => \$opt_warn,          'warning:i'   => \$opt_warn,
+        't:i'   => \$TIMEOUT,           'timeout:i'   => \$TIMEOUT,    
+        'm:s'   => \$opt_mountpoint,    'mountpoint:s'=> \$opt_mountpoint
+    );
+    if ( defined($opt_version) ) { local_print_revision(); }
+    if ( defined($opt_verbose) ) { $SNMP::debugging = 1; }
+    if ( !defined($opt_host) || defined($opt_help) || !defined($opt_mountpoint) ) {
+        print_help();
+        exit $ERRORS{UNKNOWN};
+    }
+    $opt_mountpoint = [ split(/,/, $opt_mountpoint) ];
+}
+
+sub local_print_revision {
+        print_revision( $PROGNAME, '$Revision$ ' )
+}
+
+sub print_usage {
+    print "Usage: $PROGNAME -H <host> -C <snmp_community> [-s] [-w <low>,<high>] [-c <low>,<high>] [-t <timeout>] -m <mountpoint>\n";
+}
+
+sub print_help {
+    local_print_revision();
+    print "Copyright (c) 2002 Al Tobey <albert.tobey\@priority-health.com>\n\n",
+          "SNMP Disk Monitor plugin for Nagios\n\n";
+    print_usage();
+    print <<EOT;
+-v, --verbose
+   print extra debugging information
+-h, --help
+   print this help message
+-H, --hostname=HOST
+   name or IP address of host to check
+-C, --community=COMMUNITY NAME
+   community name for the host's SNMP agent
+-m, --mountpoint=MOUNTPOINT
+   a mountpoint, or a comma delimited list of mountpoints
+-w, --warning=INTEGER
+   percent of disk used to generate WARNING state (Default: 99)
+-c, --critical=INTEGER
+   percent of disk used to generate CRITICAL state (Default: 100)
+-s, --statistics
+   output statistics in Nagios format
+EOT
+}
+
+sub verbose (@) {
+    return if ( !defined($opt_verbose) );
+    print @_;
+}
+
+sub check_for_errors {
+    if ( $snmp_session->{ErrorNum} ) {
+        print "UNKNOWN - error retrieving SNMP data: $snmp_session->{ErrorStr}\n";
+        exit $ERRORS{UNKNOWN};
+    }
+}
+
+# =========================================================================== #
+# =====> MAIN
+# =========================================================================== #
+process_options();
+
+alarm( $TIMEOUT ); # make sure we don't hang Nagios
+
+$snmp_session = new SNMP::Session(
+    DestHost => $opt_host,
+    Community => $opt_community,
+    RemotePort => $opt_port,
+    Version   => '2c'
+);
+
+# retrieve the data from the remote host
+my( $mps, $alloc, $size, $used ) = $snmp_session->bulkwalk( 0, 4, [['hrStorageDescr'],['hrStorageAllocationUnits'],['hrStorageSize'],['hrStorageUsed']] );
+check_for_errors();
+
+alarm( 0 ); # all done with the network connection
+
+# move all the data into a nice, convenient hash for processing
+foreach my $mp ( @$mps )   { $mounts{$mp->iid}->{mountpoint} = $mp->val; }
+foreach my $a  ( @$alloc ) { $mounts{$a->iid}->{alloc_units} = $a->val; }
+foreach my $si ( @$size ) {
+    if ( exists($mounts{$si->iid}->{alloc_units}) ) {
+        $mounts{$si->iid}->{size} = $si->val * $mounts{$si->iid}->{alloc_units};
+    }
+    else {
+        $mounts{$si->iid}->{size} = $si->val;
+    }
+}
+foreach my $us ( @$used ) {
+    if ( exists($mounts{$us->iid}->{alloc_units}) ) {
+        $mounts{$us->iid}->{used} = $us->val * $mounts{$us->iid}->{alloc_units};
+    }
+    else {
+        $mounts{$us->iid}->{used} = $us->val;
+    }
+}
+
+# now find the mountpoint or mountpoints that were actually requested and push onto an array for output
+my @matches = ();
+foreach my $mp ( @$opt_mountpoint ) {
+    my $found = scalar(@matches); # count all matches
+    foreach my $key ( keys(%mounts) ) {
+        if ( $mounts{$key}->{mountpoint} eq $mp ) {
+
+            # find the percentate - eval to avoid divide by zero errors
+            eval { $mounts{$key}->{percent_used} = $mounts{$key}->{used} / $mounts{$key}->{size} };
+            $mounts{$key}->{percent_used} =~ s/^0\.([0-9]{1,2})([0-9]?).*/\1/; # truncate
+            if ( $2 >= 5 ) { $mounts{$key}->{percent_used}++ }; # round the number number
+
+            verbose "mountpoint $mp has ", $mounts{$key}->{percent_used}, "% used, ",
+                $mounts{$key}->{size}, " bytes and ",$mounts{$key}->{used}, " used\n"; 
+
+            push( @matches, $mounts{$key} );
+        }
+    }
+    if ( scalar(@matches) == $found ) {
+        print "UNKNOWN - could not locate mountpoint $mp on host\n";
+        exit $ERRORS{UNKNOWN};
+    }
+}
+
+# now run through and check the thresholds
+foreach my $mp ( @matches ) {
+    if ( $mp->{percent_used} >= $opt_warning  ) {
+        $exit = 'WARNING';
+        if ( $mp->{percent_used} >= $opt_critical ) { $exit = 'CRITICAL'; }
+    }
+    $message .= $mp->{percent_used}.'% used on '.$mp->{mountpoint}.', ';
+}
+$message =~ s/,\s*$//;
+
+# append statistics if requested
+if ( defined($opt_stats) ) {
+    my @tmp = ();
+    foreach my $mp ( @matches ) {
+        push( @tmp, join(',',$mp->{mountpoint},$mp->{size},$mp->{used}) );
+    }
+    $message .= '|'.join( ':', @tmp );
+}
+
+print "Disk $exit - $message\n";
+exit $ERRORS{$exit};
+
+
diff --git a/contrib/check_snmp_process_monitor.pl b/contrib/check_snmp_process_monitor.pl
new file mode 100644 (file)
index 0000000..263255b
--- /dev/null
@@ -0,0 +1,227 @@
+#!/usr/local/bin/perl
+# author: Al Tobey <albert.tobey@priority-health.com>
+# what:   monitor a process using the host-resources mib
+# license: GPL - http://www.fsf.org/licenses/gpl.txt
+#
+# Todo:
+# * implement memory and cpu utilization checks
+# * maybe cache pids in DBM files if snmp agents get overworked
+###############################################################################
+# to get a list of processes over snmp try this command:
+# snmptable -v2c -c public hostname hrSWRunTable
+# for just a list of valid arguments for the '-e' option:
+# snmpwalk -v2c -c public hostname hrSWRunName |perl -pe 's:.*/::'
+###############################################################################
+
+use strict;
+require 5.6.0;
+use lib qw( /opt/nagios/libexec /usr/local/libexec );
+use utils qw(%ERRORS $TIMEOUT &print_revision &support &usage);
+use SNMP 5.0;
+use Getopt::Long;
+use vars qw( $exit $opt_version $opt_timeout $opt_help $opt_command $opt_host $opt_community $opt_verbose $opt_warning $opt_critical $opt_memory $opt_cpu $opt_port $opt_regex $opt_stats %processes $snmp_session $PROGNAME $TIMEOUT );
+
+$PROGNAME      = "snmp_process_monitor.pl";
+$opt_verbose   = undef;
+$opt_host      = undef;
+$opt_community = 'public';
+$opt_command   = undef;
+$opt_warning   = [ 1, -1 ];
+$opt_critical  = [ 1, -1 ];
+$opt_memory    = undef;
+$opt_cpu       = undef;
+$opt_port      = 161;
+%processes     = ();
+$exit          = 'OK';
+
+sub process_options {
+    my( $opt_crit, $opt_warn ) = ();
+    Getopt::Long::Configure( 'bundling' );
+    GetOptions(
+        'V'     => \$opt_version,       'version'     => \$opt_version,
+        'v'     => \$opt_verbose,       'verbose'     => \$opt_verbose,
+        'h'     => \$opt_help,          'help'        => \$opt_help,
+        's'     => \$opt_stats,         'statistics'  => \$opt_stats,
+        'H:s'   => \$opt_host,          'hostname:s'  => \$opt_host,
+        'p:i'   => \$opt_port,          'port:i'      => \$opt_port,
+        'C:s'   => \$opt_community,     'community:s' => \$opt_community,
+        'c:s'   => \$opt_crit,          'critical:s'  => \$opt_crit,
+        'w:s'   => \$opt_warn,          'warning:s'   => \$opt_warn,
+        't:i'   => \$TIMEOUT,           'timeout:i'   => \$TIMEOUT,    
+        'e:s'   => \$opt_command,       'command:s'   => \$opt_command,
+        'r:s'   => \$opt_regex,         'regex:s'     => \$opt_regex,
+        'cpu:i' => \$opt_cpu,           'memory:i'    => \$opt_memory,
+    );
+    if ( defined($opt_version) ) { local_print_revision(); }
+    if ( defined($opt_verbose) ) { $SNMP::debugging = 1; }
+    if ( !defined($opt_host) || defined($opt_help) || (!defined($opt_command) && !defined($opt_regex)) ) {
+        print_help();
+        exit $ERRORS{UNKNOWN};
+    }
+
+    if ( defined($opt_crit) ) {
+        if ( $opt_crit =~ /,/ ) {
+            $opt_critical = [ split(',', $opt_crit) ];
+        }
+        else {
+            $opt_critical = [ $opt_crit, -1 ];
+        }
+    }
+    if ( defined($opt_warn) ) {
+        if ( $opt_warn =~ /,/ ) {
+            $opt_warning = [ split(',', $opt_warn) ];
+        }
+        else {
+            $opt_warning = [ $opt_crit, -1 ];
+        }
+    }
+}
+
+sub local_print_revision {
+        print_revision( $PROGNAME, '$Revision$ ' )
+}
+
+sub print_usage {
+    print "Usage: $PROGNAME -H <host> -C <snmp_community> -e <command> [-w <low>,<high>] [-c <low>,<high>] [-t <timeout>]\n";
+}
+
+sub print_help {
+    local_print_revision();
+    print "Copyright (c) 2002 Al Tobey <albert.tobey\@priority-health.com>\n\n",
+          "SNMP Process Monitor plugin for Nagios\n\n";
+    print_usage();
+    print <<EOT;
+-v, --verbose
+   print extra debugging information
+-h, --help
+   print this help message
+-H, --hostname=HOST
+   name or IP address of host to check
+-C, --community=COMMUNITY NAME
+   community name for the host's SNMP agent
+-e, --command=COMMAND NAME (ps -e style)
+   what command should be monitored?
+-r, --regex=Perl RE
+   use a perl regular expression to find your process
+-w, --warning=INTEGER[,INTEGER]
+   minimum and maximum number of processes before a warning is issued (Default 1,-1)
+-c, --critical=INTEGER[,INTEGER]
+   minimum and maximum number of processes before a critical is issued (Default 1,-1)
+EOT
+}
+
+sub verbose (@) {
+    return if ( !defined($opt_verbose) );
+    print @_;
+}
+
+sub check_for_errors {
+    if ( $snmp_session->{ErrorNum} ) {
+        print "UNKNOWN - error retrieving SNMP data: $snmp_session->{ErrorStr}\n";
+        exit $ERRORS{UNKNOWN};
+    }
+}
+
+# =========================================================================== #
+# =====> MAIN
+# =========================================================================== #
+process_options();
+
+alarm( $TIMEOUT ); # make sure we don't hang Nagios
+
+$snmp_session = new SNMP::Session(
+    DestHost => $opt_host,
+    Community => $opt_community,
+    RemotePort => $opt_port,
+    Version   => '2c'
+);
+
+my $process_count = SNMP::Varbind->new( ['hrSystemProcesses', 0] );
+$snmp_session->get( $process_count ); 
+check_for_errors();
+
+# retrieve the data from the remote host
+my( $names, $index ) = $snmp_session->bulkwalk( 0, $process_count->val, [['hrSWRunName'], ['hrSWRunIndex']] );
+check_for_errors();
+
+alarm( 0 ); # all done with the network connection
+
+my %namecount = ();
+foreach my $row ( @$names ) {
+    $processes{$row->iid}->{name} = $row->val;
+    $processes{$row->iid}->{name} =~ s#.*/##; # strip path
+
+    if ( defined($opt_regex) ||
+        ($row->val =~ /(perl|\/usr\/bin\/sh|\/bin\/bash|\/bin\/sh)$/
+        && $opt_command !~ /(perl|\/usr\/bin\/sh|\/bin\/bash|\/bin\/sh)$/) ) {
+
+        # fetch the runtime parameters of the process
+        my $parm_var = SNMP::Varbind->new( ['hrSWRunParameters', $row->iid] );
+        $snmp_session->get( $parm_var );
+        check_for_errors();
+
+        # only strip if we're looking for a specific command
+        if ( defined($opt_command) ) {
+            verbose "process ",$row->iid," uses $1 as an interpreter - getting parameters\n";
+            $processes{$row->iid}->{name} = $parm_var->val;
+            # strip path name off the front
+            $processes{$row->iid}->{name} =~ s#.*/##;
+            # strip everything from the first space to the end
+            $processes{$row->iid}->{name} =~ s/\s+.*$//;
+        }
+        else {
+            # get the longer full-path style listing
+            my $path_var = SNMP::Varbind->new( ['hrSWRunPath', $row->iid] );
+            $snmp_session->get( $path_var );
+            check_for_errors();
+
+            # use the full 'ps -efl' style listing for regular expression matching
+            $processes{$row->iid}->{name} = $path_var->val.' '.$parm_var->val;
+        }
+    }
+}
+foreach my $row ( @$index ) {
+    $processes{$row->iid}->{pid}  = $row->val;
+}
+
+my @pids    = ();
+my @matches = ();
+foreach my $key ( keys(%processes) ) {
+    if ( defined($opt_command) && $processes{$key}->{name} eq $opt_command ) {
+        push( @matches, $processes{$key} );
+        push( @pids, $processes{$key}->{pid} );
+        verbose "process '$processes{$key}->{name}' has pid ",
+            "$processes{$key}->{pid} and index $key\n";
+    }
+    elsif ( defined($opt_regex) && $processes{$key}->{name} =~ /$opt_regex/o ) {
+        push( @matches, $processes{$key} );
+        push( @pids, $processes{$key}->{pid} );
+        verbose "process '$processes{$key}->{name}' has pid ",
+            "$processes{$key}->{pid} and index $key\n";
+    }
+}
+my $count = @matches;
+
+# warning, critical
+if ( ($opt_warning->[0] > 0 && $opt_warning->[0]  >  $count)
+  || ($opt_warning->[1] > 0 && $opt_warning->[1]  <= $count) ) {
+    $exit = 'WARNING';
+}
+if ( ($opt_critical->[0] > 0 && $opt_critical->[0]  >  $count)
+  || ($opt_critical->[1] > 0 && $opt_critical->[1]  <= $count) ) {
+    $exit = 'CRITICAL';
+}
+
+print "$exit - $count processes with pid(s) ",join(',',@pids);
+
+# print the number of processes if statistics are requested
+if ( defined($opt_stats) ) {
+    print "|count:$count\n";
+}
+else {
+    print "\n";
+}
+
+exit $ERRORS{$exit};
+
+