Thank you Mark!

As a tip, for at least recent Nagios versions you can disable the internal
interpreter for specific scripts only by putting the following line
(including the hash symbol) in the script:
# nagios: -epn

-Kyle

On Wed, Sep 29, 2010 at 1:14 PM, Mark McCorkle
<mark.mccor...@medialets.com>wrote:

> Yep.  I've got one that I am testing to push into production in the next
> few weeks.  It was written by Stéphane Urbanovski and posted online
> somewhere.  It requires 2 interesting things:
>
> 1) mine wouldn't work with the embedded perl interpreter, so I had to turn
> that off in nagios (via enable_embedded_perl=0 in /etc/nagios/nagios.cfg)
> 2) in your command define, if you need to pass the semi-colon, you have to
> both single quote the url and escape the semi-colon as follows:
>
> define command{
>        command_name    check_haproxy
>        command_line    $USER1$/check_haproxy.pl -u
> 'http://username:passw...@$hostaddress$/connstats\;csv\;norefresh'
>        }
>
>
> The script I am testing is as follows.  It may have mild alterations to
> suit my environment -- but I'm sure you can find the original online if you
> google search nagios haproxy plugin.
>
> Hope that helps.
>
> ::Mark McCorkle
> ::Medialets.com
>
>
> #!/usr/bin/perl -w
> #
> # Copyright (c) 2010 Stéphane Urbanovski<
> stephane.urbanov...@ac-nancy-metz.fr>
> #
> # This program is free software; you can redistribute it and/or
> # modify it under the terms of the GNU General Public License
> # as published by the Free Software Foundation; either version 2
> # of the License, or (at your option) any later version.
> #
> # This program is distributed in the hope that it will be useful,
> # but WITHOUT ANY WARRANTY; without even the implied warranty
> # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> # GNU General Public License for more details.
> #
> # you should have received a copy of the GNU General Public License
> # along with this program (or with Nagios);  if not, write to the
> # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
> # Boston, MA 02111-1307, USA
> #
> # $Id: $
>
> use lib "/usr/lib/nagios/plugins";
> use strict;                                     # should never be
> differently :-)
> use warnings;
>
> use Nagios::Plugin;
> use utils qw(%ERRORS &print_revision &support &usage);
>
> use Locale::gettext;
> use File::Basename;                     # get basename()
>
> use POSIX qw(setlocale);
> use Time::HiRes qw(time);                       # get microtime
> use POSIX qw(mktime);
>
>
> use LWP::UserAgent;                     # http client
> use HTTP::Request;                      # used by LWP::UserAgent
> use HTTP::Status;                       # to get http err msg
>
> use Data::Dumper;
>
> my $PROGNAME = basename($0);
> '$Revision: 1.0 $' =~ /^.*(\d+\.\d+) \$$/;  # Use The Revision from
> RCS/CVS/SVN
> my $VERSION = $1;
>
> my $TIMEOUT = 9;
>
> # i18n :
> setlocale(LC_MESSAGES, '');
> textdomain('nagios-plugins-perl');
>
>
> my $np = Nagios::Plugin->new(
>        version => $VERSION,
>        blurb => _gt('Plugin to check HAProxy stats url'),
>        usage => "Usage: %s [ -v|--verbose ]  -u <url> [-t <timeout>] [
> -c|--critical=<threshold> ] [ -w|--warning=<threshold> ]",
>        timeout => $TIMEOUT+1
> );
> $np->add_arg (
>        spec => 'debug|d',
>        help => _gt('Debug level'),
>        default => 0,
> );
> $np->add_arg (
>        spec => 'w=f',
>        help => _gt('Warning request time threshold (in seconds)'),
>        default => 2,
>        label => 'FLOAT'
> );
> $np->add_arg (
>        spec => 'c=f',
>        help => _gt('Critical request time threshold (in seconds)'),
>        default => 10,
>        label => 'FLOAT'
> );
> $np->add_arg (
>        spec => 'url|u=s',
>        help => _gt('URL of the HAProxy csv statistics page.'),
>        required => 1,
> );
>
>
> $np->getopts;
>
> my $verbose = $np->opts->get('verbose');
>
> # Thresholds :
> # time
> my $warn_t = $np->opts->get('w');
> my $crit_t = $np->opts->get('c');
>
> my $url = $np->opts->get('url');
>
>
> # Create a LWP user agent object:
> my $ua = new LWP::UserAgent(
>        'env_proxy' => 0,
>        'timeout' => $TIMEOUT,
>        );
> $ua->agent(basename($0));
>
> # Workaround for LWP bug :
> $ua->parse_head(0);
>
> if ( defined($ENV{'http_proxy'}) ) {
>        # Normal http proxy :
>        $ua->proxy(['http'], $ENV{'http_proxy'});
>        # Https must use Crypt::SSLeay https proxy (to use CONNECT method
> instead of GET)
>        $ENV{'HTTPS_PROXY'} = $ENV{'http_proxy'};
> }
>
> # Build and submit an http request :
> my $request = HTTP::Request->new('GET', $url);
> my $timer = time();
> my $http_response = $ua->request( $request );
> $timer = time()-$timer;
>
>
>
> my $status = $np->check_threshold(
>        'check' => $timer,
>        'warning' => $warn_t,
>        'critical' => $crit_t,
> );
>
> $np->add_perfdata(
>        'label' => 't',
>        'value' => sprintf('%.6f',$timer),
>        'min' => 0,
>        'uom' => 's',
>        'threshold' => $np->threshold()
> );
>
> if ( $status > $ERRORS{'OK'} ) {
>        $np->add_message($status, sprintf(_gt("Response time degraded: %.6fs
> !"),$timer) );
> }
>
>
> my $message = 'msg';
>
>
> if ( $http_response->is_error() ) {
>        my $err = $http_response->code."
> ".status_message($http_response->code)." (".$http_response->message.")";
>        $np->add_message($ERRORS{'CRITICAL'}, _gt("HTTP error: ").$err );
>
> } elsif ( ! $http_response->is_success() ) {
>        my $err = $http_response->code."
> ".status_message($http_response->code)." (".$http_response->message.")";
>        $np->add_message($ERRORS{'CRITICAL'}, _gt("Internal error: ").$err
> );
> }
>
>
> ($status, $message) = $np->check_messages();
>
> if ( $http_response->is_success() ) {
>
>        # Get xml content ...
>        my $stats = $http_response->content;
>
>        my @fields = ();
>        my @rows = split(/\n/,$stats);
>        if ( $rows[0] =~ /#\ \w+/ ) {
>                $rows[0] =~ s/#\ //;
>                @fields = split(/\,/,$rows[0]);
>        } else {
>                $np->nagios_exit($ERRORS{'UNKNOWN'}, _gt("Can't find csv
> header !") );
>        }
>
>        my %stats = ();
>        for ( my $y = 1; $y < $#rows; $y++ ) {
>                my @values = split(/\,/,$rows[$y]);
>                if ( !defined($stats{$values[0]}) ) {
>                        $stats{$values[0]} = {};
>                }
>                if ( !defined($stats{$values[0]}{$values[1]}) ) {
>                        $stats{$values[0]}{$values[1]} = {};
>                }
>                for ( my $x = 2,; $x < $#values; $x++ ) {
>                        # $stats{pxname}{svname}{valuename}
>                        $stats{$values[0]}{$values[1]}{$fields[$x]} =
> $values[$x];
>                }
>        }
> #       print Dumper(\%stats);
>        my %stats2 = ();
>        my $okMsg = '';
>        foreach my $pxname ( keys(%stats) ) {
>                $stats2{$pxname} = {
>                        'act' => 0,
>                        'acttot' => 0,
>                        'bck' => 0,
>                        'bcktot' => 0,
>                        'scur' => 0,
>                        'slim' => 0,
>                        };
>                foreach my $svname ( keys(%{$stats{$pxname}}) ) {
>                        if ( $stats{$pxname}{$svname}{'type'} eq '2' ) {
>                                my $svstatus =
> $stats{$pxname}{$svname}{'status'} eq 'UP';
>                                my $active = $stats{$pxname}{$svname}{'act'}
> eq '1';
>                                my $activeDescr = $active ? _gt("Active
> service") :_gt("Backup service") ;
>                                if ( $stats{$pxname}{$svname}{'status'} eq
> 'UP' ) {
>                                        logD( sprintf(_gt("%s '%s' is up on
> '%s' proxy."),$activeDescr,$svname,$pxname) );
>                                } elsif ( $stats{$pxname}{$svname}{'status'}
> eq 'DOWN' ) {
>
>  $np->add_message($ERRORS{'CRITICAL'}, sprintf(_gt("%s '%s' is DOWN on '%s'
> proxy !"),$activeDescr,$svname,$pxname) );
>                                }
>                                if ( $stats{$pxname}{$svname}{'act'} eq '1'
> ) {
>                                        $stats2{$pxname}{'acttot'}++;
>                                        $stats2{$pxname}{'act'} +=
> $svstatus;
>
>                                } elsif ($stats{$pxname}{$svname}{'bck'} eq
> '1')  {
>                                        $stats2{$pxname}{'bcktot'}++;
>                                        $stats2{$pxname}{'bck'} +=
> $svstatus;
>                                }
>                                $stats2{$pxname}{'scur'} +=
> $stats{$pxname}{$svname}{'scur'};
>                                logD( "Current sessions :
> ".$stats{$pxname}{$svname}{'scur'} );
>
>                        } elsif ( $stats{$pxname}{$svname}{'type'} eq '0' )
> {
>                                $stats2{$pxname}{'slim'} =
> $stats{$pxname}{$svname}{'slim'};
>                        }
>                }
>                if ( $stats2{$pxname}{'acttot'} > 0 ) {
>                        $okMsg .= ' '.$pxname.' (Active:
> '.$stats2{$pxname}{'act'}.'/'.$stats2{$pxname}{'acttot'};
>                        if ( $stats2{$pxname}{'bcktot'} > 0 ) {
>                                $okMsg .= ' , Backup:
> '.$stats2{$pxname}{'bck'}.'/'.$stats2{$pxname}{'bcktot'};
>                        }
>                        $okMsg .= ')';
>                        $np->add_perfdata(
>                                'label' => 'sess_'.$pxname,
>                                'value' => $stats2{$pxname}{'scur'},
>                                'min' => 0,
>                                'uom' => 'sessions',
>                                'max' => $stats2{$pxname}{'slim'},
>                        );
>                }
>        }
>
> #       print Dumper(\%stats2);
>        ($status, $message) = $np->check_messages('join' => ' ');
>
>        if ( $status == $ERRORS{'OK'} ) {
>                $message = $okMsg;
>        }
>
> }
> #       if ( $verbose ) {
> #               ($status, $message) = $np->check_messages('join' =>
> '<br/>','join_all' => '<br/>');
> #       } else {
> #               ($status, $message) = $np->check_messages('join' =>
> '<br/>');
> #       }
>
>
> $np->nagios_exit($status, $message );
>
>
> sub logD {
>        # print STDERR 'DEBUG:   '.$_[0]."\n" if ($DEBUG);
> }
> sub logW {
>        # print STDERR 'WARNING: '.$_[0]."\n" if ($DEBUG);
> }
> # Gettext wrapper
> sub _gt {
>        return gettext($_[0]);
> }
>
>
> __END__
>
> =head1 NAME
>
> This Nagios plugins check the statistics url provided by HAProxy (
> http://haproxy.1wt.eu/).
>
>
> =head1 NAGIOS CONGIGURATIONS
>
> In F<checkcommands.cfg> you have to add :
>
>        define command {
>          command_name  check_haproxy
>          command_line  $USER1$/check_haproxy.pl -u $ARG1$
>        }
>
>
> In F<services.cfg> you just have to add something like :
>
>        define service {
>          host_name             haproxy.exemple.org
>          normal_check_interval 10
>          retry_check_interval  5
>          contact_groups        linux-admins
>          service_description   HAProxy
>          check_command                 check_haproxy!
> http://haproxy.exemple.org/haproxy?stats;csv
>        }
>
> =head1 AUTHOR
>
> Stéphane Urbanovski<stephane.urbanov...@ac-nancy-metz.fr>
>
> =cut
>
>
>
>
> On Sep 29, 2010, at 1:00 PM, Kyle Brandt wrote:
>
> > Hi All,
> >
> > Before I go and reinvent the wheel, does anyone happen to have a Nagios
> script for checking that csv stats page generated by haproxy?
> >
> > Thanks!
> > Kyle
>
>
>

Reply via email to