/[nagios-plugins-perl]/trunk/plugins/check_tomcat.pl
ViewVC logotype

Contents of /trunk/plugins/check_tomcat.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 142 - (show annotations) (download)
Thu Jan 10 12:49:12 2013 UTC (7 years, 10 months ago) by racvision
File MIME type: text/plain
File size: 12263 byte(s)
Ajout de check_mod_jk.pl et check_tomcat.pl
1 #!/usr/bin/perl
2
3 #############################################################################
4 # #
5 # This script was initially developed by Lonely Planet for internal use #
6 # and has kindly been made available to the Open Source community for #
7 # redistribution and further development under the terms of the #
8 # GNU General Public License v3: http://www.gnu.org/licenses/gpl.html #
9 # #
10 #############################################################################
11 # #
12 # This script is supplied 'as-is', in the hope that it will be useful, but #
13 # neither Lonely Planet nor the authors make any warranties or guarantees #
14 # as to its correct operation, including its intended function. #
15 # #
16 # Or in other words: #
17 # Test it yourself, and make sure it works for YOU. #
18 # #
19 #############################################################################
20 # Author: George Hansper e-mail: george@hansper.id.au #
21 #############################################################################
22
23 use strict;
24 use LWP;
25 use LWP::UserAgent;
26 use Getopt::Std;
27 use XML::XPath;
28
29 my %optarg;
30 my $getopt_result;
31
32 my $lwp_user_agent;
33 my $http_request;
34 my $http_response;
35 my $url;
36 my $body;
37
38 my @message;
39 my @message_perf;
40 my $exit = 0;
41 my @exit = qw/OK: WARNING: CRITICAL:/;
42
43 my $rcs_id = '$Id: check_tomcat.pl,v 1.3 2011/12/11 04:56:27 george Exp $';
44
45 # Defaults...
46 my $timeout = 10; # Default timeout
47 my $host = 'localhost'; # default host header
48 my $host_ip = 'localhost'; # default IP
49 my $port = 80; # default port
50 my $user = 'nagios'; # default user
51 my $password = 'nagios'; # default password
52 my $uri = '/manager/status?XML=true'; #default URI
53 my $http = 'http';
54 my $connector_arg = undef;
55 my $warn_threads = "25%";
56 my $crit_threads = "10%";
57 # Memory thresholds are tight, because garbage collection kicks in only when memory is low anyway
58 my $warn_memory = "5%";
59 my $crit_memory = "2%";
60
61 my $xpath;
62 my %xpath_checks = (
63 maxThreads => '/status/connector/threadInfo/@maxThreads',
64 currentThreadCount => '/status/connector/threadInfo/@currentThreadCount',
65 currentThreadsBusy => '/status/connector/threadInfo/@currentThreadsBusy',
66 memMax => '/status/jvm/memory/@max',
67 memFree => '/status/jvm/memory/@free',
68 memTotal => '/status/jvm/memory/@total',
69 );
70 # XPath examples...
71 # /status/jvm/memory/@free
72 # /status/connector[attribute::name="http-8080"]/threadInfo/@maxThreads
73 # /status/connector/threadInfo/@* <- returns multiple nodes
74
75 my %xpath_check_results;
76
77 sub VERSION_MESSAGE() {
78 print "$^X\n$rcs_id\n";
79 }
80
81 sub HELP_MESSAGE() {
82 print <<EOF;
83 Usage:
84 $0 [-v] [-H hostname] [-I ip_address] [-p port] [-S] [-t time_out] [-l user] [-a password] [-w /xpath[=value]...] [-c /xpath[=value]...]
85
86 -H ... Hostname and Host: header (default: $host)
87 -I ... IP address (default: none)
88 -p ... Port number (default: ${port})
89 -S ... Use SSL connection
90 -v ... verbose messages
91 -t ... Seconds before connection times out. (default: $timeout)
92 -l ... username for authentication (default: $user)
93 -a ... password for authentication (default: embedded in script)
94 -u ... uri path, (default: $uri)
95 -n ... connector name, regular expression
96 eg 'ajp-bio-8009' or 'http-8080' or '^http-'.
97 default is to check: .*-port_number\$
98 Note: leading/trailing quotes and spaces are trimmed from the connector name for matching.
99 -w ... warning thresholds for threads,memory (memory in MB)
100 eg 20,50 or 10%,25% default is $warn_threads,$warn_memory
101 -c ... critical thresholds for threads,memory (memory in MB)
102 eg 10,20 or 5%,10%, default is $crit_threads,$crit_memory
103 Example:
104 $0 -H app01.signon.devint.lpo -p 8080 -t 5 -l nagios -a apples -u '/manager/status?XML=true'
105 $0 -H app01.signon.devint.lpo -p 8080 -w 10%,50 -c 5%,10
106 $0 -H app01.signon.devint.lpo -p 8080 -w 10%,50 -c 5%,10 -l admin -a admin -n .
107
108 Notes:
109 The -I parameters connects to a alternate hostname/IP, using the Host header from the -H parameter
110
111 To check ALL connectors mentioned in the status XML file, use '-n .'
112 '.' is a regular expression matching all connector names.
113
114 EOF
115 }
116
117 $getopt_result = getopts('hvSH:I:p:w:c:t:l:a:u:n:', \%optarg) ;
118
119 # Any invalid options?
120 if ( $getopt_result == 0 ) {
121 HELP_MESSAGE();
122 exit 1;
123 }
124 if ( $optarg{h} ) {
125 HELP_MESSAGE();
126 exit 0;
127 }
128
129 sub printv($) {
130 if ( $optarg{v} ) {
131 chomp( $_[-1] );
132 print STDERR @_;
133 print STDERR "\n";
134 }
135 }
136
137 if ( defined($optarg{t}) ) {
138 $timeout = $optarg{t};
139 }
140
141 # Is port number numeric?
142 if ( defined($optarg{p}) ) {
143 $port = $optarg{p};
144 if ( $port !~ /^[0-9][0-9]*$/ ) {
145 print STDERR <<EOF;
146 Port must be a decimal number, eg "-p 8080"
147 EOF
148 exit 1;
149 }
150 }
151
152 if ( defined($optarg{H}) ) {
153 $host = $optarg{H};
154 $host_ip = $host;
155 }
156
157 if ( defined($optarg{I}) ) {
158 $host_ip = $optarg{I};
159 if ( ! defined($optarg{H}) ) {
160 $host = $host_ip;
161 }
162 }
163
164 if ( defined($optarg{l}) ) {
165 $user = $optarg{l};
166 }
167
168 if ( defined($optarg{a}) ) {
169 $password = $optarg{a};
170 }
171
172 if ( defined($optarg{u}) ) {
173 $uri = $optarg{u};
174 }
175
176 if ( defined($optarg{S}) ) {
177 $http = 'https';
178 }
179
180 if ( defined($optarg{c}) ) {
181 my @threshold = split(/,/,$optarg{c});
182 if ( $threshold[0] ne "" ) {
183 $crit_threads = $threshold[0];
184 }
185 if ( $threshold[1] ne "" ) {
186 $crit_memory = $threshold[1];
187 }
188 }
189
190 if ( defined($optarg{n}) ) {
191 $connector_arg = $optarg{n};
192 } else {
193 $connector_arg = "-$port\$";
194 }
195
196 if ( defined($optarg{w}) ) {
197 my @threshold = split(/,/,$optarg{w});
198 if ( $threshold[0] ne "" ) {
199 $warn_threads = $threshold[0];
200 }
201 if ( $threshold[1] ne "" ) {
202 $warn_memory = $threshold[1];
203 }
204 }
205
206 *LWP::UserAgent::get_basic_credentials = sub {
207 return ( $user, $password );
208 };
209
210 # print $xpath_checks[0], "\n";
211
212 printv "Connecting to $host:${port}\n";
213
214 $lwp_user_agent = LWP::UserAgent->new;
215 $lwp_user_agent->timeout($timeout);
216 if ( $port == 80 || $port == 443 || $port eq "" ) {
217 $lwp_user_agent->default_header('Host' => $host);
218 } else {
219 $lwp_user_agent->default_header('Host' => "$host:$port");
220 }
221
222 $url = "$http://${host_ip}:${port}$uri";
223 $http_request = HTTP::Request->new(GET => $url);
224
225 printv "--------------- GET $url";
226 printv $lwp_user_agent->default_headers->as_string . $http_request->headers_as_string;
227
228 $http_response = $lwp_user_agent->request($http_request);
229 printv "---------------\n" . $http_response->protocol . " " . $http_response->status_line;
230 printv $http_response->headers_as_string;
231 printv "Content has " . length($http_response->content) . " bytes \n";
232
233 if ($http_response->is_success) {
234 $body = $http_response->content;
235 my $xpath = XML::XPath->new( xml => $body );
236 my $xpath_check;
237 # Parse the data out of the XML...
238 foreach $xpath_check ( keys %xpath_checks ) {
239 #print keys(%{$xpath_check}) , "\n";
240 my $path = $xpath_checks{$xpath_check};
241 $path =~ s{\$port}{$port};
242 #print $xpath_check->{xpath} , "\n";
243 my $nodeset = $xpath->find($path);
244 if ( $nodeset->get_nodelist == 0 ) {
245 push @message, "$path not found";
246 $exit |= 2;
247 push @message_perf, "$path=not_found";
248 next;
249 }
250 foreach my $node ($nodeset->get_nodelist) {
251 my $connector_name = $node->getParentNode()->getParentNode()->getAttribute("name");
252 $connector_name =~ s/^["'\s]+//;
253 $connector_name =~ s/["'\s]+$//;
254 my $value = $node->string_value();
255 if ( $value =~ /^"?([0-9.]+)"?$/ ) {
256 $value = $1;
257 } else {
258 push @message, "$path is not numeric";
259 $exit |= 2;
260 push @message_perf, "$path=not_numeric";
261 next;
262 }
263 if ( $xpath_check =~ /^mem/ ) {
264 # This is the .../memory/.. xpath, just store the value in the hash
265 $xpath_check_results{$xpath_check} = $value;
266 } elsif ( $connector_name =~ /${connector_arg}/ && $connector_name ne "" ) {
267 # This is a .../threadInfo/... xpath, put the result into a hash (key is connector_name)
268 $xpath_check_results{$xpath_check}{$connector_name} = $value;
269 }
270 }
271 }
272 # Now apply the logic and check the results
273 #----------------------------------------------
274 # Check memory
275 #----------------------------------------------
276 my $jvm_mem_available = $xpath_check_results{memFree} + $xpath_check_results{memMax} - $xpath_check_results{memTotal};
277 printv(sprintf("free=%d max=%d total=%d",$xpath_check_results{memFree}/1024, $xpath_check_results{memMax}/1024, $xpath_check_results{memTotal}/1024));
278 if ( $warn_memory =~ /(.*)%$/ ) {
279 $warn_memory = int($1 * $xpath_check_results{memMax} / 100);
280 } else {
281 # Convert to bytes
282 $warn_memory =int($warn_memory * 1024 * 1024);
283 }
284 printv("warning at $warn_memory bytes (". ( $warn_memory / 1024 /1024 )."MB) free, max=$xpath_check_results{memMax}");
285
286 if ( $crit_memory =~ /(.*)%$/ ) {
287 $crit_memory = int($1 * $xpath_check_results{memMax} / 100);
288 } else {
289 # Convert to bytes
290 $crit_memory = int($crit_memory * 1024 * 1024);
291 }
292 printv("critical at $crit_memory bytes (". ( $crit_memory / 1024 /1024 )."MB) free, max=$xpath_check_results{memMax}");
293
294 if ( $jvm_mem_available <= $crit_memory ) {
295 $exit |= 2;
296 push @message, sprintf("Memory critical <%d MB,",$crit_memory/1024/1024);
297 } elsif ( $jvm_mem_available <= $warn_memory ) {
298 $exit |= 1;
299 push @message, sprintf("Memory low <%d MB,",$warn_memory/1024/1024);
300 }
301 push @message, sprintf("memory in use %d MB (%d MB);",
302 ( $xpath_check_results{memMax} - $jvm_mem_available ) / ( 1024 * 1024),
303 $xpath_check_results{memMax} / ( 1024 * 1024)
304 );
305 push @message_perf, "used=".( $xpath_check_results{memMax} - $jvm_mem_available ) . " free=$jvm_mem_available max=$xpath_check_results{memMax}";
306
307 #----------------------------------------------
308 # Check threads
309 #----------------------------------------------
310 my $name;
311 foreach $name ( keys( %{$xpath_check_results{currentThreadsBusy}} ) ) {
312
313 if ( $warn_threads =~ /(.*)%$/ ) {
314 $warn_threads = int($1 * $xpath_check_results{maxThreads}{$name} / 100);
315 }
316 printv("warning at $warn_threads threads free, max=$xpath_check_results{maxThreads}{$name}");
317
318 if ( $crit_threads =~ /(.*)%$/ ) {
319 $crit_threads = int($1 * $xpath_check_results{maxThreads}{$name} / 100);
320 }
321 printv("critical at $crit_threads threads free, max=$xpath_check_results{maxThreads}{$name}");
322
323 my $threads_available = $xpath_check_results{maxThreads}{$name} - $xpath_check_results{currentThreadsBusy}{$name};
324 if ( $threads_available <= $crit_threads ) {
325 $exit |= 2;
326 push @message, sprintf("Critical: free_threads<%d",$crit_threads);
327 } elsif ( $threads_available <= $warn_threads ) {
328 $exit |= 1;
329 push @message, sprintf("Warning: free_threads<%d",$warn_threads);
330 }
331 push @message, sprintf("threads[$name]=%d(%d);",
332 $xpath_check_results{currentThreadsBusy}{$name},
333 $xpath_check_results{maxThreads}{$name}
334 );
335 if ( defined($optarg{n}) ) {
336 push @message_perf, "currentThreadsBusy[$name]=$xpath_check_results{currentThreadsBusy}{$name} currentThreadCount[$name]=$xpath_check_results{currentThreadCount}{$name} maxThreads[$name]=$xpath_check_results{maxThreads}{$name}";
337 } else {
338 # For the sake of backwards-compatability of graphs etc...
339 push @message_perf, "currentThreadsBusy=$xpath_check_results{currentThreadsBusy}{$name} currentThreadCount=$xpath_check_results{currentThreadCount}{$name} maxThreads=$xpath_check_results{maxThreads}{$name}";
340 }
341 }
342 if ( keys(%{$xpath_check_results{currentThreadsBusy}}) == 0 ) {
343 # no matching connectors found - this is not OK.
344 $exit |= 1;
345 push @message, "Warning: No tomcat connectors matched name =~ /$connector_arg/";
346 }
347 } elsif ( $http_response->code == 401 ) {
348 print "WARNING: $url " . $http_response->protocol . " " . $http_response->status_line ."\n";
349 exit 1;
350 } else {
351 print "CRITICAL: $url " . $http_response->protocol . " " . $http_response->status_line ."\n";
352 exit 2;
353 }
354
355 if ( $exit == 3 ) {
356 $exit = 2;
357 }
358
359 print "$exit[$exit] ". join(" ",@message) . "|". join(" ",@message_perf) . "\n";
360 exit $exit;

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.8