I was recently inspired by morgamic’s Org Chart coding exercise and that got me thinking about an article I read some months ago about Zeus’ ZXTM triggers.
After a couple hours this week re-learning Perl and learning SOAP I have something that I think is cool - @mozdashboard!
I experimented a bit earlier in this week before Zandr gave me an idea of what I was really looking for with this. This version keeps state using Config::IniFiles (yeah, I said it and it was surely an easy way out) and tweets when it detects new highs.
zxtmtwitter.pl tracks the following sites:
addons.mozilla.orgversioncheck.addons.mozilla.orgfxfeeds.mozilla.com
It’ll tweet if it detects a new bandwidth high (either inbound or outbound) or a new simultaneous current connection count.
The program’s not without some faults – I’m not accounting for any counter wraps and I’m not happy with some of the hackery to poll each ZXTM node (I can’t find a way to poll one and get the cluster aggregates).
Code and .ini below the fold.
Config File (zxtm.ini):
[addons.mozilla.org] vserver=addons-ssl maxconnections=37327 bytesOut=39293647822458 bytesIn=4266246130636 timestamp=1246168046 maxbpsOut=82 maxbpsIn=8 [versioncheck.amo] vserver=versioncheck.addons.mozilla.org maxconnections=18556 bytesOut=6227643301317 bytesIn=4356691185954 timestamp=1246168043 maxbpsOut=11 maxbpsIn=8 [fxfeeds.mozilla.com] vserver=fxfeeds maxconnections=145780 bytesOut=7943190385192 bytesIn=6738548312076 timestamp=1246168041 maxbpsOut=17 maxbpsIn=14
Perl code (zxtmtwitter.pl):
#!/usr/bin/perl
use warnings;
use strict;
use Config::IniFiles;
use SOAP::Lite 0.60;
my $DEBUG = 0;
## twitter
my $tweetusr="mozdashboard";
my $tweetpwd="myPassword";
my $updateURL="http://twitter.com/statuses/update.xml";
##
## ZXTM
my $admin_server = 'https://myUser:myPassword';
my $conn1 = SOAP::Lite -> uri('http://soap.zeus.com/zxtm/1.0/System/Stats/') -> proxy("$admin_server\@zlb01:9090/soap");
my $conn2 = SOAP::Lite -> uri('http://soap.zeus.com/zxtm/1.0/System/Stats/') -> proxy("$admin_server\@zlb02:9090/soap");
my $conn3 = SOAP::Lite -> uri('http://soap.zeus.com/zxtm/1.0/System/Stats/') -> proxy("$admin_server\@zlb03:9090/soap");
my $conn4 = SOAP::Lite -> uri('http://soap.zeus.com/zxtm/1.0/System/Stats/') -> proxy("$admin_server\@zlb04:9090/soap");
my $conn5 = SOAP::Lite -> uri('http://soap.zeus.com/zxtm/1.0/System/Stats/') -> proxy("$admin_server\@zlb05:9090/soap");
my %ini;
tie %ini, 'Config::IniFiles', ( -file => "zxtm.ini" );
# loop through each section
foreach( keys %ini ) {
my @vserverArray;
my $timeStamp = time();
print "Found section [ $_ ], " if $DEBUG;
my $vserver = $ini{$_}{"vserver"};
print "vserver == $vserver\n" if $DEBUG;
my $old_Max = $ini{$_}{"maxconnections"};
my $old_BytesOut = $ini{$_}{"bytesOut"};
my $old_BytesIn = $ini{$_}{"bytesIn"};
my $old_MaxBpsOut = $ini{$_}{"maxbpsOut"};
my $old_MaxBpsIn = $ini{$_}{"maxbpsIn"};
my $old_Timestamp = $ini{$_}{"timestamp"};
undef @vserverArray;
push @vserverArray, $vserver;
my $max = &getMaxConn([@vserverArray]);
my $BytesOut = &getBytesOut([@vserverArray]);
my $BytesIn = &getBytesIn([@vserverArray]);
print "\tmaxConn = $max ($old_Max)\n " if $DEBUG;
my $timeDiff = $timeStamp - $old_Timestamp;
# The number eight keeps rendering as a smiley face.
# I replaced eight with (4*2) so it doesn't look stupid.
my $bpsOut = int((($BytesOut - $old_BytesOut) * (4*2)) / $timeDiff / 1024 / 1024);
my $bpsIn = int((($BytesIn - $old_BytesIn) * (4*2)) / $timeDiff / 1024 / 1024);
print "\t$bpsOut Mbps out ($old_MaxBpsOut), $bpsIn Mbps in ($old_MaxBpsIn)\n" if $DEBUG;
# store new values
$ini{$_}{"bytesOut"} = $BytesOut;
$ini{$_}{"bytesIn"} = $BytesIn;
$ini{$_}{"timestamp"} = $timeStamp;
if ($max > $old_Max) {
&tweet("$_ had a new Current Connections high @ $max (prev $old_Max)!");
$ini{$_}{"maxconnections"} = $max;
}
if ($bpsOut > $old_MaxBpsOut) {
&tweet ("$_ had a new Output Bandwidth High @ $bpsOut Mbps (prev $old_MaxBpsOut)!");
$ini{$_}{"maxbpsOut"} = $bpsOut;
}
if ($bpsIn > $old_MaxBpsIn) {
&tweet("$_ had a new Inbound Bandwidth High @ $bpsIn Mbps (prev $old_MaxBpsIn)!");
$ini{$_}{"maxbpsIn"} = $bpsIn;
}
# update .ini
tied( %ini )->WriteConfig( "zxtm.ini" ) || die "Could not write settings to new file.";
print "\n" if $DEBUG;
# add a line break for readability
print "\n" if $DEBUG;
}
sub getMaxConn {
my @vs = @_;
my $total;
my $res;
$res = $conn1->getVirtualserverMaxConn(@vs); $total += $res->result->[0];
$res = $conn2->getVirtualserverMaxConn(@vs); $total += $res->result->[0];
$res = $conn3->getVirtualserverMaxConn(@vs); $total += $res->result->[0];
$res = $conn4->getVirtualserverMaxConn(@vs); $total += $res->result->[0];
$res = $conn5->getVirtualserverMaxConn(@vs); $total += $res->result->[0];
$total;
}
sub getBytesOut {
my @vs = @_;
my $total;
my $res;
$res = $conn1->getVirtualserverBytesOut(@vs); $total += $res->result->[0];
$res = $conn2->getVirtualserverBytesOut(@vs); $total += $res->result->[0];
$res = $conn3->getVirtualserverBytesOut(@vs); $total += $res->result->[0];
$res = $conn4->getVirtualserverBytesOut(@vs); $total += $res->result->[0];
$res = $conn5->getVirtualserverBytesOut(@vs); $total += $res->result->[0];
$total;
}
sub getBytesIn {
my @vs = @_;
my $total;
my $res;
$res = $conn1->getVirtualserverBytesIn(@vs); $total += $res->result->[0];
$res = $conn2->getVirtualserverBytesIn(@vs); $total += $res->result->[0];
$res = $conn3->getVirtualserverBytesIn(@vs); $total += $res->result->[0];
$res = $conn4->getVirtualserverBytesIn(@vs); $total += $res->result->[0];
$res = $conn5->getVirtualserverBytesIn(@vs); $total += $res->result->[0];
$total;
}
sub tweet {
my $message = shift;
print "\ttweet: $message\n" if $DEBUG;
my $browser = LWP::UserAgent->new;
$browser->agent('ZXTM Eventing System');
$browser->credentials(
'twitter.com:80',
'Twitter API',
$tweetusr => $tweetpwd
);
my $response = $browser->post( $updateURL, [ status => $message ] );
#print $response->status_line;
#print $response->content;
}

Comment (1)
Good, but not very encouraging considering its possibilities combined with “facebook”.