20.13. Processing Server LogsProblemYou need to summarize your server logs, but you don't have a customizable program to do it. SolutionParse the error log yourself with regular expressions, or use the Logfile modules from CPAN. DiscussionExample 20.9 is a sample report generator for an Apache weblog. Example 20.9: sumwww#!/usr/bin/perl -w
# sumwww - summarize web server log activity
$lastdate = "";
daily_logs();
summary();
exit;
# read CLF files and tally hits from the host and to the URL
sub daily_logs {
while (<>) {
($type, $what) = /"(GET|POST)\s+(\S+?) \S+"/ or next;
($host, undef, undef, $datetime) = split;
($bytes) = /\s(\d+)\s*$/ or next;
($date) = ($datetime =~ /\[([^:]*)/);
$posts += ($type eq POST);
$home++ if m, / ,;
if ($date ne $lastdate) {
if ($lastdate) { write_report() }
else { $lastdate = $date }
}
$count++;
$hosts{$host}++;
$what{$what}++;
$bytesum += $bytes;
}
write_report() if $count;
}
# use *typeglob aliasing of global variables for cheap copy
sub summary {
$lastdate = "Grand Total";
*count = *sumcount;
*bytesum = *bytesumsum;
*hosts = *allhosts;
*posts = *allposts;
*what = *allwhat;
*home = *allhome;
write;
}
# display the tallies of hosts and URLs, using formats
sub write_report {
write;
# add to summary data
$lastdate = $date;
$sumcount += $count;
$bytesumsum += $bytesum;
$allposts += $posts;
$allhome += $home;
# reset daily data
$posts = $count = $bytesum = $home = 0;
@allwhat{keys %what} = keys %what;
@allhosts{keys %hosts} = keys %hosts;
%hosts = %what = ();
}
format STDOUT_TOP =
@|||||||||| @|||||| @||||||| @||||||| @|||||| @|||||| @|||||||||||||
"Date", "Hosts", "Accesses", "Unidocs", "POST", "Home", "Bytes"
----------- ------- -------- -------- ------- ------- --------------
.
format STDOUT =
@>>>>>>>>>> @>>>>>> @>>>>>>> @>>>>>>> @>>>>>> @>>>>>> @>>>>>>>>>>>>>
$lastdate, scalar(keys %hosts),
$count, scalar(keys %what),
$posts, $home, $bytesum
.Here's sample output from that program:
Use the Logfile::Apache module from CPAN, shown in Example 20.10, to write a similar, but less specific, program. This module is distributed with other Logfile modules in a single Logfile distribution (Logfile-0.115.tar.gz at the time of writing). Example 20.10: aprept#!/usr/bin/perl -w
# aprept - report on Apache logs
use Logfile::Apache;
$l = Logfile::Apache->new(
File => "-", # STDIN
Group => [ Domain, File ]);
$l->report(Group => Domain, Sort => Records);
$l->report(Group => File, List => [Bytes,Records]);The To produce a report on STDOUT, call the Here's some sample output:
See AlsoThe documentation for the CPAN module Logfile::Apache; perlform (1) and the section on "Formats" in Chapter 2 of Programming Perl |