check_javaproc.pl 6.5 KB

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