Listing 1

#!/usr/local/bin/perl

use DB_File;
use Fcntl;

$db_file = "weekly.db";
$high_id = 0;

tie (%STATS, DB_File, $db_file, O_RDWR|O_CREAT, 0644, $DB_HASH);

while (($id, $value) = each %STATS) {
   $id > $high_id && ($high_id = $id);

   ($document, $bytes) = split(/\*/, $value);

   $doc_hits{$document}++;
   $doc_bytes{$document}+=$bytes;

   $hits++;
}

$id = $high_id+1;

while(<>) {
   next if /^$/;

   $hits++;

   /^([A-Za-z0-9\._-]+)[^"]*"([^"]+)" ([0-9]+) ([0-9]+|\-)/ &&
      ( $hostname=$1, $command=$2, $resp=$3, $bytes=$4 );
   ($type, $document, $version) = split (/ /,$command);

   next if $bytes =~ /^\-$/;
   next if $resp ne "200";

   $doc_hits{$document}++;
   $doc_bytes{$document}+=$bytes;
   $bytes > $doc_size{$document} && ($doc_size{$document}=$bytes);

   $total_bytes+=$bytes;

   $STATS{$id} = join($document, $bytes);
   $id++;
}

untie %STATS;

print <<EOT;
<HTML><HEAD><TITLE>Web
Statistics</TITLE></HEAD><BODY>

<H1>Web Statistics</H1>

<TABLE BORDER=0>
<TR><TD WIDTH=200>Total
Hits</TD><TD>$hits</TD></TR>
<TR><TD WIDTH=200>Total
Bytes</TD><TD>$total_bytes</TD></TR>
</TABLE><P>

Document Information (sorted by hits and document filename):<BR>
<TABLE BORDER=1 WIDTH=100%>
<TR>
   <TD WIDTH=40%>Document</TD>
   <TD WIDTH=15%>Hits</TD>
   <TD WIDTH=15%>Bytes</TD>
   <TD WIDTH=15%>% Hits</TD>
   <TD WIDTH=15%>% Bytes</TD>
</TR>
EOT

sub sort_doc_hits {
   ($doc_hits{$b} <=> $doc_hits{$a}) || ($a cmp $b);
}

for (sort sort_doc_hits keys %doc_hits) {
   $hit_percent = sprintf "%-8.2f", ($doc_hits{$_} / $hits) * 100.0;
   $byte_percent = sprintf "%-8.2f", ($doc_bytes{$_} / $total_bytes) * 100.0;

   $document = pack("A30",$_);

print <<EOT;
<TR>
   <TD><A HREF="$_">$document</A></TD>
   <TD ALIGN=RIGHT>$doc_hits{$_}</TD>
   <TD ALIGN=RIGHT>$doc_size{$_}</TD>
   <TD ALIGN=RIGHT>$hit_percent</TD>
   <TD ALIGN=RIGHT>$byte_percent</TD>
</TR>
EOT
}

print "</TABLE></BODY></HTML>\n";