#!/usr/bin/perl -w #-d
#
# sar graphing tool based on rrdtool
# (c) 2004-2007 B. Cornec HP <bruno.cornec@hp.com>
# Licensed under the GPL or Artistic License
#
# Original Charter: Monitor CPU/Load/Net_eth0|2 (io/s)/Disk (io/s) 
# 1 mesure par 20 seconde
# Absolute time in minutes since Epoch
# So the script has been developped first with that context in mind
# trying to be generic enough to be expandable later on
# More work needs to be done, some code factorized, ...
#
use strict;		# Always :-)
use English;		# for $UID
use Data::Dumper;	# for debug
use Time::Local;	# for timestamp
use Date::Manip;	# for timestamp
use File::Basename;	# for file manageemnt
use Storable;		# for data exchange
use Config::Auto;	# for config file
use sario2rrd qw(create_attr create_gauge update_gauge);
			# local common functions

# Avoid localisation problems in sar
$ENV{LANG}="C";

#
# Begin of configuration options
#
my $dir = "sar2rrd"; 	# Place under the html dir of user apache
			# Under that directory you should have one
			# directory per machine and in it all the
			# files resulting form the sar and iostat
			# commands (saxx and ioxx). Look at the 
			# cron file and related script

my ($l,$p,$uid,$gid,$q,$c,$gc,$apache,$empty) = getpwnam("apache") or die "apache not in passwd file";
my $base = "$apache/html/$dir";
my $config = Config::Auto::parse("$base/$dir.conf");
my @machines = @{$config->{machines}};
my $shot = $config->{shot};

my $debug = 0;
foreach my $a (@ARGV) {
	$debug++ if ($a =~ /-v/);
	$| = 1;		# Flush STDOUT
}

#
my @day;
my %t;
my %attr;

print Dumper($config) if ($debug > 1);
mkdir $base,0755 if (not (-d $base));
chown $uid, $gid, $base || warn "Unable to chown $base to $uid" if ($UID == 0);
#
# data struct: hash per machine and per timestamp pointing to sar 
# and iostat values and a hash containing the  attributes
#

foreach my $m (@machines) {
	# Clean the table
	foreach my $ts (keys %t) {
		delete $t{$ts};
	}
	$attr{$m}{nbfields} = 0;
	#
	# The sar file has to be the result of sar -A -h
	# This stores the sar file content in the %t datastructure
	# 
	print "Getting sar info for $m ( " if ($debug > 0);
	foreach my $d (<$base/$m/sarh[0-9][0-9]>) {
		print basename($d)." " if ($debug > 0);
		open(SAR,$d) || die "Unable to open $d";
		while (<SAR>) {
			my ($name,$int,$tmst,$f1,$f2,$f3) = split /\t/;
			chomp($f3);
			$t{$tmst}{memoryfree} = $f3 if ($f2 =~ /kbmemfree/);
			$t{$tmst}{${f1}."-in"} = $f3 if ($f2 =~ /rxpck/);
			$t{$tmst}{${f1}."-out"} = $f3 if ($f2 =~ /txpck/);
			$t{$tmst}{runq} = $f3 if ($f2 =~ /runq-sz/);
			$t{$tmst}{plist} = $f3 if ($f2 =~ /plist-sz/);
			$t{$tmst}{load1} = $f3 if ($f2 =~ /ldavg-1/);
			$t{$tmst}{load5} = $f3 if ($f2 =~ /ldavg-5/);
			$t{$tmst}{${f1}."-user"} = $f3 if ($f2 =~ /user/);
			$t{$tmst}{${f1}."-nice"} = $f3 if ($f2 =~ /nice/);
			$t{$tmst}{${f1}."-system"} = $f3 if ($f2 =~ /system/);
			$t{$tmst}{${f1}."-idle"} = $f3 if ($f2 =~ /idle/);
			#$t{$tmst}{${f1}} = $f3 if (($f2 =~ /tps/) && ($f1 =~ /dev/));
			}
		close(SAR);
	}
	print ")\n" if ($debug > 0);
	print Dumper(%t) if ($debug > 1);
	#
	# Then create hash attributes + rrd base + update it
	#
	create_attr(\%t,\%attr,$m,$shot,$debug);
	create_gauge(\%t,\%attr,$config->{step},"$base/$m/$config->{rrdsar}",$uid,$gid,$m,$debug);
	update_gauge(\%t,\%attr,"$base/$m/$config->{rrdsar}",$m,$debug);
}
store (\%attr,"$base/$config->{svgsar}") || die "Unable to store attr structure: $!";
print "Please launch sar2html now to get graphs in HTML pages\n" if ($debug > 0);
