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

Contents of /trunk/plugins/check_mod_jk.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 155 - (show annotations) (download)
Thu Sep 25 09:22:14 2014 UTC (6 years, 2 months ago) by racvision
File MIME type: text/plain
File size: 9591 byte(s)
Fix error reporting when there is no member attached to a worker
1 #!/usr/bin/perl -w
2 #
3 # Copyright (c) 2012-2014 St├ęphane Urbanovski <stephane.urbanovski@ac-nancy-metz.fr>
4 # (some code took from nagiosexchange by ??? )
5 #
6 # This program is free software; you can redistribute it and/or
7 # modify it under the terms of the GNU General Public License
8 # as published by the Free Software Foundation; either version 2
9 # of the License, or (at your option) any later version.
10 #
11 # This program is distributed in the hope that it will be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty
13 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 # GNU General Public License for more details.
15 #
16 # you should have received a copy of the GNU General Public License
17 # along with this program (or with Nagios); if not, write to the
18 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 # Boston, MA 02111-1307, USA
20 #
21 ## check_jk_status:
22 ##
23 ## Check the status for mod_jk's loadbalancers via XML download from status
24 ## URL.
25
26 use strict;
27 use warnings;
28
29 use Nagios::Plugin ;
30
31 use Locale::gettext;
32 use File::Basename; # get basename()
33 use LWP::UserAgent;
34 use HTTP::Request;
35 use HTTP::Status;
36 use XML::Simple;
37 use Data::Dumper;
38 use Getopt::Long;
39
40 my $VERSION = '1.1';
41 my $TIMEOUT = 9;
42 my $DEBUG = 0;
43
44
45 my $np = Nagios::Plugin->new(
46 version => $VERSION,
47 blurb => _gt('Plugin to check mod_jk status url'),
48 usage => "Usage: %s [ -v|--verbose ] -u <url> [-t <timeout>] [ -c|--critical=<threshold> ] [ -w|--warning=<threshold> ] [ -b|--balancer <balancer> ]",
49 timeout => $TIMEOUT+1
50 );
51 $np->add_arg (
52 spec => 'debug|d',
53 help => _gt('Debug level'),
54 default => 0,
55 );
56 $np->add_arg (
57 spec => 'w=f',
58 help => _gt('Warning request time threshold (in seconds)'),
59 default => 2,
60 label => 'FLOAT'
61 );
62 $np->add_arg (
63 spec => 'c=f',
64 help => _gt('Critical request time threshold (in seconds)'),
65 default => 10,
66 label => 'FLOAT'
67 );
68 $np->add_arg (
69 spec => 'url|u=s',
70 help => _gt('URL of the mod_jk status page.'),
71 required => 1,
72 );
73 $np->add_arg (
74 spec => 'balancer|b=s',
75 help => _gt('balancer name.'),
76 required => 0,
77 );
78
79 $np->getopts;
80
81 $DEBUG = $np->opts->get('debug');
82 my $verbose = $np->opts->verbose;
83
84 # Thresholds :
85 # time
86 my $warn_t = $np->opts->get('w');
87 my $crit_t = $np->opts->get('c');
88
89 my $url = $np->opts->get('url');
90 my $reqbalancer = $np->opts->get('balancer');
91
92
93
94 # Create a LWP user agent object:
95 my $ua = new LWP::UserAgent(
96 'env_proxy' => 0,
97 'timeout' => $TIMEOUT,
98 );
99 $ua->agent(basename($0));
100
101 # Workaround for LWP bug :
102 $ua->parse_head(0);
103
104 if ( defined($ENV{'http_proxy'}) ) {
105 # Normal http proxy :
106 $ua->proxy(['http'], $ENV{'http_proxy'});
107 # Https must use Crypt::SSLeay https proxy (to use CONNECT method instead of GET)
108 $ENV{'HTTPS_PROXY'} = $ENV{'http_proxy'};
109 }
110
111 # Build and submit an http request :
112 $url .= '?mime=xml&opt=2';
113 if ( $reqbalancer ) {
114 $url .= '&cmd=show&w='.$reqbalancer;
115 }
116
117 my $request = HTTP::Request->new('GET', $url);
118 my $timer = time();
119 logD("GET ".$request->uri());
120 my $http_response = $ua->request( $request );
121 $timer = time()-$timer;
122
123
124
125 my $status = $np->check_threshold(
126 'check' => $timer,
127 'warning' => $warn_t,
128 'critical' => $crit_t,
129 );
130
131 $np->add_perfdata(
132 'label' => 't',
133 'value' => sprintf('%.6f',$timer),
134 'min' => 0,
135 'uom' => 's',
136 'threshold' => $np->threshold()
137 );
138
139 if ( $status > OK ) {
140 $np->add_message($status, sprintf(_gt("Response time degraded: %.6fs !"),$timer) );
141 }
142
143
144 my $message = 'msg';
145
146
147 if ( $http_response->is_error() ) {
148 my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
149 $np->add_message(CRITICAL, _gt("HTTP error: ").$err );
150
151 } elsif ( ! $http_response->is_success() ) {
152 my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
153 $np->add_message(CRITICAL, _gt("Internal error: ").$err );
154 }
155
156
157
158
159
160 if ( $http_response->is_success() ) {
161
162 # Get xml content ...
163 my $xml = $http_response->content;
164 if ($DEBUG) {
165 print "------------------===http output===------------------\n$xml\n-----------------------------------------------------\n";
166 print "t=".$timer."s\n";
167 };
168
169 ### Convert XML to hash
170
171 my $statusData = eval { XMLin($xml, forcearray => ['jk:member']) };
172 if ($@) {
173 $np->nagios_exit(CRITICAL, _gt("Unparsable XML in jkstatus response: ").$@ );
174 }
175 # TODO: handle supplied balancer name
176
177
178 # print Dumper($statusData);
179
180 if ( defined($statusData->{'jk:result'}->{'type'}) ) {
181 if ( $statusData->{'jk:result'}->{'type'} ne 'OK' ) {
182 if ( defined($statusData->{'jk:result'}->{'message'}) ) {
183 $np->nagios_exit(CRITICAL, sprintf(_gt("Jk result error : %s"),$statusData->{'jk:result'}->{'message'}) );
184 } else {
185 $np->nagios_exit(CRITICAL, _gt("Unknown jk result error") );
186 }
187 }
188 }
189
190 my $jkVersion = '';
191 if ( defined($statusData->{'jk:software'}->{'web_server'}) ) {
192 $jkVersion = $statusData->{'jk:software'}->{'web_server'};
193 }
194 if ( defined($statusData->{'jk:software'}->{'jk_version'}) ) {
195 $jkVersion .= ' - '.$statusData->{'jk:software'}->{'jk_version'};
196 }
197
198
199 my @balancers = keys( %{$statusData->{'jk:balancers'}->{'jk:balancer'}} );
200
201 if ( defined($reqbalancer) ) {
202
203 my $balancer = $reqbalancer;
204 my @good_members = ();
205 my @bad_members = ();
206
207 ### Get number of members
208 my $member_count = $statusData->{'jk:balancer'}->{'member_count'} || 0;
209
210 if ( $member_count == 0 ) {
211 $np->nagios_exit(WARNING, sprintf(_gt('No member found for worker \'%s\' !'),$reqbalancer) );
212 }
213
214 foreach my $member ( sort keys %{$statusData->{'jk:balancer'}->{'jk:member'}} ) {
215 my %memberData = %{$statusData->{'jk:balancer'}->{'jk:member'}->{$member}};
216
217
218 $np->add_perfdata(
219 'label' => 'busy['.$member.']',
220 'value' => $memberData{'busy'},
221 'min' => 0,
222 );
223 $np->add_perfdata(
224 'label' => 'errors['.$member.']',
225 'value' => $memberData{'errors'},
226 'min' => 0,
227 );
228
229 if ( defined($memberData{'connected'}) ) {
230 $np->add_perfdata(
231 'label' => 'connected['.$member.']',
232 'value' => $memberData{'connected'},
233 'min' => 0,
234 );
235 }
236 $np->add_perfdata(
237 'label' => 'client_errors['.$member.']',
238 'value' => $memberData{'client_errors'},
239 'min' => 0,
240 );
241 $np->add_perfdata(
242 'label' => 'used['.$member.']',
243 'value' => $memberData{'elected'},
244 'min' => 0,
245 );
246
247
248
249 $np->add_perfdata(
250 'label' => 'read['.$member.']',
251 'value' => $memberData{'read'},
252 'min' => 0,
253 'uom' => 'B'
254 );
255 $np->add_perfdata(
256 'label' => 'transferred['.$member.']',
257 'value' => $memberData{'transferred'},
258 'min' => 0,
259 'uom' => 'B'
260 );
261
262 my $activation = $memberData{'activation'};
263 my $state = $memberData{'state'};
264
265
266 logD( "STATE for $member: $state / $activation");
267 if ( $activation ne 'ACT' ) {
268 push (@bad_members, $member);
269 } elsif ( $activation eq 'ACT' ) {
270 if ( ($state !~ /^OK/) && ($state ne 'N/A') ) {
271 push (@bad_members, $member);
272 } else {
273 push (@good_members, $member);
274 }
275 }
276 }
277
278 logD("balancer = $balancer : ".scalar(@good_members)."/".$member_count);
279
280 ### Calculate possible differences
281 my $bad_count = scalar(@bad_members);
282 my $good_count = $member_count - $bad_count;
283
284 if ($good_count == 0) {
285 $np->add_message(CRITICAL, sprintf(_gt("All members (%d/%d) of '%s' are down"),$bad_count,$member_count,$balancer) );
286
287 } elsif ($member_count != $good_count) {
288 $np->add_message(WARNING, sprintf(_gt("Some members (%d/%d) of '%s' are down : %s"),$bad_count,$member_count,$balancer, join(',',@bad_members)) );
289
290 }
291 $np->add_message(OK, sprintf(_gt("%s - All members (%d/%d) of '%s' are optimal : %s"),$jkVersion,$good_count,$member_count,$balancer,join(',',@good_members)) );
292
293 } else {
294 foreach my $balancer ( @balancers ) {
295
296 my @good_members = ();
297 my @bad_members = ();
298
299 ### Get number of members
300 my $member_count = $statusData->{'jk:balancers'}->{'jk:balancer'}->{$balancer}->{'member_count'};
301
302 ### Check all members
303 foreach my $member ( sort keys %{$statusData->{'jk:balancers'}->{'jk:balancer'}->{$balancer}->{'jk:member'}} ) {
304 ### Check status for every node activation
305
306
307 my %memberData = %{$statusData->{'jk:balancers'}->{'jk:balancer'}->{$balancer}->{'jk:member'}->{$member}};
308 my $activation = $memberData{'activation'};
309 my $state = $memberData{'state'};
310
311
312 logD( "STATE for $member: $state / $activation");
313 if ( $activation ne 'ACT' ) {
314 push (@bad_members, $member);
315 } elsif ( $activation eq 'ACT' ) {
316 if ( ($state !~ /^OK/) && ($state ne 'N/A') ) {
317 push (@bad_members, $member);
318 } else {
319 push (@good_members, $member);
320 }
321 }
322 }
323
324 logD("balancer = $balancer : ".scalar(@good_members)."/".$member_count);
325
326 ### Calculate possible differences
327 my $good_count = $member_count - scalar(@bad_members);
328
329 if ($good_count == 0) {
330 $np->add_message(CRITICAL, sprintf(_gt("All members of '%s' are down"),$balancer) );
331
332 } elsif ($member_count != $good_count) {
333 $np->add_message(WARNING, sprintf(_gt("Some members of '%s' are down : %s"),$balancer, join(',',@bad_members)) );
334
335 }
336 }
337 $np->add_message(OK, sprintf(_gt("%s - All balancers are optimal : %s"),$jkVersion,join(',',@balancers)) );
338 }
339
340
341 }
342
343 ($status, $message) = $np->check_messages();
344 $np->nagios_exit($status, $message );
345
346
347
348 exit 0;
349
350 sub logD {
351 print STDERR 'DEBUG: '.$_[0]."\n" if ($DEBUG);
352 }
353 sub logW {
354 print STDERR 'WARNING: '.$_[0]."\n" if ($DEBUG);
355 }
356 # Gettext wrapper
357 sub _gt {
358 return gettext($_[0]);
359 }

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.8