#! /usr/bin/perl -w
use POSIX qw(strftime);
use Time::Local;
%statusdefs = (
'200' => 'OK',
'206' => 'Partial Content',
'301' => 'Moved Permanently',
'302' => 'Moved Temporarily',
'304' => 'Not Modified',
'403' => 'Forbidden',
'404' => 'Not Found',
'500' => 'Internal Server Error',
);
for $month (0..11) {
$monthname = strftime "%b", localtime(timelocal(0,0,0,1,$month,70));
$mname{$monthname}=$month;
}
%statuses=();
%methods=();
%protocolvers=();
%useragents=();
%hostnames=();
%filenames=();
$numreqs=$totalsize=$idents=$remoteusers=$referers=0;
$earliest=time; $latest=0;
while (defined ($line=<>)) {
chomp($line);
next if ($line eq "");
($hostname, $ident, $remoteuser, $timestamp, $request, $status, $size, $referer, $useragent) =
($line =~ m/^(.*?) +(.*?) +(.*?) +(\[.*?\]) +\"(.*?)\" +(\d*) +([\d-]*) +\"(.*?)\" +\"(.*?)\"/);
$numreqs++;
$hostnames{$hostname}++;
$idents++ unless ($ident eq "-");
$remoteusers++ unless ($remoteuser eq "-");
($mday,$mon,$year,$hours,$min,$sec) =
($timestamp =~ m#^\[(\d+)/(\w+)/(\d+):(\d+):(\d+):(\d+).*$#);
$etime = timelocal($sec,$min,$hours,$mday,$mname{$mon},$year-1900);
$earliest = $etime if ($etime < $earliest);
$latest = $etime if ($etime > $latest );
($method, $filename, $protocol) = ($request =~ m/^(\w+) ([^?]*).* (HTTP\/[\d\.]*)/);
$methods{$method}++;
$filenames{$filename}++;
$protocolvers{$protocol}++;
$statuses{$status}++;
$totalsize+=$size unless ($size eq "-");
$referers++ unless ($referer eq "-");
$useragents{$useragent}++;
}
($user, $system, undef, undef) = times;
print "\n";
print "$totalsize total bytes served in $numreqs requests\n";
$timespan = ($latest-$earliest)/86400;
$timespan++ if ($timespan == 0);
printf ("requests per day: %0.2f\n", $numreqs/$timespan);
printf "seconds per request: %0.2f\n", (($latest-$earliest)/$numreqs);
print "average of ",int($totalsize/$numreqs)," bytes/req\n";
print "requests with valid idents: $idents\n";
print "requests with valid remote users: $remoteusers\n";
print "requests with referers: $referers ";
printf ("(%1.1f%%)\n", 100*($referers/$numreqs));
print "\nstatus summary:\n";
for (sort keys %statuses) {
printf("\t%03d\t%d\t(%1.1f%%)", $_, $statuses{$_}, 100*($statuses{$_}/$numreqs));
if ($statusdefs{$_}) {
print "\t",$statusdefs{$_};
}
print "\n";
}
print "\nmethod summary:\n";
for (sort keys %methods) {
printf ("\t%s\t%s\t(%1.1f%%)\n", $_, $methods{$_}, 100*($methods{$_}/$numreqs));
}
print "\nprotocol version summary:\n";
for (sort keys %protocolvers) {
printf( "\t%s\t%s\t(%1.1f%%)\n", $_, $protocolvers{$_}, 100*($protocolvers{$_}/$numreqs) );
}
$uniquseragents=0;
for (keys %useragents) {
$uniquseragents++;
}
print "\nno of unique user agents: $uniquseragents\n";
print "(avg reqs/agent: ",int($numreqs/$uniquseragents),")\n";
$uniqhostnames=0;
for (keys %hostnames) {
$uniqhostnames++;
}
print "\nno of unique hostnames: $uniqhostnames\n";
print "(avg reqs/hostname: ",int($numreqs/$uniqhostnames),")\n";
$uniqfilenames=0;
for (keys %filenames) {
$uniqfilenames++;
}
print "\nno of unique filenames in reqs: $uniqfilenames\n";
print "\n(${user}s, ${system}s, ";
printf "%0.2f lines/sec)\n", $numreqs/$user;