Monday, October 25, 2010

best practice A: use perl to calculate avalance result.

[root@localhost cal_avalanche_sustained]# ./avalAnalyzer.pl realtime.csv
Use of uninitialized value in addition (+) at ./avalAnalyzer.pl line 232, line 432.
Use of uninitialized value in addition (+) at ./avalAnalyzer.pl line 232, line 432.
Use of uninitialized value in addition (+) at ./avalAnalyzer.pl line 237, line 432.
Use of uninitialized value in addition (+) at ./avalAnalyzer.pl line 237, line 432.
Argument "\n" isn't numeric in numeric ge (>=) at ./avalAnalyzer.pl line 267, line 432.

Avalanche Stats
---------------
Avg Packet Size (in/out/both): 175 / 103 / 132 (Bytes)
Throughput (in/out/both)
Avg: 223.74 / 201.14 / 422.87 (Mbps) [Sd: 134.69 (31.9%)]
Max: 382.27 / 351.53 / 730.50 (Mbps)
HTTP Transactions Per Second
Avg: 94931 [Sd: 28450 (30.0%)]
Max: 160452
Response Time
Avg: 623.81 (ms) [Sd: 3196.82 (512.5%)]
Max: 30000.58 (ms)
Packet Rate (in/out/both)
Avg: 160507 / 243390 / 401464 (pps) [Sd: 128969 (32.1%)]
Max: 283360 / 425252 / 708612 (pps)
Concurrent Connections
Avg: 266 [Sd: 61 (23.1%)]
Max: 466
Connections Per Second
Avg: 94928 [Sd: 28459 (30.0%)]
Max: 160880
Cumulative Success 100.00%, Abort 0.00%, Fail 0.00%

[root@localhost cal_avalanche_sustained]#
use Getopt::Long;

# 10m steady state
my $startTime = 240;
my $endTime = 700;

my $kilo = 1000;
#my $kilo = 1024;

sub usage()
{
use File::Basename;
my $program = basename($0);

print STDERR << "EOF";
Usage: $program [options]

Options:
-type stats type: smtp, pop3, ftp, http, all

-s startTime
-e endTime

-m10 startTime=240, endTime=700: good for standard 10 min steady state
Aval config -- rampUp=120s, sustained=600s, rampDown=60s [Default]

-m5 startTime=100, endTime=340: good for standard 5 min steady state
Aval config -- rampUp=60s, sustained=300s, rampDown=60s

-m2 startTime=50, endTime=140: good for standard 2 min steady state
Aval config -- rampUp=30s, sustained=120s, rampDown=30s

-page_resp caculate HTTP response time per page [default: 1st TCP byte]
-url_resp caculate HTTP response time per url [default: 1st TCP byte]

-help

EOF
exit;
}

my $header = "
Avalanche Stats
---------------
";

my %names =
(
"seconds" => "Seconds Elapsed",
"success" => "Cumulative Successful Transactions",
"fail" => "Cumulative Unsuccessful Transactions",
"abort" => "Cumulative Aborted Transactions",
"thPutIn" => "Incoming Traffic (Kbps)",
"thPutOut" => "Outgoing Traffic (Kbps)",
"rateIn" => "Incoming Packets (Packets/sec)",
"rateOut" => "Outgoing Packets (Packets/sec)",
"conns" => "Current Established TCP Connections",
"cps" => "Established TCP Connection Rate (Connections/sec)",
"respTime" => "Average Time to TCP First Byte (msec)",
"http_tps" => "Successful Transactions/Second",
"smtp_sps" => "SMTP: Successful Sessions Per Sec",
"pop3_sps" => "POP3: Successful Sessions Per Sec",
"ftp_sps" => "FTP: Successful Sessions Per Sec",
"dns_qps" => "DNS: Successful Queries Per Sec",
"telnet_cps" => "Telnet: Successful Sessions Per Sec",
);


sub mapFields ($$)
{
my ($input, $fieldRef) = @_;

my (@fields) = split(/,/, $input);

for (my $i = 0; $i < @fields; $i++) {
if (%names) {
foreach (keys %names) {
if ($names{$_} eq $fields[$i]) {
$fieldRef->{$_} = $i;
delete($names{$_});
last;
}
}
}
else {
last;
}
}
}

sub Mean
{
my $arrayref = shift;
return undef unless defined $arrayref && @$arrayref > 0;
my $result;
foreach (@$arrayref) {$result += $_}
return $result / @$arrayref;
}

sub StandardDeviation
{
my $arrayref = shift;
my $mean = shift;
return undef unless defined $arrayref && @$arrayref > 0;
$mean = Mean($arrayref) unless defined $mean;
return sqrt(abs(Mean([map $_**2, @$arrayref]) - ($mean**2)));
}

