/[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 - (hide 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 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     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