#!/usr/bin/perl -w require 5.003; use strict; # plots traces labeled with label_results # see also: label_results, plot_traces if (`pwd` =~ 'ReportGen') { use lib '..'; } use FileHandle; #use HTML::Entities; use ReportGen::Opts; use ReportGen::Globs; use ReportGen::ObjDbase; use ReportGen::ObjManip; use ReportGen::RepFormat; # Configuration my %Opts = ( trace_plotter => undef(), trace_plotter_opts => undef(), ); my %SavedOpts = %Opts; my @BaseTypes = qw( hit miss ims.sc200 ims.sc304 redired_req rep_to_redir cachable uncachable fill basic ims reload rep ); # globals my @Labels; &init(); exit(&main()); sub main { foreach my $label (@Labels) { makeCard($label); } return 0; } sub makeCard { my $label = &curLabel(shift); &clearObjects(); my $stats = &ReadDbase(&FullInFName($label, "clt.All.lx")); &importObjects($stats); my $facts = &ReadDbase(&FullInFName($label, "facts.lx"), 'may fail'); &importObjects($facts) if $facts; &checkObjects(); my $fname = &FullOutFName("$label/card", 'index', '.html'); my $hname = label2hname($label); &openReport($fname, $hname); &reportAggrStats(); &reportTraces(); #&reportDistrib(); &closeReport(); warn("$0: local report URL is file:$fname\n"); &curLabel(undef()); } sub reportAggrStats { print($OFile '
'); &reportExSummary(); print($OFile &substNamesInHTML('Phases: [name].

')); &reportTputAndHr(); print($OFile '
'); &reportStreams(); print($OFile '
'); &reportObjs(); # print some warnings if needed my @wobjs = (&getWarnObjs()); if (@wobjs) { print($OFile "

Potential problems:\n

    \n"); foreach my $obj (@wobjs) { printf($OFile "\t
  1. %s\n", $obj->{warn_key}, $obj->{warn_txt}) if $obj->{warn_txt}; } print($OFile "
\n"); } &reportErrors(); } sub reportExSummary { my $html = <
Throughput:[rep.rate]rep/sec
Response time:[rep.rptm.mean]msec
- misses:[miss.rptm.mean]msec
- hits:[hit.rptm.mean]msec
Hit Ratio:[hit.ratio.obj]%
Errors:[err_xact.ratio]%
Duration:[duration/3600]hour