my ($resp_page, $resp_url);

my $help;
GetOptions(
"page_resp" => \$resp_page,
"url_resp" => \$resp_url,
"m10" => \$runtime10m,
"m5" => \$runtime5m,
"m2" => \$runtime2m,
"start=i" => \$startTime,
"end=i" => \$endTime,
"type=s" => \$statType,
"help" => \$help,
) or usage();

usage if ($help);

my $input = shift || usage();

if (! open(IN,"<$input") ) {
die "Can't open input file $input: $!";
}

# 10m steady state
if ($runtime10m) {
$startTime = 240;
$endTime = 700;
}

# 5m steady state
if ($runtime5m) {
$startTime = 100;
$endTime = 340;
}

# 2m steady state
if ($runtime2m) {
$startTime = 50;
$endTime = 140;
}

my @realtimeStats = ("thPutIn", "thPutOut", "rateIn", "rateOut", "respTime",
"cps", "conns");

my @derivedStats = ("thPutBoth", "rateBoth", "sizeIn", "sizeOut", "sizeBoth");

my @cumuStats = ("success", "fail", "abort");

my @maxStatNames = ("thPutIn", "thPutOut", "thPutBoth",
"rateIn", "rateOut", "rateBoth",
"cps", "conns", "respTime");

my @sdStats = ("thPutBoth", "rateBoth", "respTime", "cps", "conns");

my @trans;
my %transNames = (
"http_tps" => "HTTP Transactions Per Second",
"ftp_sps" => "FTP Sessions Per Second",
"pop3_sps" => "POP3 Sessions Per Second",
"smtp_sps" => "SMTP Sessions Per Second",
"dns_qps" => "DNS Queries Per Second",
"telnet_cps" => "Telnet Connections Per Second",
);

if (lc($statType) eq "http") {
@trans = ("http_tps");
$names{"respTime"} = "Current Response Time Per Page (msec)" if ($resp_url);
$names{"respTime"} = "Current Response Time Per URL (msec)" if ($resp_page);
}
elsif (lc($statType) eq "ftp") {
@trans = ("ftp_sps");
}
elsif (lc($statType) eq "pop3") {
@trans = ("pop3_sps");
}
elsif (lc($statType) eq "smtp") {
@trans = ("smtp_sps");
}
elsif (lc($statType) eq "dns") {
@trans = ("dns_qps");
}
elsif (lc($statType) eq "telnet") {
@trans = ("telnet_cps");
}
else {
@trans = ("http_tps", "ftp_sps", "pop3_sps", "smtp_sps", "dns_qps", "telnet_cps");
$names{"respTime"} = "Current Response Time Per Page (msec)" if ($resp_url);
$names{"respTime"} = "Current Response Time Per URL (msec)" if ($resp_page);
}

push(@realtimeStats, @trans);
push(@maxStatNames, @trans);
push(@sdStats, @trans);

my @allStats = ();
push(@allStats, @realtimeStats, @derivedStats);

my @stats = undef;
my %cooked = ();
my %maxStats = ();
my %mean = ();
my %sd = ();
my %field;

my %cumu;
$cumu{$_} = 0 foreach (@cumuStats);

while () {

if (! %field) {

mapFields($_, \%field) if (/^Seconds Elapsed/);

}
else {

@stats = split /,/;

%cooked = ();

# Throughput
#
$cooked{thPutBoth} = $stats[$field{thPutIn}] + $stats[$field{thPutOut}];


# Packet Rate
#
$cooked{rateBoth} = $stats[$field{rateIn}] + $stats[$field{rateOut}];

# Avg Packet Size
#
if ($stats[$field{rateIn}] && $stats[$field{rateOut}]) {
$cooked{sizeIn} = $stats[$field{thPutIn}] * $kilo / 8 /
$stats[$field{rateIn}];
$cooked{sizeOut} = $stats[$field{thPutOut}] * $kilo / 8 /
$stats[$field{rateOut}];
$cooked{sizeBoth} = $cooked{thPutBoth} * $kilo / 8 /
$cooked{rateBoth};
}

foreach (@maxStatNames) {
my $stat = undef;

if ($field{$_}) {
$stat = $stats[$field{$_}];
}
elsif ($cooked{$_}) {
$stat = $cooked{$_};
}

if ($stat) {
if (!exists($maxStats{$_}) || $stat > $maxStats{$_}) {
$maxStats{$_} = $stat;
}
}
}

if ($stats[0] >= $startTime && $stats[0] <= $endTime) {

foreach (@realtimeStats) {
push(@$_, $stats[$field{$_}]) if ($stats[$field{$_}]);
}

foreach (@derivedStats) {
push(@$_, $cooked{$_}) if ($cooked{$_});
}

foreach (@cumuStats) {
if ($stats[$field{$_}] > $cumu{$_}) {
$cumu{$_} = $stats[$field{$_}];
}
}
}

}
}

