#!/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(),
load_balancer => undef(),
);
my %SavedOpts = %Opts;
my @BaseTypes = qw(
hit miss
ims.sc200 ims.sc304
redired_req rep_to_redir
head post put abort
cachable uncachable
fill basic ims reload rep
);
# globals
my @Labels;
&init();
exit(&main());
sub main {
if ($Opts{load_balancer}) {
@BaseTypes = grep { !/^(hit|miss|fill)$/ } @BaseTypes;
}
foreach my $label (@Labels) {
makeReport($label);
}
return 0;
}
sub makeReport {
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, '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 {
&openSection('Executive summary');
&reportExSummary();
&closeSection();
&openSection('Engineer summary');
print($OFile &substNamesInHTML('
[log.count||"Unknown number of"] logs
were used to generate this report.
'));
&reportTput();
&reportHits() unless $Opts{load_balancer};
&reportChb();
&reportTimes();
&reportWait();
&reportStreams();
&reportConns();
&reportSizes();
&reportClasses();
&reportErrors();
# print some warnings if needed
my @wobjs = (&getWarnObjs());
if (grep { $_->{warn_txt} } @wobjs) {
my $hasDiff = 0;
print($OFile "
Potential problems:\n
\n");
foreach my $obj (@wobjs) {
next unless $obj->{warn_txt};
printf($OFile "\t
... where A differs from B by X% means X = 100*(A-B)/B.
\n")
if $hasDiff;
}
&closeSection();
}
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
Phases: [name]
HTML
if ($Opts{load_balancer}) {
$html =~ s|^.*misses:.*$||m;
$html =~ s|^.*hits:.*$||m;
$html =~ s|^.*Hit Ratio:.*$||m;
}
print($OFile &substNamesInHTML($html));
}
sub reportTput {
my $html = <
Load
Count (xact/sec)
Volume (Mbit/sec)
Offered:
[req.rate]
[req.bw/$Mbit]
Measured:
[rep.rate]
[rep.bw/$Mbit]
TABLE
if (&objVal('_have_icp_stats')) {
$html .= <
ICP reqs:
[icp.req.rate]
[icp.req.bw/$Mbit]
ICP reps:
[icp.rep.rate]
[icp.rep.bw/$Mbit]
TABLE
}
$html .= <
TABLE
print($OFile &substNamesInHTML($html));
}
sub reportHits {
my $html = <
Hit Ratios
DHR (%)
BHR (%)
Offered:
[offered.hit.ratio.obj]
[offered.hit.ratio.byte]
Measured:
[hit.ratio.obj]
[hit.ratio.byte]
TABLE
if (&objVal('_have_icp_stats')) {
$html .= <
ICP:
[icp.hit.ratio.obj]
[icp.hit.ratio.byte]
TABLE
}
$html .= <
TABLE
print($OFile &substNamesInHTML($html));
}
sub reportChb {
my $html = <
Cachability Ratios
Count (%)
Volume (%)
Measured:
[cachable.ratio.obj]
[cachable.ratio.byte]
TABLE
print($OFile &substNamesInHTML($html));
}
sub reportTimes {
my @types = ( 'byte', @BaseTypes );
my @measures = qw( min median mean max );
push @types, map { "icp.$_" } qw ( hit miss rep ) if
&objVal('_have_icp_stats');
print $OFile <
Response Times
Response Time (msec)
Min
Median
Mean
Max
TABLE
my $html = '';
foreach my $type (@types) {
$html .= "
$type
\n";
foreach my $meas (@measures) {
if ( $type eq 'byte' && $meas ne 'mean' ){
$html .= "\t
TABLE
print($OFile &substNamesInHTML($html));
}
sub reportStreams {
&reportStreamRates();
&reportStreamTotals();
}
sub reportStreamRates {
my $html = <
Stream Rates
Count (rep/sec)
Volume (Mbit/sec)
TABLE
my @types = @BaseTypes;
push @types, map { "icp.$_" } qw ( hit miss rep ) if
&objVal('_have_icp_stats');
for my $type (@types) {
$html .= "
$type
[$type.rate]
[$type.bw/$Mbit]
\n";
}
$html .= '
';
print($OFile &substNamesInHTML($html));
}
sub reportStreamTotals {
my $html = <
Stream Totals
Count (rep*106)
Volume (GByte)
TABLE
my @types = @BaseTypes;
push @types, map { "icp.$_" } qw ( hit miss rep ) if
&objVal('_have_icp_stats');
for my $type (@types) {
$html .= "
$type
[$type.size.count/1e6]
[$type.size.sum/$GByte]
\n";
}
$html .= '
';
print($OFile &substNamesInHTML($html));
}
sub reportConns {
my $html = <
Connection Length
Min
Mean
Max
Use (xact/conn)
[conn.use.min]
[conn.use.mean]
[conn.use.max]
Life time (msec)
[conn.ttl.min]
[conn.ttl.mean]
[conn.ttl.max]
TABLE
print($OFile &substNamesInHTML($html));
}
sub reportSizes {
my @types = @BaseTypes;
my @measures = qw( min median mean max );
push @types, map { "icp.$_" } qw ( hit miss rep ) if
&objVal('_have_icp_stats');
print $OFile <
Object Sizes
Size (KB)
Min
Median
Mean
Max
TABLE
my $html = '';
foreach my $type (@types) {
$html .= "