HTML print($OFile &substNamesInHTML($html)); } sub reportTputAndHr { my $html = < TABLE if (&objVal('_have_icp_stats')) { $html .= < TABLE } $html .= <

TABLE print($OFile &smallTable(&substNamesInHTML($html))); } sub reportChb { my $html = <
  Load Hit Ratios
Count
(xact/sec)
Volume
(Mbit/sec)
DHR
(%)
BHR
(%)
Offered: [req.rate] [req.bw/$Mbit] [offered.hit.ratio.obj] [offered.hit.ratio.byte]
Measured: [rep.rate] [rep.bw/$Mbit] [hit.ratio.obj] [hit.ratio.byte]
ICP reqs: [icp.req.rate] [icp.req.bw/$Mbit]    
ICP reps: [icp.rep.rate] [icp.rep.bw/$Mbit] [icp.hit.ratio.obj] [icp.hit.ratio.byte]
Cachability Ratios Count
(%)
Volume
(%)
Measured: [cachable.ratio.obj] [cachable.ratio.byte]

TABLE print($OFile &smallTable(&substNamesInHTML($html))); } sub reportObjs { my @types = @BaseTypes; my $html = ''; $html .= < TABLE foreach my $type (@types) { $html .= "\n"; foreach my $meas (qw( obj byte )) { $html .= "\t\n"; } foreach my $meas (qw( min median mean max )) { $html .= "\t\n"; } foreach my $meas (qw( min median mean max )) { $html .= "\t\n"; } $html .= "\n"; } print($OFile &smallTable(&substNamesInHTML($html))); print $OFile <

TABLE } sub reportStreams { my $html = <
Object Class Contribution (%) Response Time (msec) Size (KB)
Count Volume Min Median Mean Max Min Median Mean Max
$type[$type.ratio.$meas][$type.rptm.$meas][$type.size.$meas/1024]
TABLE my @types = @BaseTypes; push @types, map { "icp.$_" } qw ( hit miss rep ) if &objVal('_have_icp_stats'); for my $type (@types) { $html .= " \n"; } $html .= '
Streams Rates Totals
Count
(rep/sec)
Volume
(Mbit/sec)
Count
(rep*106)
Volume
(GByte)
$type [$type.rate] [$type.bw/$Mbit] [$type.size.count/1e6] [$type.size.sum/$GByte]

'; print($OFile &smallTable(&substNamesInHTML($html))); } sub reportErrors { if (&objVal('_have_icp_stats')) { print($OFile &substNamesInHTML( "

ICP timeouts: [icp.timeout.count]". " ([icp.timeout.ratio]% of all ICP requests)

\n" )); } # print errors table my $tbl = &getTable('errors.tbl'); if (defined $tbl) { my $lines = $tbl->{lines}; if ($lines && @{$lines}) { print($OFile '
');
			foreach my $line (@{$lines}) {
				print($OFile $line);
			}
			print($OFile "
\n"); } } } sub checkObjects { my $diffp; $diffp = 2; if (&exprDiffer('rep.rate', 'req.rate', \$diffp)) { &setWarn('rep.rate', 'suspecious reply rate', "Reply rate ([rep.rate]/sec) differs from the request rate ([req.rate]/sec) by [$diffp]%."); } $diffp = 3; if (&exprDiffer('hit.ratio.obj', 'offered.hit.ratio.obj', \$diffp)) { &setWarn('hit.ratio.obj', 'suspecious DHR', "Measured document hit ratio ([hit.ratio.obj]%) differs from the offered DHR ([offered.hit.ratio.obj]%) by [$diffp]%."); } $diffp = 5; if (&exprDiffer('hit.ratio.byte', 'offered.hit.ratio.byte', \$diffp)) { &setWarn('hit.ratio.byte', 'suspecious BHR', "Measured byte hit ratio ([hit.ratio.byte]%) differs from the offered BHR ([offered.hit.ratio.byte]%) by [$diffp]%."); } $diffp = 10; if (&exprDiffer('hit.rptm.mean', 'miss.rptm.mean', \$diffp) && $diffp > 0) { &setWarn('hit.rptm.mean', 'hit rptm too high', "Hit response time ([hit.rptm.mean]s msec) is [$diffp]% higher than miss response time ([miss.rptm.mean] msec)."); } # $diffp = 0.01; # my $wr = '100*wait.started/xact.started'; # if (&computeExpr("$wr > $diffp")) { # &setWarn('wait.started', 'too many queued requests', # "Quite a few ([$wr]% > $diffp%) requests # got queued waiting for resources."); # } $diffp = 0.1; if (&checkObj('err_xact.ratio') && &objVal('err_xact.ratio') > $diffp) { &setWarn('err_xact.ratio', 'too many errors', "Error ratio ([err_xact.ratio]%) exceeds [$diffp]%."); } my $minDur = 20*60; if (checkObj('duration') && &objVal('duration') < $minDur) { &setWarn('duration', 'too small sample', "Experiment duration ([duration/60] minutes) is less than [$minDur] minutes and may be too short."); } } sub reportTraces { &traceSmth('rates', [qw( req.rate rep.rate )]); &traceSmth('rptms', [qw( miss.rptm.mean rep.rptm.mean hit.rptm.mean )]); &traceSmth('ratios', [qw( cachable.ratio.obj offered.hit.ratio.obj hit.ratio.obj )]); &traceSmth('xact_lvl', [qw( xact.level.mean wait.level.mean )]); &traceSmth('errors',[qw( err_xact.ratio err_xact.count )]); } sub traceSmth { my ($name, $objects, $options) = @_; $options = $Opts{trace_plotter_opts} unless defined $options; $options = '' unless defined $options; $options .= ' --plot_size 1,0.33' unless index('--plot_size ', $options) >= 0; my $fname = "$name.png"; my $label = &curLabel(); my $fullFName = &FullOutFName("$label/card", $fname); &System(sprintf("%s %s --out_name %s %s", $Opts{trace_plotter}, $options, $fullFName, join(' ', map { "$label:$_" } @{$objects}))); printf($OFile '

', $fname); } sub smallTable { my $txt = shift; $txt =~ s|]*>|$&|g; $txt =~ s|]*>|$&|g; $txt =~ s|]*>|$&|g; $txt =~ s|]*>|$&|g; return $txt; } sub init { die(&usage()) unless &ParseOpts(\%Opts, \@Labels, @ARGV) && @Labels; } sub usage { return "usage: $0 [options]