diff --git a/evolinux-users/templates/sudoers_jessie.j2 b/evolinux-users/templates/sudoers_jessie.j2 index c349ac09..b82c67ac 100644 --- a/evolinux-users/templates/sudoers_jessie.j2 +++ b/evolinux-users/templates/sudoers_jessie.j2 @@ -5,6 +5,7 @@ User_Alias ADMINS = {{ user.name }} nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall +nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats nagios ALL = NOPASSWD: /usr/sbin/bkctld check nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt diff --git a/evolinux-users/templates/sudoers_stretch.j2 b/evolinux-users/templates/sudoers_stretch.j2 index fb785c46..025aa0c2 100644 --- a/evolinux-users/templates/sudoers_stretch.j2 +++ b/evolinux-users/templates/sudoers_stretch.j2 @@ -4,6 +4,7 @@ Cmnd_Alias MAINT = /usr/share/scripts/evomaintenance.sh, /usr/share/scripts nagios ALL = NOPASSWD: /usr/lib/nagios/plugins/check_procs nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_minifirewall +nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats nagios ALL = NOPASSWD: /usr/sbin/bkctld check nagios ALL = (clamav) NOPASSWD: /usr/bin/clamscan /tmp/safe.txt diff --git a/haproxy/files/check_haproxy_stats.pl b/haproxy/files/check_haproxy_stats.pl deleted file mode 100644 index fc51938f..00000000 --- a/haproxy/files/check_haproxy_stats.pl +++ /dev/null @@ -1,288 +0,0 @@ -#!/usr/bin/env perl -# vim: se et ts=4: - -# -# Copyright (C) 2012, Giacomo Montagner -# 2015, Yann Fertat, Romain Dessort, Jeff Palmer, -# Christophe Drevet-Droguet -# -# This program is free software; you can redistribute it and/or modify it -# under the same terms as Perl 5.10.1. -# For more details, see http://dev.perl.org/licenses/artistic.html -# -# 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. -# - -our $VERSION = "1.2.0"; - -open(STDERR, ">&STDOUT"); - -# CHANGELOG: -# 1.0.0 - first release -# 1.0.1 - fixed empty message if all proxies are OK -# 1.0.2 - add perfdata -# 1.0.3 - redirect stderr to stdout -# 1.0.4 - fix undef vars -# 1.0.5 - fix thresholds -# 1.1.0 - support for HTTP interface -# 1.1.1 - drop perl 5.10 requirement -# 1.2.0 - add an option for ignore NOLB - -use strict; -use warnings; -use File::Basename qw/basename/; -use IO::Socket::UNIX; -use Getopt::Long; -my $lwp = eval { - require LWP::Simple; - LWP::Simple->import; - 1; -}; - -sub usage { - my $me = basename $0; - print <. - $me is distributed under GPL and the Artistic License 2.0 -SEE ALSO - Check out online haproxy documentation at -EOU -} - -my %check_statuses = ( - UNK => "unknown", - INI => "initializing", - SOCKERR => "socket error", - L4OK => "layer 4 check OK", - L4CON => "connection error", - L4TMOUT => "layer 1-4 timeout", - L6OK => "layer 6 check OK", - L6TOUT => "layer 6 (SSL) timeout", - L6RSP => "layer 6 protocol error", - L7OK => "layer 7 check OK", - L7OKC => "layer 7 conditionally OK", - L7TOUT => "layer 7 (HTTP/SMTP) timeout", - L7RSP => "layer 7 protocol error", - L7STS => "layer 7 status error", -); - -my @status_names = (qw/OK WARNING CRITICAL UNKNOWN/); - -# Defaults -my $swarn = 80.0; -my $scrit = 90.0; -my $sock = "/var/run/haproxy.sock"; -my $url; -my $user = ''; -my $pass = ''; -my $dump; -my $ignore_maint; -my $ignore_nolb; -my $proxy; -my $no_proxy; -my $help; - -# Read command line -Getopt::Long::Configure ("bundling"); -GetOptions ( - "c|critical=i" => \$scrit, - "d|dump" => \$dump, - "h|help" => \$help, - "m|ignore-maint" => \$ignore_maint, - "n|ignore-nolb" => \$ignore_nolb, - "p|proxy=s" => \$proxy, - "P|no-proxy=s" => \$no_proxy, - "s|sock|socket=s" => \$sock, - "U|url=s" => \$url, - "u|user|username=s" => \$user, - "x|pass|password=s" => \$pass, - "w|warning=i" => \$swarn, -); - -# Want help? -if ($help) { - usage; - exit 3; -} - -my $haproxy; -if ($url and $lwp) { - my $geturl = $url; - if ($user ne '') { - $url =~ /^([^:]*:\/\/)(.*)/; - $geturl = $1.$user.':'.$pass.'@'.$2; - } - $geturl .= ';csv'; - $haproxy = get($geturl); -} elsif ($url) { - my $haproxyio; - my $getcmd = "curl --insecure -s --fail " - . "--user '$user:$pass' '".$url.";csv'"; - open $haproxyio, "-|", $getcmd; - while (<$haproxyio>) { - $haproxy .= $_; - } - close($haproxyio); -} else { - # Connect to haproxy socket and get stats - my $haproxyio = new IO::Socket::UNIX ( - Peer => $sock, - Type => SOCK_STREAM, - ); - die "Unable to connect to haproxy socket: $sock\n$@" unless $haproxyio; - print $haproxyio "show stat\n" or die "Print to socket failed: $!"; - $haproxy = ''; - while (<$haproxyio>) { - $haproxy .= $_; - } - close($haproxyio); -} - -# Dump stats and exit if requested -if ($dump) { - print($haproxy); - exit 0; -} - -# Get labels from first output line and map them to their position in the line -my @hastats = ( split /\n/, $haproxy ); -my $labels = $hastats[0]; -die "Unable to retrieve haproxy stats" unless $labels; -chomp($labels); -$labels =~ s/^# // or die "Data format not supported."; -my @labels = split /,/, $labels; -{ - no strict "refs"; - my $idx = 0; - map { $$_ = $idx++ } @labels; -} - -# Variables I will use from here on: -our $pxname; -our $svname; -our $status; -our $slim; -our $scur; - -my @proxies = split ',', $proxy if $proxy; -my @no_proxies = split ',', $no_proxy if $no_proxy; -my $exitcode = 0; -my $msg; -my $checked = 0; -my $perfdata = ""; - -# Remove excluded proxies from the list if both -p and -P options are -# specified. -my %hash; -@hash{@no_proxies} = undef; -@proxies = grep{ not exists $hash{$_} } @proxies; - -foreach (@hastats) { - chomp; - next if /^#/; - next if /^[[:space:]]*$/; - my @data = split /,/, $_; - if (@proxies) { next unless grep {$data[$pxname] eq $_} @proxies; }; - if (@no_proxies) { next if grep {$data[$pxname] eq $_} @no_proxies; }; - - # Is session limit enforced? - if ($data[$slim]) { - $perfdata .= sprintf "%s-%s=%u;%u;%u;0;%u;", $data[$pxname], $data[$svname], $data[$scur], $swarn * $data[$slim] / 100, $scrit * $data[$slim] / 100, $data[$slim]; - - # Check current session # against limit - my $sratio = $data[$scur]/$data[$slim]; - if ($sratio >= $scrit / 100 || $sratio >= $swarn / 100) { - $exitcode = $sratio >= $scrit / 100 ? 2 : - $exitcode < 2 ? 1 : $exitcode; - $msg .= sprintf "%s:%s sessions: %.2f%%; ", $data[$pxname], $data[$svname], $sratio * 100; - } - } - - # Check of BACKENDS - if ($data[$svname] eq 'BACKEND') { - if ($data[$status] ne 'UP') { - $msg .= sprintf "BACKEND: %s is %s; ", $data[$pxname], $data[$status]; - $exitcode = 2; - } - # Check of FRONTENDS - } elsif ($data[$svname] eq 'FRONTEND') { - if ($data[$status] ne 'OPEN') { - $msg .= sprintf "FRONTEND: %s is %s; ", $data[$pxname], $data[$status]; - $exitcode = 2; - } - # Check of servers - } else { - if ($data[$status] ne 'UP') { - next if ($ignore_maint && $data[$status] eq 'MAINT'); - next if ($ignore_nolb && $data[$status] eq 'NOLB'); - next if $data[$status] eq 'no check'; # Ignore server if no check is configured to be run - next if $data[$svname] eq 'sock-1'; - $exitcode = 2; - our $check_status; - $msg .= sprintf "server: %s:%s is %s", $data[$pxname], $data[$svname], $data[$status]; - $msg .= sprintf " (check status: %s)", $check_statuses{$data[$check_status]} if $check_statuses{$data[$check_status]}; - $msg .= "; "; - } - } - ++$checked; -} - -unless ($msg) { - $msg = @proxies ? sprintf("checked proxies: %s", join ', ', sort @proxies) : "checked $checked proxies."; -} -print "Check haproxy $status_names[$exitcode] - $msg|$perfdata\n"; -exit $exitcode; diff --git a/haproxy/tasks/main.yml b/haproxy/tasks/main.yml index 0c8cb1fe..75a953e6 100644 --- a/haproxy/tasks/main.yml +++ b/haproxy/tasks/main.yml @@ -33,5 +33,4 @@ - haproxy - config -- include: nagios.yml - include: munin.yml diff --git a/haproxy/tasks/nagios.yml b/haproxy/tasks/nagios.yml deleted file mode 100644 index 1663b71b..00000000 --- a/haproxy/tasks/nagios.yml +++ /dev/null @@ -1,22 +0,0 @@ ---- -- include_role: - name: remount-usr - -- name: "Install check_haproxy_stats script" - copy: - src: check_haproxy_stats.pl - dest: /usr/local/lib/nagios/plugins/check_haproxy_stats.pl - mode: "0755" - tags: - - haproxy - - nrpe - -- name: "Add check_haproxy to sudoers" - lineinfile: - dest: /etc/sudoers.d/evolinux - line: 'nagios ALL = NOPASSWD: /usr/local/lib/nagios/plugins/check_haproxy_stats.pl' - insertafter: '^nagios' - tags: - - haproxy - - nrpe - - sudo diff --git a/nagios-nrpe/files/plugins/check_haproxy_stats b/nagios-nrpe/files/plugins/check_haproxy_stats index e3e8ff4b..fc51938f 100755 --- a/nagios-nrpe/files/plugins/check_haproxy_stats +++ b/nagios-nrpe/files/plugins/check_haproxy_stats @@ -1,94 +1,105 @@ -#!/usr/bin/env perl +#!/usr/bin/env perl # vim: se et ts=4: # # Copyright (C) 2012, Giacomo Montagner -# -# This program is free software; you can redistribute it and/or modify it -# under the same terms as Perl 5.10.1. +# 2015, Yann Fertat, Romain Dessort, Jeff Palmer, +# Christophe Drevet-Droguet +# +# This program is free software; you can redistribute it and/or modify it +# under the same terms as Perl 5.10.1. # For more details, see http://dev.perl.org/licenses/artistic.html -# +# # 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. # -our $VERSION = "1.0.1"; +our $VERSION = "1.2.0"; + +open(STDERR, ">&STDOUT"); # CHANGELOG: # 1.0.0 - first release # 1.0.1 - fixed empty message if all proxies are OK -# +# 1.0.2 - add perfdata +# 1.0.3 - redirect stderr to stdout +# 1.0.4 - fix undef vars +# 1.0.5 - fix thresholds +# 1.1.0 - support for HTTP interface +# 1.1.1 - drop perl 5.10 requirement +# 1.2.0 - add an option for ignore NOLB use strict; use warnings; -use 5.010.001; use File::Basename qw/basename/; use IO::Socket::UNIX; use Getopt::Long; +my $lwp = eval { + require LWP::Simple; + LWP::Simple->import; + 1; +}; sub usage { my $me = basename $0; print <. + Copyright (C) 2012 Giacomo Montagner . $me is distributed under GPL and the Artistic License 2.0 - SEE ALSO Check out online haproxy documentation at - EOU } @@ -115,19 +126,31 @@ my @status_names = (qw/OK WARNING CRITICAL UNKNOWN/); my $swarn = 80.0; my $scrit = 90.0; my $sock = "/var/run/haproxy.sock"; +my $url; +my $user = ''; +my $pass = ''; my $dump; +my $ignore_maint; +my $ignore_nolb; my $proxy; +my $no_proxy; my $help; # Read command line Getopt::Long::Configure ("bundling"); GetOptions ( - "c|critical=i" => \$scrit, - "d|dump" => \$dump, - "h|help" => \$help, - "p|proxy=s" => \$proxy, - "s|sock|socket=s" => \$sock, - "w|warning=i" => \$swarn, + "c|critical=i" => \$scrit, + "d|dump" => \$dump, + "h|help" => \$help, + "m|ignore-maint" => \$ignore_maint, + "n|ignore-nolb" => \$ignore_nolb, + "p|proxy=s" => \$proxy, + "P|no-proxy=s" => \$no_proxy, + "s|sock|socket=s" => \$sock, + "U|url=s" => \$url, + "u|user|username=s" => \$user, + "x|pass|password=s" => \$pass, + "w|warning=i" => \$swarn, ); # Want help? @@ -136,28 +159,53 @@ if ($help) { exit 3; } -# Connect to haproxy socket and get stats -my $haproxy = new IO::Socket::UNIX ( - Peer => $sock, - Type => SOCK_STREAM, -); -die "Unable to connect to haproxy socket: $@" unless $haproxy; -print $haproxy "show stat\n" or die "Print to socket failed: $!"; +my $haproxy; +if ($url and $lwp) { + my $geturl = $url; + if ($user ne '') { + $url =~ /^([^:]*:\/\/)(.*)/; + $geturl = $1.$user.':'.$pass.'@'.$2; + } + $geturl .= ';csv'; + $haproxy = get($geturl); +} elsif ($url) { + my $haproxyio; + my $getcmd = "curl --insecure -s --fail " + . "--user '$user:$pass' '".$url.";csv'"; + open $haproxyio, "-|", $getcmd; + while (<$haproxyio>) { + $haproxy .= $_; + } + close($haproxyio); +} else { + # Connect to haproxy socket and get stats + my $haproxyio = new IO::Socket::UNIX ( + Peer => $sock, + Type => SOCK_STREAM, + ); + die "Unable to connect to haproxy socket: $sock\n$@" unless $haproxyio; + print $haproxyio "show stat\n" or die "Print to socket failed: $!"; + $haproxy = ''; + while (<$haproxyio>) { + $haproxy .= $_; + } + close($haproxyio); +} # Dump stats and exit if requested if ($dump) { - while (<$haproxy>) { - print; - } + print($haproxy); exit 0; } # Get labels from first output line and map them to their position in the line -my $labels = <$haproxy>; +my @hastats = ( split /\n/, $haproxy ); +my $labels = $hastats[0]; +die "Unable to retrieve haproxy stats" unless $labels; chomp($labels); -$labels =~ s/^# // or die "Data format not supported."; +$labels =~ s/^# // or die "Data format not supported."; my @labels = split /,/, $labels; -{ +{ no strict "refs"; my $idx = 0; map { $$_ = $idx++ } @labels; @@ -167,33 +215,46 @@ my @labels = split /,/, $labels; our $pxname; our $svname; our $status; +our $slim; +our $scur; my @proxies = split ',', $proxy if $proxy; +my @no_proxies = split ',', $no_proxy if $no_proxy; my $exitcode = 0; my $msg; my $checked = 0; -while (<$haproxy>) { +my $perfdata = ""; + +# Remove excluded proxies from the list if both -p and -P options are +# specified. +my %hash; +@hash{@no_proxies} = undef; +@proxies = grep{ not exists $hash{$_} } @proxies; + +foreach (@hastats) { chomp; + next if /^#/; next if /^[[:space:]]*$/; my @data = split /,/, $_; if (@proxies) { next unless grep {$data[$pxname] eq $_} @proxies; }; + if (@no_proxies) { next if grep {$data[$pxname] eq $_} @no_proxies; }; - # Is session limit enforced? - our $slim; + # Is session limit enforced? if ($data[$slim]) { + $perfdata .= sprintf "%s-%s=%u;%u;%u;0;%u;", $data[$pxname], $data[$svname], $data[$scur], $swarn * $data[$slim] / 100, $scrit * $data[$slim] / 100, $data[$slim]; + # Check current session # against limit - our $scur; my $sratio = $data[$scur]/$data[$slim]; - if ($sratio >= $scrit || $sratio >= $swarn) { - $exitcode = $sratio >= $scrit ? 2 : + if ($sratio >= $scrit / 100 || $sratio >= $swarn / 100) { + $exitcode = $sratio >= $scrit / 100 ? 2 : $exitcode < 2 ? 1 : $exitcode; - $msg .= sprintf "%s:%s sessions: %.2f%%; ", $data[$pxname], $data[$svname], $sratio; + $msg .= sprintf "%s:%s sessions: %.2f%%; ", $data[$pxname], $data[$svname], $sratio * 100; } } # Check of BACKENDS if ($data[$svname] eq 'BACKEND') { - if ($data[$status] !~ '(UP|MAINT)') { + if ($data[$status] ne 'UP') { $msg .= sprintf "BACKEND: %s is %s; ", $data[$pxname], $data[$status]; $exitcode = 2; } @@ -205,8 +266,11 @@ while (<$haproxy>) { } # Check of servers } else { - if ($data[$status] !~ '(UP|MAINT)') { + if ($data[$status] ne 'UP') { + next if ($ignore_maint && $data[$status] eq 'MAINT'); + next if ($ignore_nolb && $data[$status] eq 'NOLB'); next if $data[$status] eq 'no check'; # Ignore server if no check is configured to be run + next if $data[$svname] eq 'sock-1'; $exitcode = 2; our $check_status; $msg .= sprintf "server: %s:%s is %s", $data[$pxname], $data[$svname], $data[$status]; @@ -220,6 +284,5 @@ while (<$haproxy>) { unless ($msg) { $msg = @proxies ? sprintf("checked proxies: %s", join ', ', sort @proxies) : "checked $checked proxies."; } -say "Check haproxy $status_names[$exitcode] - $msg"; +print "Check haproxy $status_names[$exitcode] - $msg|$perfdata\n"; exit $exitcode; - diff --git a/nagios-nrpe/templates/evolix.cfg.j2 b/nagios-nrpe/templates/evolix.cfg.j2 index bab8b681..517b93d1 100644 --- a/nagios-nrpe/templates/evolix.cfg.j2 +++ b/nagios-nrpe/templates/evolix.cfg.j2 @@ -66,7 +66,7 @@ command[check_mongodb_connect]={{ nagios_plugins_directory }}/check_mongodb -H l command[check_glusterfs]={{ nagios_plugins_directory }}/check_glusterfs -v all -n 0 command[check_supervisord_status]={{ nagios_plugins_directory }}/check_supervisord command[check_varnish]={{ nagios_plugins_directory }}/check_varnish_health -i 127.0.0.1 -p 6082 -s /etc/varnish/secret -w 2 -c 4 -command[check_haproxy]={{ nagios_plugins_directory }}/check_haproxy_stats -s /var/run/haproxy.sock -w 80 -c 90 +command[check_haproxy]=sudo {{ nagios_plugins_directory }}/check_haproxy_stats -s /var/run/haproxy.sock -w 80 -c 90 --ignore-maint --ignore-nolb command[check_minifirewall]=sudo {{ nagios_plugins_directory }}/check_minifirewall command[check_redis_instances]={{ nagios_plugins_directory }}/check_redis_instances