#! /usr/bin/perl # Check haproxy load balance status # anders@fupp.net, 2009-05-19 use Getopt::Std; use IO::Socket; use MIME::Base64; $timeout = 10; getopts('H:b:s:u:p:dc'); sub usage { print "Usage:\n\tcheck_haproxy_lbstatus -H -b -s \n\t -u -p [-c (failure is critical)]\n"; exit(3); } usage unless ($opt_H && $opt_b && $opt_s); if ($opt_c) { $failexit = 2; } else { $failexit = 1; } $vhost = $opt_s; $vhost =~ s@^\w+://(.+?)/.*@\1@; # Remove port number: $vhost =~ s@\:\d+$@@; $baseurl = $opt_s; $baseurl =~ s@^\w+://.+?(/)@\1@; $port = $opt_s; if ($port =~ /^\w+:\/\/.+?\:(\d+)\/.*$/) { $port = $1; } else { $port = 80; } if ($opt_d) { print "vhost=$vhost\n"; print "baseurl=$baseurl\n"; print "port=$port\n"; } sub unknown { my $txt = shift; print "Could not check haproxy load balance status for $opt_H in backend $opt_b on $vhost"; if ($txt) { print ", $txt"; } elsif ($httpresponse) { print ", got $httpresponse"; } print "\n"; exit(3); } # Konstruer request $req = "GET $baseurl;csv;norefresh HTTP/1.1\r\nHost: $vhost\r\n"; if ($opt_u) { $req .= "Authorization: Basic " . encode_base64($opt_u . ":" . $opt_p, "") . "\r\n"; } $req .= "Connection: close\r\n\r\n"; if ($opt_d) { print "Request:\n$req"; } my $sock = new IO::Socket::INET ( PeerAddr => $vhost, PeerPort => $port, Proto => 'tcp', Timeout => $timeout ); unknown("could not connect") unless ($sock); print $sock $req; # HTTP respons $httpresponse = <$sock>; # Skip HTTP headere; while (<$sock>) { last if (/^\s*$/); } # Fields line; $fields = <$sock>; $fields =~ s@^# @@; chomp($fields); $fields =~ s@,$@@; @fields = split(/,/, $fields); #print "Felter: @fields X\n"; while (<$sock>) { @line = split(/,/, $_); next if ($line[1] =~ /^(FRONTEND|BACKEND)$/); # print "Jongo line: @line\n"; # print "line0: $line[0] line1: @line[1] numfields " . $#fields . " \n"; for ($i = 2; $i <= $#fields; $i++) { $status{"$line[0]"}{"$line[1]"}{"$fields[$i]"} = $line[$i]; # print "Ke $line[$i] "; } # print "\n"; #} # last if (/^(\r\n|\n)$/); # last if (/^\s*$/); # print; # $data .= $_; } close($sock); chomp($httpresponse); $httpcode = $httpresponse; $httpcode =~ s@^HTTP/[\d\.]+ (\d+).*@$1@g; if ($opt_d) { foreach $gr (keys %status) { print "gruppe: $gr\n"; foreach $host (keys %{ $status{"$gr"} }) { print "\thost: $host\n"; print "\tvalues: "; foreach $type (keys %{ $status{"$gr"}{"$host"} }) { print "$type=" . $status{"$gr"}{"$host"}{"$type"} . " "; } print "\n"; } } } $mystatus = $status{"$opt_b"}{"$opt_H"}{"status"}; $lastchg = $status{"$opt_b"}{"$opt_H"}{"lastchg"}; if ($opt_d) { print "Host: $opt_H\n"; print "Backend: $opt_b\n"; print "Status: $mystatus\n"; print "Last change: $lastchg\n"; } unknown unless ($httpcode == 200); if ($mystatus eq "UP") { print "Host $opt_H is UP on $vhost for $lastchg seconds\n"; exit(0); } elsif ($mystatus eq "DOWN") { print "Host $opt_H is DOWN on $vhost for $lastchg seconds\n"; exit($failexit); } elsif ($mystatus ne "") { print "Host $opt_H is in UNKNOWN status ($mystatus) on $vhost for $lastchg seconds\n"; exit($failexit); } else { unknown("host not found"); }