#!/usr/local/bin/perl -w # # check_remote_proc # # by ATonns Mon Sep 9 14:15:23 EDT 2002 # # monitor the custom ps OID via net-snmpd to view process table # # # $Id: check_remote_proc,v 1.3 2003/07/08 18:12:33 atonns Exp atonns $ # # check_remote_proc # Copyright (C) 2003 - iVillage.com, Anthony Tonns # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # perl setup use strict; use Getopt::Long; use Net::SNMP (); use CGI(-debug); use IO::String; use lib "/usr/local/nagios/libexec"; use utils qw($TIMEOUT %ERRORS &print_revision &support); delete @ENV{'PATH', 'IFS', 'CDPATH', 'ENV', 'BASH_ENV'}; use NWPE; # static variables my $PROGNAME = "check_remote_proc"; my $version = '$Revision: 1.3 $'; # OIDs for the custom net-snmpd process table # # .iso.org.dod.internet.private.enterprises.ucdavis.52.101 my $baseoid = "1.3.6.1.4.1.2021.52.101"; my $baselen = length($baseoid) + 1; # auth config stuff my $username = "xxxxxxxx"; my $authpass = "xxxxxxxx"; my $privpass = "xxxxxxxx"; ################################################################################ my $nwpe = NWPE->new($PROGNAME,$version); @ARGV = $nwpe->get_args; if ( ! exists $ARGV[0] ) { print "$PROGNAME: no args passed\n"; $nwpe->quit($ERRORS{UNKNOWN}); } # parse args my ($opt_V,$opt_h,$opt_v,$opt_H,$opt_r,$opt_l,$opt_u); # bleh inititalization sucks $opt_l = $opt_u = ""; Getopt::Long::Configure('bundling'); GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "v+" => \$opt_v, "verbose+" => \$opt_v, "H=s" => \$opt_H, "hostname=s" => \$opt_H, "r=s" => \$opt_r, "regex=s" => \$opt_r, "l=i" => \$opt_l, "lower=i" => \$opt_l, "u=i" => \$opt_u, "upper=i" => \$opt_u, ); # check args if ( $opt_h ) { print_usage($nwpe,""); } if ( $opt_V ) { print_revision($PROGNAME,$version); $nwpe->quit($ERRORS{OK}); } if ( ! $opt_H ) { print_usage($nwpe,"must specify hostname with -H option."); } if ( ! $opt_r ) { print_usage($nwpe,"must specify regular expressiong for process matching."); } if ( "$opt_l" eq "" ) { print_usage($nwpe,"must specify lower limit for number of matching procs with -l option"); } if ( "$opt_u" eq "" ) { print_usage($nwpe,"must specify upper limit for number of matching procs with -u option"); } # validate/rename input to sane variable names my $hostname = $opt_H; my $regex = $opt_r; my $lower = $opt_l; my $upper = $opt_u; # last sanity check if ( $upper != 0 && $lower > $upper ) { print_usage($nwpe,qq!Inconsistence in parameters: lower limit ($lower) greater than upper limit ($upper).!); } #DEBUG #print "hostname $hostname\n"; #print "regex $regex\n"; #print "lower $lower\n"; #print "upper $upper\n"; # set a timeout w/error message $SIG{'ALRM'} = sub { print ("$PROGNAME: alarm timeout\n"); $nwpe->quit($ERRORS{UNKNOWN}); }; #alarm($TIMEOUT); # establish a session my ($session,$error) = Net::SNMP->session( -hostname => $hostname, -version => "3", -username => $username, -authprotocol => "md5", -authpassword => $authpass, -privpassword => $privpass, -maxmsgsize => 1048576, -timeout => $TIMEOUT, -retries => 3, # -debug => 0xff, ); if ( $error ) { print "$PROGNAME: session error: $error\n"; $nwpe->quit($ERRORS{UNKNOWN}); } # retreive the process table my $result = $session->get_table( -baseoid => $baseoid, ); if ( $session->error ) { print "$PROGNAME: get_table error: ".$session->error."\n"; $session->close; $nwpe->quit($ERRORS{UNKNOWN}); } $session->close; my %data; # simplify data by re-hashing on final column foreach (sort keys %{$result}) { my $key = $_; my ($instance) = substr($key,$baselen); $data{$instance} = ${$result}{$key}; } #DEBUG ## let's see it in order now #foreach (sort {$a<=>$b} keys %data) { # my $key = $_; # my $val = $data{$key}; # print "$key "; # print " " if length($key) < 8; # print "$val\n"; #} # since we've checked all the sanity beforehand, # start off assuming all is well my $state = $ERRORS{OK}; my $count = 0; foreach (sort {$a<=>$b} keys %data) { my $key = $_; my $val = $data{$key}; if ( $val =~ /$regex/ ) { $count++; } } if ( $count < $lower ) { $state = $ERRORS{CRITICAL}; } if ( $upper != 0 && $count > $upper ) { $state = $ERRORS{CRITICAL}; } # print text for the humans my $statetxt; foreach (keys(%ERRORS)) { my $key = $_; $statetxt=$key if ( $state == $ERRORS{$key} ); } # the almighty output print qq!Process "$regex" - $count instances ($lower / $upper)!; print qq! - $statetxt! unless $state == $ERRORS{OK}; print qq!\n!; $nwpe->quit($state); ################################################################################ # how does this work again? sub print_usage { my ($nwpe,$msg) = @_; my $PROGNAME = $nwpe->PROGNAME; my $version = $nwpe->version; if ( $msg ) { print "$PROGNAME: $msg\n\n"; } print_revision($PROGNAME,$version); print "Usage: $PROGNAME -H hostname -r regex " . "-l lower -u upper\n"; print "Usage: $PROGNAME --hostname=hostname --regex=regularExpression " . "--lower=lowerLimit --upper=upperLimit\n"; print " ".' ' x length($PROGNAME) . " [-v|--verbose -V|--version -h|--help]\n"; print "NOTE: lowerLimit of 0 returns 'OK' if none are running\n"; print "NOTE: upperLimit of 0 returns 'OK' no matter how many are running\n"; $nwpe->quit($ERRORS{UNKNOWN}); }