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

Contents of /trunk/plugins/check_haproxy.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 131 - (show annotations) (download)
Fri Feb 26 11:22:11 2010 UTC (10 years, 10 months ago) by racvision
File MIME type: text/plain
File size: 7859 byte(s)
add a check for HAProxy and MS SQL Server
1 #!/usr/bin/perl -w
2 #
3 # Copyright (c) 2010 St├ęphane Urbanovski <stephane.urbanovski@ac-nancy-metz.fr>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty
12 # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # you should have received a copy of the GNU General Public License
16 # along with this program (or with Nagios); if not, write to the
17 # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 # Boston, MA 02111-1307, USA
19 #
20 # $Id: $
21
22 use strict; # should never be differently :-)
23 use warnings;
24
25
26 use Locale::gettext;
27 use File::Basename; # get basename()
28
29 use POSIX qw(setlocale);
30 use Time::HiRes qw(time); # get microtime
31 use POSIX qw(mktime);
32
33 use Nagios::Plugin ;
34
35 use LWP::UserAgent; # http client
36 use HTTP::Request; # used by LWP::UserAgent
37 use HTTP::Status; # to get http err msg
38
39
40 use Data::Dumper;
41
42
43 my $PROGNAME = basename($0);
44 '$Revision: 1.0 $' =~ /^.*(\d+\.\d+) \$$/; # Use The Revision from RCS/CVS/SVN
45 my $VERSION = $1;
46
47 my $DEBUG = 0;
48 my $TIMEOUT = 9;
49
50 # i18n :
51 setlocale(LC_MESSAGES, '');
52 textdomain('nagios-plugins-perl');
53
54
55 my $np = Nagios::Plugin->new(
56 version => $VERSION,
57 blurb => _gt('Plugin to check HAProxy stats url'),
58 usage => "Usage: %s [ -v|--verbose ] -u <url> [-t <timeout>] [ -c|--critical=<threshold> ] [ -w|--warning=<threshold> ]",
59 timeout => $TIMEOUT+1
60 );
61 $np->add_arg (
62 spec => 'debug|d',
63 help => _gt('Debug level'),
64 default => 0,
65 );
66 $np->add_arg (
67 spec => 'w=f',
68 help => _gt('Warning request time threshold (in seconds)'),
69 default => 2,
70 label => 'FLOAT'
71 );
72 $np->add_arg (
73 spec => 'c=f',
74 help => _gt('Critical request time threshold (in seconds)'),
75 default => 10,
76 label => 'FLOAT'
77 );
78 $np->add_arg (
79 spec => 'url|u=s',
80 help => _gt('URL of the HAProxy csv statistics page.'),
81 required => 1,
82 );
83
84
85 $np->getopts;
86
87 $DEBUG = $np->opts->get('debug');
88 my $verbose = $np->opts->get('verbose');
89
90 # Thresholds :
91 # time
92 my $warn_t = $np->opts->get('w');
93 my $crit_t = $np->opts->get('c');
94
95 my $url = $np->opts->get('url');
96
97
98 # Create a LWP user agent object:
99 my $ua = new LWP::UserAgent(
100 'env_proxy' => 0,
101 'timeout' => $TIMEOUT,
102 );
103 $ua->agent(basename($0));
104
105 # Workaround for LWP bug :
106 $ua->parse_head(0);
107
108 if ( defined($ENV{'http_proxy'}) ) {
109 # Normal http proxy :
110 $ua->proxy(['http'], $ENV{'http_proxy'});
111 # Https must use Crypt::SSLeay https proxy (to use CONNECT method instead of GET)
112 $ENV{'HTTPS_PROXY'} = $ENV{'http_proxy'};
113 }
114
115 # Build and submit an http request :
116 my $request = HTTP::Request->new('GET', $url);
117 my $timer = time();
118 my $http_response = $ua->request( $request );
119 $timer = time()-$timer;
120
121
122
123 my $status = $np->check_threshold(
124 'check' => $timer,
125 'warning' => $warn_t,
126 'critical' => $crit_t,
127 );
128
129 $np->add_perfdata(
130 'label' => 't',
131 'value' => sprintf('%.6f',$timer),
132 'min' => 0,
133 'uom' => 's',
134 'threshold' => $np->threshold()
135 );
136
137 if ( $status > OK ) {
138 $np->add_message($status, sprintf(_gt("Response time degraded: %.6fs !"),$timer) );
139 }
140
141
142 my $message = 'msg';
143
144
145 if ( $http_response->is_error() ) {
146 my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
147 $np->add_message(CRITICAL, _gt("HTTP error: ").$err );
148
149 } elsif ( ! $http_response->is_success() ) {
150 my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
151 $np->add_message(CRITICAL, _gt("Internal error: ").$err );
152 }
153
154
155 ($status, $message) = $np->check_messages();
156
157 if ( $http_response->is_success() ) {
158
159 # Get xml content ...
160 my $stats = $http_response->content;
161 if ($DEBUG) {
162 print "------------------===http output===------------------\n$stats\n-----------------------------------------------------\n";
163 print "t=".$timer."s\n";
164 };
165
166 my @fields = ();
167 my @rows = split(/\n/,$stats);
168 if ( $rows[0] =~ /#\ \w+/ ) {
169 $rows[0] =~ s/#\ //;
170 @fields = split(/\,/,$rows[0]);
171 } else {
172 $np->nagios_exit(UNKNOWN, _gt("Can't find csv header !") );
173 }
174
175 my %stats = ();
176 for ( my $y = 1; $y < $#rows; $y++ ) {
177 my @values = split(/\,/,$rows[$y]);
178 if ( !defined($stats{$values[0]}) ) {
179 $stats{$values[0]} = {};
180 }
181 if ( !defined($stats{$values[0]}{$values[1]}) ) {
182 $stats{$values[0]}{$values[1]} = {};
183 }
184 for ( my $x = 2,; $x < $#values; $x++ ) {
185 # $stats{pxname}{svname}{valuename}
186 $stats{$values[0]}{$values[1]}{$fields[$x]} = $values[$x];
187 }
188 }
189 # print Dumper(\%stats);
190 my %stats2 = ();
191 my $okMsg = '';
192 foreach my $pxname ( keys(%stats) ) {
193 $stats2{$pxname} = {
194 'act' => 0,
195 'acttot' => 0,
196 'bck' => 0,
197 'bcktot' => 0,
198 'scur' => 0,
199 'slim' => 0,
200 };
201 foreach my $svname ( keys(%{$stats{$pxname}}) ) {
202 if ( $stats{$pxname}{$svname}{'type'} eq '2' ) {
203 my $svstatus = $stats{$pxname}{$svname}{'status'} eq 'UP';
204 my $active = $stats{$pxname}{$svname}{'act'} eq '1';
205 my $activeDescr = $active ? _gt("Active service") :_gt("Backup service") ;
206 if ( $stats{$pxname}{$svname}{'status'} eq 'UP' ) {
207 logD( sprintf(_gt("%s '%s' is up on '%s' proxy."),$activeDescr,$svname,$pxname) );
208 } elsif ( $stats{$pxname}{$svname}{'status'} eq 'DOWN' ) {
209 $np->add_message(CRITICAL, sprintf(_gt("%s '%s' is DOWN on '%s' proxy !"),$activeDescr,$svname,$pxname) );
210 }
211 if ( $stats{$pxname}{$svname}{'act'} eq '1' ) {
212 $stats2{$pxname}{'acttot'}++;
213 $stats2{$pxname}{'act'} += $svstatus;
214
215 } elsif ($stats{$pxname}{$svname}{'bck'} eq '1') {
216 $stats2{$pxname}{'bcktot'}++;
217 $stats2{$pxname}{'bck'} += $svstatus;
218 }
219 $stats2{$pxname}{'scur'} += $stats{$pxname}{$svname}{'scur'};
220 logD( "Current sessions : ".$stats{$pxname}{$svname}{'scur'} );
221
222 } elsif ( $stats{$pxname}{$svname}{'type'} eq '0' ) {
223 $stats2{$pxname}{'slim'} = $stats{$pxname}{$svname}{'slim'};
224 }
225 }
226 if ( $stats2{$pxname}{'acttot'} > 0 ) {
227 $okMsg .= ' '.$pxname.' (Active: '.$stats2{$pxname}{'act'}.'/'.$stats2{$pxname}{'acttot'};
228 if ( $stats2{$pxname}{'bcktot'} > 0 ) {
229 $okMsg .= ' , Backup: '.$stats2{$pxname}{'bck'}.'/'.$stats2{$pxname}{'bcktot'};
230 }
231 $okMsg .= ')';
232 $np->add_perfdata(
233 'label' => 'sess_'.$pxname,
234 'value' => $stats2{$pxname}{'scur'},
235 'min' => 0,
236 'uom' => 'sessions',
237 'max' => $stats2{$pxname}{'slim'},
238 );
239 }
240 }
241
242 # print Dumper(\%stats2);
243 ($status, $message) = $np->check_messages('join' => ' ');
244
245 if ( $status == OK ) {
246 $message = $okMsg;
247
248 }
249
250 }
251 # if ( $verbose ) {
252 # ($status, $message) = $np->check_messages('join' => '<br/>','join_all' => '<br/>');
253 # } else {
254 # ($status, $message) = $np->check_messages('join' => '<br/>');
255 # }
256
257
258 $np->nagios_exit($status, $message );
259
260
261 sub logD {
262 print STDERR 'DEBUG: '.$_[0]."\n" if ($DEBUG);
263 }
264 sub logW {
265 print STDERR 'WARNING: '.$_[0]."\n" if ($DEBUG);
266 }
267 # Gettext wrapper
268 sub _gt {
269 return gettext($_[0]);
270 }
271
272
273 __END__
274
275 =head1 NAME
276
277 This Nagios plugins check the statistics url provided by HAProxy (http://haproxy.1wt.eu/).
278
279
280 =head1 NAGIOS CONGIGURATIONS
281
282 In F<checkcommands.cfg> you have to add :
283
284 define command {
285 command_name check_haproxy
286 command_line $USER1$/check_haproxy.pl -u $ARG1$
287 }
288
289
290 In F<services.cfg> you just have to add something like :
291
292 define service {
293 host_name haproxy.exemple.org
294 normal_check_interval 10
295 retry_check_interval 5
296 contact_groups linux-admins
297 service_description HAProxy
298 check_command check_haproxy!http://haproxy.exemple.org/haproxy?stats;csv
299 }
300
301 =head1 AUTHOR
302
303 St├ęphane Urbanovski <stephane.urbanovski@ac-nancy-metz.fr>
304
305 =cut

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.8