#!/usr/bin/perl =head1 NAME jpred_stats.pl - Collate Monthly and Daily usage statistics for the Jpred server =cut use strict; use warnings; use GD::Graph::bars; use Getopt::Long; use Pod::Usage; # path for nicer fonts for the graph labels my $FONTPATH = "$ENV{HOME}/bin/fonts/"; my $help; my $man; my $outPath = '.'; my $file = '/grid/default/common/accounting'; GetOptions( 'source=s' => \$file, 'path=s' => \$outPath, 'h|?' => \$help, 'help' => \$help, 'man' => \$man, ) or pod2usage(0); pod2usage(-verbose => 1) if $help; pod2usage(-verbose => 2) if $man; pod2usage(-msg => "$outPath doesn't exist please give a valid path", -verbose => 0) if (!-e $outPath); my @abbr = qw( Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec ); open (my $MONF, ">$outPath/monthly.csv") or die "ERROR - unable to open \'$outPath/monthly.csv\': $!"; open (my $DAYF, ">$outPath/daily.csv") or die "ERROR - unable to open \'$outPath/daily.csv\': $!"; my %stats; my %dayStats; my $currMon = extract_stats(\%stats, \%dayStats, $file); my @monthly; my $i = 0; #print "Monthly summary.\n"; ## Sort by and then by month and output/store usage data for each month foreach my $yr (sort {$a <=> $b} keys %stats) { #printf "\n%d\n", $yr + 1900; foreach my $mon (sort {$a <=> $b} keys %{$stats{$yr}}) { #print "$abbr[$mon]: $stats{$yr}{$mon}\n"; my $date = sprintf "%s %02d", $abbr[$mon], $yr-100; print $MONF "$date,$stats{$yr}{$mon}\n"; $monthly[0][$i] = $date; $monthly[1][$i] = $stats{$yr}{$mon}; ++$i; } } draw_graph(\@monthly, 'Month', 'Monthly Breakdown of JNet Usage'); my @daily; $i = 0; #print "\nDaily summary for $abbr[$currMon]\n"; ## Sort by date and ouput/store data for the current month. foreach my $day (sort {$a <=> $b} keys %dayStats) { #printf "%02d: %d\n", $day, $dayStats{$day}; printf $DAYF "%02d,%d\n", $day, $dayStats{$day}; $daily[0][$i] = $day; $daily[1][$i] = $dayStats{$day}; ++$i; } die "ERROR - No data for current month ($abbr[$currMon])" if (!@daily); draw_graph(\@daily, 'Date', "Daily Breakdown for $abbr[$currMon]"); $i = 0; my @week; foreach my $num (-7..-1) { next if (!$daily[0][$num]); $week[0][$i] = sprintf "%02d/%02d", $daily[0][$num], $currMon+1; $week[1][$i] = $daily[1][$num]; ++$i; } draw_sm_graph(\@week); exit; sub extract_stats { my ($statsRef, $dayRef, $file) = @_; open (my $FH, $file) or die "ERROR - can't open file \'$file\': $!"; my ($currMon, $currYr) = (localtime())[4,5]; while (<$FH>) { next unless /www-jpred/; my @F = split(/:/, $_); die "ERROR - not enough fileds found in source file \'$file\'. Is the file correct and in the correct format?" if (9 > scalar @F); #the 9th field is the date in Unix time. Extract the day, month and year from it. my ($day, $mnth, $year) = (localtime($F[8]))[3..5]; next if ($year == 70); # ignore jobs with invalid dates next if ($F[8] < 1148338800); # ignore jobs prior to 1 May 2006 if (($mnth == $currMon) && ($year == $currYr)) { $dayRef->{$day}++; } $statsRef->{$year}{$mnth}++; } close($FH); die "ERROR - no valid data found in \'$file\'" unless $statsRef; # die if there's no data in $statsRef return ($currMon); } sub draw_graph { my ($dataref, $x_label, $title) = @_; my $graph = GD::Graph::bars->new(700, 400); $graph->set_title_font("$FONTPATH/VeraBd.ttf", 12); $graph->set_x_label_font("$FONTPATH/VeraBd.ttf", 8); $graph->set_y_label_font("$FONTPATH/VeraBd.ttf", 8); $graph->set_x_axis_font("$FONTPATH/Vera.ttf", 6); $graph->set_y_axis_font("$FONTPATH/Vera.ttf", 8); $graph->set( x_label => $x_label, y_label => 'No. JNet Submissions', title => $title, shadow_depth => -2, shadowclr => 'gray', x_labels_vertical => 1, borderclrs => undef, bar_width => 1, bar_spacing => 4 ) or die $graph->error; my $gd = $graph->plot($dataref) or die $graph->error; open(IMG, ">$outPath/jnet_${x_label}_stats.png") or die $!; binmode IMG; print IMG $gd->png; close(IMG); } sub draw_sm_graph { my ($dataref) = @_; my $graph = GD::Graph::bars->new(250, 150); $graph->set_y_label_font("$FONTPATH/VeraBd.ttf", 8); $graph->set_x_axis_font("$FONTPATH/Vera.ttf", 8); $graph->set_y_axis_font("$FONTPATH/Vera.ttf", 8); $graph->set( y_label => 'No. Jobs', x_labels_vertical => 1, borderclrs => undef, bar_width => 15, accentclr => 'lbrown', dclrs => [ qw(dbrown dpurple) ], bar_spacing => 2 ) or die $graph->error; my $gd = $graph->plot($dataref) or die $graph->error; open(IMG, ">$outPath/jnet_stats.png") or die $!; binmode IMG; print IMG $gd->png; close(IMG); } =head1 SYNOPSIS jpred_stats.pl [--path ] [--source ] =head1 DESCRIPTION Script to collate the usage statistics for the Jpred server. The stats are subdivided by month and then my day for he current month only. The outputs are two graph images and and two comma separated files ( and ) containing the raw data. =head1 OPTIONS =over =item --path Path to where you want the output saved. [default: ] =item --source Source of Sun Grid Engine usage log file. [default: /grid/default/common/accounting] =item --help Display help. =item --man Display man page. =back By default the script with use the current known SGE logfile and output the data to current directory. =head1 AUTHOR Chris Cole =cut