#!/usr/bin/perl
#
use lib "/home/spong/lib";
use IO::File;
use Data::Dumper;
use File::Path;
use Sys::Hostname;
use Getopt::Long;
use Carp;
# Configuration variables
$SPONGDB = "/home/spong/var/database";
$RRDCGI = "/usr/local/rrdtool/bin/rrdcgi"; # Location of RRD CGI program
$RRDDIR = "/home/spong/var/rrd"; # RRD Databases location
$RRDWWWDIR = "/home/spong/var/spong-rrd"; # Location to put generated
# CGI programs
$WWW_URL = "/spong-rrd"; # URL path to spong-rrd web pages
$WWW_IMAGE_URL = "/spong-rrd/images"; # URL path to image directory
$IMAGE_DIR = "/home/spong/tmp/spong-rrd"; # Directory file for generated
# graph images
$CGIEXT = ".cgi";
@COLORS = ( "00cc00", "0000ff", "00ffff", "ff00ff", "ffff00", "cc0000",
"0080c0", "8080c0", "ff0080", "800080", "0000a0",
"408080", "808000", "000000", "00ff00", "0080ff", "ff8000",
"800000", "fb31fb" );
my(@files);
%opt;
@options = ("info","help","debug");
if (! GetOptions(\%opt, @options)) {warn "Incorrect usage, see $0 --help"; exit 1; }
if ($opt{"help"}) { &usage(); exit 0; }
$debug = ($opt{'debug'}) ? 1 : 0;
opendir DIR,$RRDDIR or die "Could not opendir $RRDDIR: $!";
@files = grep { ! /^\./ } readdir(DIR);
closedir DIR;
&debug("Done scanning $RRDDIR dir, found " . ($#files+1) . " hosts");
# Create the IMAGE_DIR dir is not present
if ( ! -d $IMAGE_DIR ) {
&debug("\$IMAGE_DIR $IMAGE_DIR not found, creating it");
mkpath $IMAGE_DIR,0,"0777";
}
foreach $host (@files) {
&debug("Processing host $host");
# If --info parameter entered, generate Host Info file for the host
if ( $opt{'info'} ) { &doInfo($host) }
my($namemap);
# Create $host subdirectories if needed
if (! -d "$RRDWWWDIR/$host" ) {
&debug("spong-rrd dir $RRDWWWDIR/$host not found, creating it");
mkpath "$RRDWWWDIR/$host",0,"0755";
}
my( $indexfile ) = "$RRDWWWDIR/$host/index.html";
my( $fh ) = new IO::File "$indexfile","w";
if (! defined $fh) {
&error("doDiskIndex: Error: could not create file $indexfile; $!");
return;
}
$fh->print( &htmlHeader("System Charts of $host",
"Spong RRD - System Charts") );
$fh->print("\n
System Charts for $host.
\n");
$fh->print("\n");
$fh->print("
\n");
# If data_rrd_disk plugin is running, run the DiskGen routines
if ( -f "$RRDDIR/$host/.rrd-disk" ) {
&debug("data_rrd_disk DB's found, running DiskGen");
$namemap = &doDiskSingle( $RRDDIR, $host );
if (%$namemap) {
&doDiskSummary( $RRDDIR, $host, $namemap);
}
$fh->print("- Disk Usage\n");
}
# If data_rrd_la plugin is running, generate the CPU stats pages
if ( -f "$RRDDIR/$host/.rrd-la" ) {
&debug("data_rrd_la DB's found, running LoadAvgGen");
$fh->print("
- CPU/Job Information\n");
$fh->print("
\n");
&doLoadAvg( $RRDDIR, $host );
$fh->print("- Load Average
\n" );
&doNumUsers( $RRDDIR, $host );
$fh->print("- Number of Users
\n" );
&doNumJobs( $RRDDIR, $host );
$fh->print("- Number of Jobs
\n" );
$fh->print("
\n");
}
# If data_rrd_mysql plugin is running, generate the MySQL stats pages
if ( -f "$RRDDIR/$host/.rrd-mysql" ) {
&debug("data_rrd_mysql DB's found, running MySQLGen");
$fh->print(" - MySQL Information\n");
$fh->print("
\n");
&doMySQLThreads( $RRDDIR, $host );
$fh->print("- Threads
\n" );
&doMySQLTables( $RRDDIR, $host );
$fh->print("- Tables
\n" );
&doMySQLAvg( $RRDDIR, $host );
$fh->print("- Queries per Second
\n" );
$fh->print("
\n");
}
# If data_rrd_ping plugin is running, generate the ping stats pages
if ( -f "$RRDDIR/$host/.rrd-ping" ) {
&debug("data_rrd_mysql DB's found, running PingGen");
$fh->print(" - Ping Information\n");
$fh->print("
\n");
&doPingTimes( $RRDDIR, $host );
$fh->print("- Response Time
\n" );
$fh->print("
\n");
}
# If data_rrd_realserver plugin is running, run the RealServerGen routines
if ( -f "$RRDDIR/$host/.rrd-realserver" ) {
&debug("data_rrd_realserver DB's found, running RealServerGen");
$namemap = &doRealServerSingle( $RRDDIR, $host );
if (%$namemap) {
&doRealServerSummary( $RRDDIR, $host, $namemap);
}
$fh->print(" - RealServer Usage\n");
}
$fh->print("
\n");
$fh->print( &cgiFooter() );
$fh->close();
}
# Build index page of hosts that have rrd data
&buildIndex();
exit;
sub buildIndex {
my($curtime) = scalar localtime();
my($host) = &Sys::Hostname::hostname();
my($user) = $ENV{'USER'};
$fh = new IO::File "$RRDWWWDIR/index.html","w";
print $fh "
$title
Spong-rrd Host Index
";
foreach $host (sort @files) {
print $fh " - $host\n";
}
print $fh "
";
$fh->close();
}
sub doInfo {
my( $host ) = @_;
my($infodir) = "$SPONGDB/$host/info";
if (! -d $infodir ) { mkpath "$infodir",0,"0755"; }
my($fh) = new IO::File "$infodir/info.html","w";
if (! defined $fh) {
&error("doInfo: Error: Could not create file $infodir/info.html: $!");
return;
}
$fh->print("System Charts");
$fh->close();
&debug("info file i$infodir/info.html created for host $host");
}
sub doLoadAvg {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/la.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doDiskGen: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/loadavg";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, Load Average",
"Load Average for $host") );
my $comment = "load avg";
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"loadavg","Load Average",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"loadavg","Load Average",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"loadavg","Load Average",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"loadavg","Load Average",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doNumUsers {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/la.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doDiskGen: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/num-users";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, Number of Users" ,
"Number of Users for $host") );
my $comment = "# of users";
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"users","# of users",
$comment) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"users","# of users",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"users","# of users",
$comment) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"users","# of users",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doNumJobs {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/la.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doDiskGen: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/num-jobs";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
my $comment = "# of jobs";
$fh->print( &cgiHeader("host $host, Number of Jobs",
"Number of Jobs for $host") );
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"jobs","# of jobs",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"jobs","# of jobs",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"jobs","# of jobs",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"jobs","# of jobs",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doMySQLThreads {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/mysql.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doMySQLThreads: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/mysql-threads";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, MySQL Threads",
"MySQL Threads for $host") );
my $comment = "threads";
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"threads","MySQL Threads",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"threads","MySQL Threads",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"threads","MySQL Threads",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"threads","MySQL Threads",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doMySQLTables {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/mysql.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doMySQLTables: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/mysql-tables";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, MySQL Tables",
"MySQL Tables for $host") );
my $comment = "tables";
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"tables","MySQL Tables",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"tables","MySQL Tables",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"tables","MySQL Tables",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"tables","MySQL Tables",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doMySQLAvg {
my( $rrddir, $host ) = @_;
my($rrdfile) = "$RRDDIR/$host/mysql.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doMySQLTables: Error: Can't find rrd file $rrdfile");
next;
}
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/mysql-avg";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, MySQL Queries per Second",
"MySQL Queries per Second for $host") );
$fh->print("If you have MySQL v3.22 or below, these'll be zero.\n");
my $comment = "queries/s";
$fh->print( "\n
Hourly
" );
$fh->print( &dsGraph('hourly',$host,$rrdfile,"avg","MySQL Queries per Second",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &dsGraph('daily',$host,$rrdfile,"avg","MySQL Queries per Second",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &dsGraph('weekly',$host,$rrdfile,"avg","MySQL Queries per Second",
$comment ) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &dsGraph('monthly',$host,$rrdfile,"avg","MySQL Queries per Second",
$comment ) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doPingTimes {
my( $rrddir, $host, $namemap ) = @_;
# Build the DEFS and LINES definitions
my( $partfile, $defs, $lines, $p );
$defs = $lines = ""; $p=-1;
my($rrdfile) = "$rrddir/$host/ping-times.rrd";
foreach $part ( @{ [ 'max', 'avg', 'min' ] } ) {
$p++;
$defs .= "\nDEF:$p=$rrdfile:$part:AVERAGE";
if ($part eq 'max') {
$lines .= "\nAREA:$p#" . $COLORS[$p] . ":$part";
} else {
$lines .= "\nLINE2:$p#" . $COLORS[$p] . ":$part";
}
}
my($cgifile) = "$RRDWWWDIR/$host/ping-times";
$cgifile .= $CGIEXT if $CGIEXT;
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("doPingTimes: Error: could not create file $cgifile; $!");
return;
}
$fh->print( cgiHeader("host $host, Ping Times",
"Ping Times to $host") );
$fh->print( "\n
Hourly
" );
$fh->print( &pingTimes('hourly',$host,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &pingTimes('daily',$host,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &pingTimes('weekly',$host,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &pingTimes('monthly',$host,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub pingTimes {
my($type,$host,$part,$rrdfile,$defs,$lines) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-w 500 -h 200 -v "ping times (s)" -s $timestr
$defs
$lines
>
|;
return $graph;
}
sub doDiskSummary {
my( $rrddir, $host, $namemap ) = @_;
# Build the DEFS and LINES definitions
my( $partfile, $defs, $lines, $p );
$defs = $lines = ""; $p=-1;
foreach $part ( sort (keys %$namemap) ) {
my($rrdfile) = "$rrddir/$host/disk-$part.rrd";
$p++;
$defs .= "\nDEF:$p=$rrdfile:pct:AVERAGE";
$lines .= "\nLINE2:$p#" . $COLORS[$p] . ':"' . $namemap->{$part} . '"';
}
my($cgifile) = "$RRDWWWDIR/$host/disk-summary";
$cgifile .= $CGIEXT if $CGIEXT;
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("doDiskSummary: Error: could not create file $cgifile; $!");
return;
}
$fh->print( cgiHeader("host $host, All Partitions",
"File Usage Summary for $host") );
$fh->print( "\n
Hourly
" );
$fh->print( &diskGraphAll('hourly',$host,$partfile,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &diskGraphAll('daily',$host,$partfile,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &diskGraphAll('weekly',$host,$partfile,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &diskGraphAll('monthly',$host,$partfile,$part,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doDiskSingle {
my( $rrddir, $host ) = @_;
# Read in the disk-name-map files
my($mapfile)= "$rrddir/$host/disk-name-map";
my($nm) = new IO::File "$mapfile", "r";
if (! defined $nm) {
&error("Error:doDiskGen: Could not open name map file $file: $!");
return;
}
# Read in the disk name map and process each one
my( %namemap );
while (<$nm>) {
chomp; my($k,$v) = split ':';
$namemap{$k} = $v;
my($rrdfile) = "$RRDDIR/$host/disk-$k.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doDiskGen: Error: Can't find rrd file $rrdfile");
next;
}
# Build the CGI page for the host/partition
&bldPartCGI($host,$k,$v,$rrdfile);
}
return \%namemap; # Return the name map to papa
}
sub bldPartCGI {
my( $host, $partfile, $part, $rrdfile ) = @_;
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/disk-$partfile";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldPartCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, partition $part",
"File Usage for $host $part") );
$fh->print( "\n
Hourly
" );
$fh->print( &diskGraphOne('hourly',$host,$partfile,$part,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &diskGraphOne('daily',$host,$partfile,$part,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &diskGraphOne('weekly',$host,$partfile,$part,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &diskGraphOne('monthly',$host,$partfile,$part,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub diskGraphAll {
my($type,$host,$partfile,$part,$rrdfile,$defs,$lines) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-l 0 -u 100 -w 500 -h 200 -v "% Full" -s $timestr
$defs
$lines
>
|;
return $graph;
}
sub diskGraphOne {
my($type,$host,$partfile,$part,$rrdfile) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-l 0 -u 100 -w 500 -h 200 -v "% Full" -s $timestr
DEF:part=$rrdfile:pct:AVERAGE
LINE2:part#00a000:"$part"
>
|;
return $graph;
}
sub doRealServerSummary {
my( $rrddir, $host, $namemap ) = @_;
# Build the DEFS and LINES definitions
my( $partfile, $defs, $lines, $p );
$defs = $lines = ""; $p=-1;
foreach $stream ( sort (keys %$namemap) ) {
my($rrdfile) = "$rrddir/$host/realserver-$stream.rrd";
$p++;
$defs .= "\nDEF:$p=$rrdfile:players:AVERAGE";
$lines .= "\nLINE2:$p#" . $COLORS[$p] . ':"' . $namemap->{$stream} . '"';
}
my($cgifile) = "$RRDWWWDIR/$host/realserver-summary";
$cgifile .= $CGIEXT if $CGIEXT;
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("doRealServerSummary: Error: could not create file $cgifile; $!");
return;
}
$fh->print( cgiHeader("host $host, All Streams",
"RealServer Players Summary for $host") );
$fh->print( "\n
Hourly
" );
$fh->print( &realServerGraphAll('hourly',$host,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &realServerGraphAll('daily',$host,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &realServerGraphAll('weekly',$host,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &realServerGraphAll('monthly',$host,$rrdfile,$defs,$lines) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub doRealServerSingle {
my( $rrddir, $host ) = @_;
# Read in the realserver-stream-map files
my($mapfile)= "$rrddir/$host/realserver-stream-map";
my($nm) = new IO::File "$mapfile", "r";
if (! defined $nm) {
&error("Error:doRealServerSingle: Could not open name map file $file: $!");
return;
}
# Read in the stream name map and process each one
my( %namemap );
while (<$nm>) {
chomp; my($k,$v) = split ':';
$namemap{$k} = $v;
my($rrdfile) = "$RRDDIR/$host/realserver-$k.rrd";
# If rrdfile not found, complain and move on
if ( ! -f $rrdfile ) {
&error("doRealServerSingle: Error: Can't find rrd file $rrdfile");
next;
}
# Build the CGI page for the host/partition
&bldStreamCGI($host,$k,$v,$rrdfile);
}
return \%namemap; # Return the name map to papa
}
sub bldStreamCGI {
my( $host, $streamfile, $stream, $rrdfile ) = @_;
my($cgidir) = "$RRDWWWDIR/$host";
my($cgifile) = "$cgidir/realserver-$streamfile";
$cgifile .= $CGIEXT if $CGIEXT;
if (! -d $cgidir) { mkpath "$cgidir",0,0755; }
my($fh) = new IO::File "$cgifile","w";
if (! defined $fh) {
&error("bldSteamCGI: Error: Could not create file $cgifile: $!");
return;
}
$fh->print( &cgiHeader("host $host, stream $streamName",
"RealServer Usage for $host $part") );
$fh->print( "\n
Hourly
" );
$fh->print( &realServerGraphOne('hourly',$host,$streamfile,$stream,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Daily
" );
$fh->print( &realServerGraphOne('daily',$host,$streamfile,$stream,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Weekly
" );
$fh->print( &realServerGraphOne('weekly',$host,$streamfile,$stream,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( "\n
Monthly
" );
$fh->print( &realServerGraphOne('monthly',$host,$streamfile,$stream,$rrdfile) );
$fh->print( "\n\n" );
$fh->print( &cgiFooter );
$fh->close();
# Set permissions so it's executable
chmod 0755,$cgifile;
}
sub realServerGraphAll {
my($type,$host,$rrdfile,$defs,$lines) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-l 0 -w 500 -h 200 -v "players" -s $timestr
$defs
$lines
>
|;
return $graph;
}
sub realServerGraphOne {
my($type,$host,$streamfile,$stream,$rrdfile) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-w 500 -h 200 -v "% Full" -s $timestr
DEF:part=$rrdfile:players:AVERAGE
LINE2:part#00a000:"$part"
>
|;
return $graph;
}
sub dsGraph {
my($type,$host,$rrdfile,$ds,$comment,$y_comment) = @_;
my($timestr) = "";
if ($type eq 'hourly') { $timestr = "e-48h"; }
elsif ($type eq 'daily') { $timestr = "e-12d"; }
elsif ($type eq 'weekly') { $timestr = "e-48d"; }
elsif ($type eq 'monthly') { $timestr = "e-576d"; }
my($graph) = qq|
'
-w 500 -h 200 -v "$y_comment" -s $timestr
DEF:$ds=$rrdfile:$ds:AVERAGE
LINE2:$ds#$COLORS[0]:"$comment"
>
|;
return $graph;
}
sub htmlHeader {
my($for,$title) = @_;
my($curtime) = scalar localtime();
my($host) = &Sys::Hostname::hostname();
my($user) = $ENV{'USER'};
my($header) = "
$title
";
return $header;
}
sub cgiHeader {
my($for,$title) = @_;
my($curtime) = scalar localtime();
my($host) = &Sys::Hostname::hostname();
my($user) = $ENV{'USER'};
my($header) = "#!$RRDCGI
$title
$title
";
return $header;
}
sub cgiFooter {
my($footer) = "
";
return $footer;
}
# Error reporting routine
sub error {
my($msg) = @_;
warn scalar localtime(), " Error: $msg \n";
}
sub debug {
print scalar localtime(), " ", @_[0], "\n" if $main::debug;
}