close IN;

die "*** Aborted: $input not a Avalanche output\n" if (! %field);

foreach (@allStats) {
$mean{$_} = Mean(\@$_);
}

foreach (@sdStats) {
$sd{$_} = StandardDeviation(\@$_, $mean{$_});
}

print "$header";

if (defined($mean{sizeBoth})) {
printf "Avg Packet Size (in/out/both): %.0f / %.0f / %.0f (Bytes)\n",
$mean{sizeIn}, $mean{sizeOut}, $mean{sizeBoth};
}

if (defined($mean{thPutBoth})) {
print "Throughput (in/out/both)\n";
if ($mean{thPutBoth}) {
printf " Avg: %.2f / %.2f / %.2f (Mbps) [Sd: %.2f (%.1f%%)]\n",
$mean{thPutIn}/$kilo, $mean{thPutOut}/$kilo,
$mean{thPutBoth}/$kilo, $sd{thPutBoth}/$kilo,
$sd{thPutBoth}*100/$mean{thPutBoth};
}
else {
printf " Avg: %.2f / %.2f / %.2f (Mbps)\n",
$mean{thPutIn}/$kilo, $mean{thPutOut}/$kilo,
$mean{thPutBoth}/$kilo;
}
printf " Max: %.2f / %.2f / %.2f (Mbps)\n",
$maxStats{thPutIn}/$kilo, $maxStats{thPutOut}/$kilo,
$maxStats{thPutBoth}/$kilo;
}

foreach (@trans) {
if (defined($mean{$_})) {
print "$transNames{$_}\n";
if ($mean{$_} != 0) {
printf " Avg: %.0f [Sd: %.0f (%.1f%%)]\n",
$mean{$_}, $sd{$_}, $sd{$_}*100/$mean{$_};
} else {
printf " Avg: %.0f\n", $mean{$_};
}
printf " Max: %.0f\n", $maxStats{$_};
}
}

if (defined($mean{respTime})) {
print "Response Time\n";
if ($mean{respTime}) {
printf " Avg: %.2f (ms) [Sd: %.2f (%.1f%%)]\n",
$mean{respTime}, $sd{respTime}, $sd{respTime}*100/$mean{respTime};
}
else {
printf " Avg: %.2f (ms)\n", $mean{respTime};
}
printf " Max: %.2f (ms)\n", $maxStats{respTime};
}

if (defined($mean{rateBoth})) {
print "Packet Rate (in/out/both)\n";
if ($mean{rateBoth}) {
printf " Avg: %.0f / %.0f / %.0f (pps) [Sd: %.0f (%.1f%%)]\n",
$mean{rateIn}, $mean{rateOut}, $mean{rateBoth},
$sd{rateBoth}, $sd{rateBoth}*100/$mean{rateBoth};
} else {
printf " Avg: %.0f / %.0f / %.0f (pps)\n",
$mean{rateIn}, $mean{rateOut}, $mean{rateBoth};
}
printf " Max: %.0f / %.0f / %.0f (pps)\n",
$maxStats{rateIn}, $maxStats{rateOut}, $maxStats{rateBoth};
}

if (defined($mean{conns})) {
print "Concurrent Connections\n";
if ($mean{conns}) {
printf " Avg: %.0f [Sd: %.0f (%.1f%%)]\n",
$mean{conns}, $sd{conns}, $sd{conns}*100/$mean{conns};
} else {
printf " Avg: %.0f\n", $mean{conns};
}
printf " Max: %.0f\n", $maxStats{conns};
}

if (defined($mean{cps})) {
print "Connections Per Second\n";
if ($mean{conns}) {
printf " Avg: %.0f [Sd: %.0f (%.1f%%)]\n",
$mean{cps}, $sd{cps}, $sd{cps}*100/$mean{cps};
} else {
printf " Avg: %.0f\n", $mean{cps};
}
printf " Max: %.0f\n", $maxStats{cps};
}

my $cumulativeAttempts = $cumu{success} + $cumu{abort} + $cumu{fail};
if ($cumulativeAttempts) {
$successRate = $cumu{success} * 100 / $cumulativeAttempts;
$abortRate = $cumu{abort} * 100 / $cumulativeAttempts;
$failRate = $cumu{fail} * 100 / $cumulativeAttempts;
printf "Cumulative Success %.2f%%, Abort %.2f%%, Fail %.2f%%\n\n",
$successRate, $abortRate, $failRate;
}

# vim: sw=4 sts=4 sta et

No comments:

Post a Comment