Code

Fix for regex input of '|', being output causing problems with Nagios' parsing of
[nagiosplug.git] / contrib / check_javaproc.pl
1 #!/usr/bin/perl -w
3 #
4 # Author: Wim Rijnders, 17-10-2002
5 #
6 # Description:
7 # -----------
8 #
9 # Nagios host script to check if any specified java processes are running.
10 #
11 # Implementation Notes:
12 # ---------------------
13 #
14 # check_disk_smb was used as a starting point, since it was written in perl.
15 #
16 # This script has been created and tested on Linux RH 7.1. 
17 #
18 # I tried OS-X Darwin (BSD), but the ps command works differently.
19 # Notably, you can't get a combined list of child processes. The best approach
20 # appears to be to use 'ps -wwaxo command' combined with 'ps -M' (or suchlike) 
21 #
22 ########################################################################
23 ####
25 require 5.004;
26 use POSIX;
27 use strict;
28 use Getopt::Long;
29 use vars qw($opt_w $opt_c $verbose $classname);
30 use vars qw($PROGNAME);
31 use lib "utils.pm" ;
32 use utils qw($TIMEOUT %ERRORS &print_revision &support &usage);
34 $PROGNAME="check_javaprocs";
35 sub getJavaList ();
36 sub check_ranges ($ $ $ $);
38 Getopt::Long::Configure('bundling', 'no_ignore_case');
39 GetOptions
40         ("V|version"     => \&version,
41          "h|help"        => \&help,
42          "v|verbose"     => \$verbose,
43          "w|warning=s"   => \$opt_w,
44          "c|critical=s"  => \$opt_c,
45          "n|name=s"      => \$classname
46          );
49 my $state    = 'OK';
50 my $min_warn = undef 
51 my $max_warn = undef;
52 my $min_crit = undef;
53 my $max_crit = undef;
56 ($opt_w) || ($opt_w = shift);
57 check_ranges($opt_w,\$min_warn, \$max_warn, "warning");
58 ($opt_c) || ($opt_c = shift);
59 check_ranges($opt_c,\$min_crit, \$max_crit, "critical");
62 #
63 # Determine # of running processes for the java programs that interest us. 
64 #
65 my @javalist = getJavaList();
67 my $total = 0;
68 my $msgout = "";
69 my @fields;
71 if ( defined $classname ) {
73         #filter out a single java process based on class name
74         foreach (@javalist) {
75                 @fields = split(/\s+/, $_);
76                 $total = $fields[-1] and last if $classname eq $fields[0];
77         }
78         $msgout .=  "$total processes for $classname\n";
79 } else {
80         #Handle all java processes
81         $msgout .= "\n";
82         foreach (@javalist) {
83                 @fields = split(/\s+/, $_);
84         
85                 $total += $fields[-1];
86                 $msgout .= "   $fields[-1] processes for ";
87                 $msgout .= (scalar @fields > 1)? $fields[0] : "unknown" ;
88                 $msgout .= "\n";
89         }
90         my $msgtotal =  "$total java processes for ". scalar @javalist .  " applications";
92         if ( defined $verbose ) {
93                 $msgout = $msgtotal . $msgout;
94         } else {
95                 $msgout = $msgtotal;
96         }
97         
98 }
101 # Set the state with the data we now have accumulated
102 # Note that due to the order of testing, warnings have precedence over
103 # criticals. This is logical, since you should be able to create a criticals
104 # range which encompasses a warning range. eg. following should be possible:
106 # check_javaproc -w 5:10 -c 3:12
107 # proper specification of the ranges is the responsibility of the script user.
109 $state = 'CRITICAL' if (defined $min_crit && $total < $min_crit);
110 $state = 'CRITICAL' if (defined $max_crit && $total > $max_crit);
111 $state = 'CRITICAL' if (!defined $min_crit && !defined $max_crit && $total==0 );
112 $state = 'WARNING' if (defined $min_warn && $total < $min_warn);
113 $state = 'WARNING' if (defined $max_warn && $total > $max_warn);
115 print $msgout;
116 print "$state\n" if ($verbose);
117 exit $ERRORS{$state};
119 ###################################
120 # Support routines for Nagios
121 ###################################
122 sub check_ranges($$$$) {
123         my ($opt, $min, $max, $rangename) = @_;
124         
125         if ( defined $opt ) {
126                 if ( $opt =~ /^([0-9]*)\:([0-9]*)$/) {
127                         $$min = $1 if $1 > 0;
128                         $$max= $2 if $2 > 0;
129                 } else {
130                         usage("Invalid $rangename range: $opt\n");
131                 } 
132         }
133         
134         if ( defined $$min && defined $$max ) {
135                 usage("Min value of $rangename range larger than max value: $opt\n") if ( $$min > $$max);
136         }
139 sub print_usage () {
140         print "Usage: $PROGNAME [-v] [-w <min:max>] [-c <min:max>] [ -n <classname>]\n";
143 sub print_help () {
144         revision();
145         print "Copyright (c) 2002 by Wim Rijnders
147 Perl Check java processes plugin for Nagios
149 ";
150         print_usage();
151         print "
152 -v, --verbose
153    Return additional information. 
154    Intended as a command-line aid, not recommended for Nagios script usage.
155    
156 -w, --warning=INTEGER:INTEGER
157    Minimum and maximum number of processes outside of which a warning will be
158    generated.  If omitted, no warning is generated. 
159    
160 -c, --critical=INTEGER:INTEGER
161    Minimum and maximum number of processes outside of which a critical will be
162    generated. If omitted, a critical is generated if no processes are running.
163    
164 -n, --name=STRING
165    Name of class specified on the java command line (from which main() is run).
166    If omitted, all java processes are taken into account.
168 ";
169         support();
172 sub revision() {
173         print_revision($PROGNAME,'$Revision: 211 $ ');
176 sub version () {
177         revision();
178         exit $ERRORS{'OK'};
181 sub help () {
182         print_help();
183         exit $ERRORS{'OK'};
186 ###################################
187 # Routines for delivering the data 
188 ###################################
191 # Generate a formatted list of running java processes.
193 # Returns an array of strings having the following syntax:
195 #       <java class running as main> <parameters if any> <#processes for this class>
197 sub getJavaList() {
199         my @output;
201         # Untaint
202         local $ENV{'PATH'} = '/bin:/usr/bin';   
203         local $ENV{'BASH_ENV'} = '~/.bashrc';   
204         
205         # We are only interested in the full command line
206         # The -H opstion is important for the order of the processes;
207         # this option ensures that all child processes are listed under
208         # their parents
209         @output=`ps -AHo \"\%a\" -ww`;
210         
211         #remove preceding whitespace and final EOL
212         foreach (@output) { 
213                 s/^\s*//;
214                 chop; 
215         } 
216         
217         #Combine any consecutive processes with exactly the same command line
218         #into a single item
219         @output = checkSameLine(@output);
220         
221         #Filter out all java processes
222         my @javalist;
223         for (my $i = 0; $i < scalar @output; ++$i) {
224                 push @javalist, $output[$i] if $output[$i] =~ /^\S*java/;
225         }
226         
227         foreach (@javalist) {
228                 #The java statement at the beginning is redundant; remove it
229                 s/^\S*java//; 
230         
231                 #remove all defines
232                 s/\-D\S+//g;
233         
234                 #remove classpath
235                 s/\-(classpath|cp)\s+\S+//g;
236         
237                 #remove any other parameters we don't want to see
238                 s/\-server\s+//g;
239                 s/\-X\S*\s+//g;
240         
241                 #remove any redundant whitespaces at the beginning
242                 s/^\s+//;
244         }
246         @javalist;
251 # Combine all consecutive lines with an identical command line 
252 # to a signle line with a count at the end
254 sub checkSameLine {
255         my @input  = @_;
256         my @output;
257         my $prevline= "";
258         my $prevcount = 0;
260         foreach my $a (@input) {
261                 if ( $prevline eq $a) {
262                         ++$prevcount;
263                 } else {
264                         push @output, $prevline . " " . ($prevcount + 1);
265                         $prevcount = 0;
266                 }
267                 $prevline = $a;
268         }
270         #don't forget the last item!
271         if ( $prevcount > 0 ) {
272                 push @output, $prevline . " " . ($prevcount + 1);
273         }
275         @output;
278 #======= end check_javaproc =====