mourningdove/bin/pbadm

124 lines
3.6 KiB
Text
Raw Normal View History

2026-05-24 01:03:05 +00:00
#!/usr/bin/perl
#
# pbadm
#
# Perlbal administrative helper script.
#
# Authors:
# kareila <kareila@livejournal.com>
#
# Copyright (c) 2009 by Dreamwidth Studios, LLC.
#
# This program is free software; you may redistribute it and/or modify it under
# the same terms as Perl itself. For a copy of the license, please reference
# 'perldoc perlartistic' or 'perldoc perlgpl'.
#
use warnings;
use strict;
use Net::Telnet ();
use Date::Format ('time2str');
use Term::ANSIColor ('color');
### USER CHANGEABLE CONSTANTS ###
my $summary = 0;
if ($ARGV[0] eq '-s') {
$summary = 1;
shift;
}
my $refresh = shift() || 10; # polling interval in seconds
my $timeout = 5; # max time to connect in seconds
# intervals for color levels
my $sev0 = 0; my $sev0_color = 'green';
my $sev1 = 100; my $sev1_color = 'yellow';
my $sev2 = 500; my $sev2_color = 'bold yellow';
my $sev3 = 1000; my $sev3_color = 'red';
my $sev4_color = 'bold red'; # anything above sev3
### READ CONFIG INFO ###
require "$ENV{LJHOME}/ext/local/etc/config-private.pl";
my %hostinfo = eval "return %LJ::PERLBAL_SERVERS;"; # to suppress the warning
die "\%LJ::PERLBAL_SERVERS not found, please check config" unless %hostinfo;
my @servers = sort keys %hostinfo;
### INITIALIZE NETWORK VARIABLES ###
my %tcp; my %s1; my %s2;
foreach (@servers)
{
$tcp{$_} = new Net::Telnet (Timeout => $timeout, Telnetmode => 0);
my ($host, $port) = split ':', $hostinfo{$_};
$tcp{$_}->host($host); $tcp{$_}->port($port);
$tcp{$_}->errmode('return'); # don't die on connfail
$tcp{$_}->prompt('/\.$/'); # Perlbal end-of-data marker
$tcp{$_}->open(); # should stay open
}
sub color_for {
my $n = $_[0]+0;
return color $sev4_color if ($n > $sev3);
return color $sev3_color if ($n > $sev2 && $n <= $sev3);
return color $sev2_color if ($n > $sev1 && $n <= $sev2);
return color $sev1_color if ($n > $sev0 && $n <= $sev1);
return color $sev0_color if ($n == $sev0);
return color $sev4_color; # Makes no sense.
}
### INFINITE POLLING LOOP ###
until (0 > 1)
{
my $timestr = time2str("%a %b %d %T %Y", time);
foreach my $server (@servers)
{
my @states = $tcp{$server}->cmd('states');
unless (@states)
{
$s1{$server} = 'DWN';
$s2{$server} = 'DOWN';
$tcp{$server}->open(); # try to reopen
next;
}
my $bh_xfer = 0; my $bh_wait = 0; my $backend = 0;
foreach (@states)
{
$bh_xfer = $1 if /Perlbal::BackendHTTP xfer_res (\d+)/;
$bh_wait = $1 if /Perlbal::BackendHTTP wait_res (\d+)/;
$backend = $1 if /Perlbal::ClientProxy wait_backend (\d+)/;
}
$s1{$server} = sprintf("%03d", $bh_xfer + $bh_wait);
$s2{$server} = sprintf("%04d", $backend);
}
if ($summary) {
my ($ts1, $ts2, $td) = (0, 0, 0); # totals of
foreach (@servers)
{
$ts1 += $s1{$_} || 0;
$ts2 += $s2{$_} || 0;
$td++ if $s1{$_} eq 'DWN';
}
my $cr = color 'reset';
my $cw = color 'white';
my $down = $td ? sprintf(' %s** %d DOWN **%s', color($sev4_color), $td, $cr) : '';
printf '%s%2d%s%s IF %s%d%s%s Q%s%s',
color($sev0_color), $ts1, $cr, $cw, color_for($ts2), $ts2, $cr, $cw, $down, $cr;
print "\n";
last; # only run once
} else {
print "$timestr: ";
foreach (@servers)
{
my $n = ($s2{$_} eq 'DOWN') ? $sev3 * 10 : $s2{$_};
print color_for($n) . "[$_ - $s1{$_}, $s2{$_}] ";
print color 'reset';
}
print "\n";
}
sleep $refresh;
}