/[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 135 - (hide annotations) (download)
Fri Mar 12 17:26:57 2010 UTC (10 years, 10 months ago) by racvision
File MIME type: text/plain
File size: 8344 byte(s)
add -U and -P switches to supply username/password credentials
1 racvision 131 #!/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 racvision 135 usage => "Usage: %s [ -v|--verbose ] -u <url> [-t <timeout>] [-U <username>] [-P <password>] [ -c|--critical=<threshold> ] [ -w|--warning=<threshold> ]",
59 racvision 131 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 racvision 135 spec => 'username|U=s',
68     help => _gt('Username for HTTP Auth'),
69     required => 0,
70     );
71     $np->add_arg (
72     spec => 'password|P=s',
73     help => _gt('Password for HTTP Auth'),
74     required => 0,
75     );
76     $np->add_arg (
77 racvision 131 spec => 'w=f',
78     help => _gt('Warning request time threshold (in seconds)'),
79     default => 2,
80     label => 'FLOAT'
81     );
82     $np->add_arg (
83     spec => 'c=f',
84     help => _gt('Critical request time threshold (in seconds)'),
85     default => 10,
86     label => 'FLOAT'
87     );
88     $np->add_arg (
89     spec => 'url|u=s',
90     help => _gt('URL of the HAProxy csv statistics page.'),
91     required => 1,
92     );
93    
94    
95     $np->getopts;
96    
97     $DEBUG = $np->opts->get('debug');
98     my $verbose = $np->opts->get('verbose');
99 racvision 135 my $username = $np->opts->get('username');
100     my $password = $np->opts->get('password');
101 racvision 131
102     # Thresholds :
103     # time
104     my $warn_t = $np->opts->get('w');
105     my $crit_t = $np->opts->get('c');
106    
107     my $url = $np->opts->get('url');
108    
109    
110     # Create a LWP user agent object:
111     my $ua = new LWP::UserAgent(
112     'env_proxy' => 0,
113     'timeout' => $TIMEOUT,
114     );
115     $ua->agent(basename($0));
116    
117     # Workaround for LWP bug :
118     $ua->parse_head(0);
119    
120     if ( defined($ENV{'http_proxy'}) ) {
121     # Normal http proxy :
122     $ua->proxy(['http'], $ENV{'http_proxy'});
123     # Https must use Crypt::SSLeay https proxy (to use CONNECT method instead of GET)
124     $ENV{'HTTPS_PROXY'} = $ENV{'http_proxy'};
125     }
126    
127     # Build and submit an http request :
128     my $request = HTTP::Request->new('GET', $url);
129 racvision 135 # Authenticate if username and password are supplied
130     if ( defined($username) && defined($password) ) {
131     $request->authorization_basic($username, $password);
132     }
133 racvision 131 my $timer = time();
134     my $http_response = $ua->request( $request );
135     $timer = time()-$timer;
136    
137    
138    
139     my $status = $np->check_threshold(
140     'check' => $timer,
141     'warning' => $warn_t,
142     'critical' => $crit_t,
143     );
144    
145     $np->add_perfdata(
146     'label' => 't',
147     'value' => sprintf('%.6f',$timer),
148     'min' => 0,
149     'uom' => 's',
150     'threshold' => $np->threshold()
151     );
152    
153     if ( $status > OK ) {
154     $np->add_message($status, sprintf(_gt("Response time degraded: %.6fs !"),$timer) );
155     }
156    
157    
158     my $message = 'msg';
159    
160    
161     if ( $http_response->is_error() ) {
162     my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
163     $np->add_message(CRITICAL, _gt("HTTP error: ").$err );
164    
165     } elsif ( ! $http_response->is_success() ) {
166     my $err = $http_response->code." ".status_message($http_response->code)." (".$http_response->message.")";
167     $np->add_message(CRITICAL, _gt("Internal error: ").$err );
168     }
169    
170    
171     ($status, $message) = $np->check_messages();
172    
173     if ( $http_response->is_success() ) {
174    
175     # Get xml content ...
176     my $stats = $http_response->content;
177     if ($DEBUG) {
178     print "------------------===http output===------------------\n$stats\n-----------------------------------------------------\n";
179     print "t=".$timer."s\n";
180     };
181    
182     my @fields = ();
183     my @rows = split(/\n/,$stats);
184     if ( $rows[0] =~ /#\ \w+/ ) {
185     $rows[0] =~ s/#\ //;
186     @fields = split(/\,/,$rows[0]);
187     } else {
188     $np->nagios_exit(UNKNOWN, _gt("Can't find csv header !") );
189     }
190    
191     my %stats = ();
192     for ( my $y = 1; $y < $#rows; $y++ ) {
193     my @values = split(/\,/,$rows[$y]);
194     if ( !defined($stats{$values[0]}) ) {
195     $stats{$values[0]} = {};
196     }
197     if ( !defined($stats{$values[0]}{$values[1]}) ) {
198     $stats{$values[0]}{$values[1]} = {};
199     }
200 racvision 135 for ( my $x = 2,; $x <= $#values; $x++ ) {
201 racvision 131 # $stats{pxname}{svname}{valuename}
202     $stats{$values[0]}{$values[1]}{$fields[$x]} = $values[$x];
203     }
204     }
205     # print Dumper(\%stats);
206     my %stats2 = ();
207     my $okMsg = '';
208     foreach my $pxname ( keys(%stats) ) {
209     $stats2{$pxname} = {
210     'act' => 0,
211     'acttot' => 0,
212     'bck' => 0,
213     'bcktot' => 0,
214     'scur' => 0,
215     'slim' => 0,
216     };
217     foreach my $svname ( keys(%{$stats{$pxname}}) ) {
218     if ( $stats{$pxname}{$svname}{'type'} eq '2' ) {
219     my $svstatus = $stats{$pxname}{$svname}{'status'} eq 'UP';
220     my $active = $stats{$pxname}{$svname}{'act'} eq '1';
221     my $activeDescr = $active ? _gt("Active service") :_gt("Backup service") ;
222     if ( $stats{$pxname}{$svname}{'status'} eq 'UP' ) {
223     logD( sprintf(_gt("%s '%s' is up on '%s' proxy."),$activeDescr,$svname,$pxname) );
224     } elsif ( $stats{$pxname}{$svname}{'status'} eq 'DOWN' ) {
225     $np->add_message(CRITICAL, sprintf(_gt("%s '%s' is DOWN on '%s' proxy !"),$activeDescr,$svname,$pxname) );
226     }
227     if ( $stats{$pxname}{$svname}{'act'} eq '1' ) {
228     $stats2{$pxname}{'acttot'}++;
229     $stats2{$pxname}{'act'} += $svstatus;
230    
231     } elsif ($stats{$pxname}{$svname}{'bck'} eq '1') {
232     $stats2{$pxname}{'bcktot'}++;
233     $stats2{$pxname}{'bck'} += $svstatus;
234     }
235     $stats2{$pxname}{'scur'} += $stats{$pxname}{$svname}{'scur'};
236     logD( "Current sessions : ".$stats{$pxname}{$svname}{'scur'} );
237    
238     } elsif ( $stats{$pxname}{$svname}{'type'} eq '0' ) {
239     $stats2{$pxname}{'slim'} = $stats{$pxname}{$svname}{'slim'};
240     }
241     }
242     if ( $stats2{$pxname}{'acttot'} > 0 ) {
243     $okMsg .= ' '.$pxname.' (Active: '.$stats2{$pxname}{'act'}.'/'.$stats2{$pxname}{'acttot'};
244     if ( $stats2{$pxname}{'bcktot'} > 0 ) {
245     $okMsg .= ' , Backup: '.$stats2{$pxname}{'bck'}.'/'.$stats2{$pxname}{'bcktot'};
246     }
247     $okMsg .= ')';
248     $np->add_perfdata(
249     'label' => 'sess_'.$pxname,
250     'value' => $stats2{$pxname}{'scur'},
251     'min' => 0,
252     'uom' => 'sessions',
253     'max' => $stats2{$pxname}{'slim'},
254     );
255     }
256     }
257    
258     # print Dumper(\%stats2);
259     ($status, $message) = $np->check_messages('join' => ' ');
260    
261     if ( $status == OK ) {
262     $message = $okMsg;
263    
264     }
265    
266     }
267     # if ( $verbose ) {
268     # ($status, $message) = $np->check_messages('join' => '<br/>','join_all' => '<br/>');
269     # } else {
270     # ($status, $message) = $np->check_messages('join' => '<br/>');
271     # }
272    
273    
274     $np->nagios_exit($status, $message );
275    
276    
277     sub logD {
278     print STDERR 'DEBUG: '.$_[0]."\n" if ($DEBUG);
279     }
280     sub logW {
281     print STDERR 'WARNING: '.$_[0]."\n" if ($DEBUG);
282     }
283     # Gettext wrapper
284     sub _gt {
285     return gettext($_[0]);
286     }
287    
288    
289     __END__
290    
291     =head1 NAME
292    
293     This Nagios plugins check the statistics url provided by HAProxy (http://haproxy.1wt.eu/).
294    
295    
296     =head1 NAGIOS CONGIGURATIONS
297    
298     In F<checkcommands.cfg> you have to add :
299    
300     define command {
301     command_name check_haproxy
302     command_line $USER1$/check_haproxy.pl -u $ARG1$
303     }
304    
305    
306     In F<services.cfg> you just have to add something like :
307    
308     define service {
309     host_name haproxy.exemple.org
310     normal_check_interval 10
311     retry_check_interval 5
312     contact_groups linux-admins
313     service_description HAProxy
314     check_command check_haproxy!http://haproxy.exemple.org/haproxy?stats;csv
315     }
316    
317     =head1 AUTHOR
318    
319     St├ęphane Urbanovski <stephane.urbanovski@ac-nancy-metz.fr>
320    
321     =cut

Properties

Name Value
svn:executable *

  ViewVC Help
Powered by ViewVC 1.1.8