#!/usr/um/bin/perl

# statanal version 0.90b August 18, 1995
# Copyright (c) 1995 David S. Carter. All rights reserved.
# Permission is granted to freely use and modify for personal use, but not to distribute.
# Information on statanal, licensing agreement, and the latest version, 
# can be obtained at http://www.sils.umich.edu/~superman/AP/

#Simple statistical analysis of transaction log

# Get filename for input
$t1 = 1;
while ($t1) {
	print "Input Filename: ";
	$infile = <STDIN>;
	chop($infile);
	if (-e $infile) {
		$t1 = 0;
		}
	else {
		print "$infile does not exist!\n";
		}
	}

# Get filename for event output
$t2 = 1;
while ($t2) {
	print "Output Filename for events: ";
	$evoutfile = <STDIN>;
	chop($evoutfile);
	if (-e $evoutfile) {
		print "$evoutfile already exists. Okay to overwrite (y/n)[n]? ";
		$q1 = <STDIN>;
		if ($q1 =~ /^(y|Y)/) {
			$t2 = 0;
			}
		}
	else {
		$t2 = 0;
		}
	}

# Get filename for time output
$t2 = 1;
while ($t2) {
	print "Output Filename for time: ";
	$tioutfile = <STDIN>;
	chop($tioutfile);
	if (-e $tioutfile) {
		print "$tioutfile already exists. Okay to overwrite (y/n)[n]? ";
		$q1 = <STDIN>;
		if ($q1 =~ /^(y|Y)/) {
			$t2 = 0;
			}
		}
	else {
		$t2 = 0;
		}
	}

# Open $infile, read in data, close $infile
open (IN, "$infile");
print "Reading $infile \n";
@log = <IN>;
$shtuff = $#log + 1;
print "Read $shtuff lines of data\n";
close (IN);


# Exclude, Include, or Neither?
print "Would you like to Exclude hosts, Only Include certain hosts, or neither (e/i/n)[n]? ";
$opt = <STDIN>;
chop($opt);
if ($opt =~ /^(e|E)/) {
	$t3 = 1;
	$ctr = 0;
	while ($t3) {
		print "Enter host or IP address to exclude (return to end): ";
		$exc = <STDIN>;
		chop($exc);
		if ($exc =~ /^\S/) {
			$exclude[$ctr++] = $exc;
			}
		else {
			$t3 = 0;
			}
		}
	}

elsif ($opt =~ /^(i|I)/) {
	$t3 = 1;
	$ctr = 0;
	while ($t3) {
		print "Enter host or IP address to include (return to end): ";
		$inc = <STDIN>;
		chop($inc);
		if ($inc =~ /^\S/) {
			$include[$ctr++] = $inc;
			}
		else {
			$t3 = 0;
			}
		}
	}


# Get the ball rolling

$ii = 0;
$cntt = 0;

while ($ii < $shtuff) {

	if ($log[$ii] =~ /^\*/) {
	
		# check to see if this request should be included
	
		$doit = 1;
	
		if ($opt =~ /^(e|E)/) {
			for ($tt = 0; $tt <= $#exclude; $tt++) {
				if ($log[$ii + 1] eq $exclude[$tt]) {
					$doit = 0;
					}
				}
			}
		
		elsif ($opt =~ /^(i|I)/) {
			$doit = 0;
			for ($tt = 0; $tt <= $#include; $tt++) {
				if ($log[$ii + 1] eq $include[$tt]) {
					$doit = 1;
					}
				}
			}
	
		# if okay to include, then do it
		if ($doit) {
		
			
			$events[$cntt] = $log[$ii + 4];
			$time[$cntt] = $log[$ii + 9];
			
			if ($log[$ii + 10] != 0) {
				$imload++;
				}
			
			$cntt++;
			}
			
		$ii = $ii + 11 + $log[$ii + 4];
		
		}
		
	else {
		$ii++;
		}
		
	}
	
# run the statistics
print "Running the Statistics\n\n";

print "S T A T I S T I C A L   S U M M A R Y\n\n";
$ggg = $cntt + 1;
print "$ggg transactions were processed\n";
print "$imload transactions loaded images\n\n";

@events_st = sort {$a <=> $b} @events;
@time_st = sort {$a <=> $b} @time;

# calculate event statistics

&statme(@events_st);

print "Event Statistics\n";
print "  Min: $min ";
print "  Max: $max ";
print "  Median: $median ";
print "  Q1: $q1 ";
print "  Q3: $q3 ";
print "  Quartile Skewness: $qskew \n\n";
print "  Mean: $mean \n";
print "  Std. Dev.: $std \n";
print "  Pearson's Second Skewness: $pskew \n";


open (OUT, ">$evoutfile");
print "  Writing ordered data set to $evoutfile \n\n";
foreach $line (@events_st) {
                print OUT ("$line\n");
        }
close (OUT);



&statme(@time_st);

print "Time Statistics (in seconds)\n";
print "  Min: $min ";
print "  Max: $max ";
print "  Median: $median ";
print "  Q1: $q1 ";
print "  Q3: $q3 ";
print "  Quartile Skewness: $qskew \n\n";
print "  Mean: $mean \n";
print "  Std. Dev.: $std \n";
print "  Pearson's Second Skewness: $pskew \n";

open (OUT, ">$tioutfile");
print "  Writing ordered data set to $tioutfile \n\n";
foreach $line (@time_st) {
                print OUT ("$line\n");
        }
close (OUT);

print "\n Analysis Completed\n";




sub statme {

	local (@set) = @_;
	
	$min = $set[0];
	$max = $set[$#set];

	if (($#set/2) == int($#set/2)) {
		$median = $set[$#set/2];
		}
	else {
		$median = ($set[int($#set/2)] + $set[int($#set/2) + 1])/2;
		}
	
	if (($#set/4) == int($#set/4)) {
		$q1 = $set[$#set/4];
		$q3 = $set[$#set - $#set/4];
		}
	else {
		$q1 = ($set[int($#set/4)] + $set[int($#set/4) + 1])/2;
		$q3 = ($set[$#set - int($#set/4)] + $set[$#set - int($#set/4) + 1])/2;
		} 
	
	$mean = &mean(@set);
	
	$runsum = 0;
	
	foreach $entry (@set) {
		$runsum = $runsum + ($entry - $mean)**2;
		}
		
	$std = sqrt($runsum/($#set + 1));
	
	$pskew = 3*($mean - $median)/$std;
	
	$qskew = ($q3 - 2*$q2 + $q1)/($q3 - $q1);
	
	}
	
sub mean {

	local (@pat) = @_;
	
	$rt = 0;
	
	foreach $entry (@pat) {
		$rt = $rt + $entry;
		}
		
	return ($rt/($#pat + 1));
	
	}
