#!/usr/bin/perl $version="1.0"; %MonthToNumber=( 'Jan','01', 'Feb','02', 'Mar','03', 'Apr','04', 'May','05', 'Jun','06', 'Jul','07', 'Aug','08', 'Sep','09', 'Oct','10', 'Nov','11', 'Dec','12', ); require "ctime.pl"; $zcat = "/usr/contrib/bin/gzip -cd"; # Name of server $HTTPDSERVER='www.clubparadise.com'; # Type of log being parsed $LogType="common"; exit if ($#ARGV == -1); $hitscounter=0; &Initialize; &IncludeOldFile if ($IncludeFile); foreach $Filename (@ARGV) { $ACCESSLOGFILE = $Filename; next if (! -e $ACCESSLOGFILE); # skip it if it doesn't exist if ($ACCESSLOGFILE =~ m#\.gz$#) { # Handle compressed files $ACCESSLOGFILE = "$zcat $ACCESSLOGFILE |"; } open(ACCESSLOG,"$ACCESSLOGFILE") || die "Can't open ${ACCESSLOGFILE}: $!"; while($line=) { chop $line; if (($LogType eq 'common') || ($LogType eq 'combined')) { ($Domain,$rfc931,$authuser,$TimeDate,$Request,$Status,$Bytes) = $line =~ /^(\S+) (\S+) (\S+) \[([^\]\[]+)\] \"([^"]*)\" (\S+)/o; } # Date format sample: 07/Nov/1995:23:59:07 -0800 ($day,$monthname,$year,$hour,$minute,$second,$tzone)= $TimeDate =~ m#^(\d+)/(\w+)/(\d+):(\d+):(\d+):(\d+)\s+(\S+)$#o; $month=$MonthToNumber{$monthname}; $hour = "0$hour" if (length($hour) ==1); $day = "0$day" if (length($day) ==1); $datestring="${year}${month}${day}${hour}${minute}${second}"; ($Method,$File,$Protocal)=split(/\s/,$Request,3); next if ($Status != 200); next if ($authuser eq '-'); next if (! ($authuser && $Domain)); $hitscounter++; $Domain=~ s#<#\<\;#og; # prevent accidents with '<' $Domain=~ s#>#\>\;#og; # prevent accidents with '>' $Domain=~ s#\&#\&\;#og; # prevent accidents with '&' $Domain=~ s#"#\"\;#og; # prevent accidents with '"' $Domain=~ tr/A-Z/a-z/; # no more playing around with case problems $authuser=~ s#<#\<\;#og; # prevent accidents with '<' $authuser=~ s#>#\>\;#og; # prevent accidents with '>' $authuser=~ s#\&#\&\;#og; # prevent accidents with '&' $authuser=~ s#"#\"\;#og; # prevent accidents with '"' $keyform="$authuser $Domain"; $UserCounter{$authuser}++; $AccountDomainCounter{$keyform}++; if ($UserLastAccessTick{$authuser} < $datestring) { $UserLastAccessTick{$authuser} = $datestring; $UserLastAccessDisplay{$authuser} = $TimeDate; } } close(ACCESSLOG); } # Print the report if ($OutputFile) { open (OUTPUTFILE,">$OutputFile") || die ("Could not open $OutputFile for writing.\n$!"); select(OUTPUTFILE); } print "Account Statistics for ", "${HTTPDSERVER}\n\n", "$hitscounter accesses examined this run.
\n", "Last updated: ",&ctime(time),"

"; print "

\n"; $LastUser=''; foreach $key (sort byAccountthenhits keys(%AccountDomainCounter)) { ($authuser,$Domain)=split(/ /,$key,2); if ("$authuser" ne "$LastUser") { print "
$authuser ($UserCounter{$authuser} access"; print "es" if ($UserCounter{$authuser} > 1); print ", last one at $UserLastAccessDisplay{$authuser})
\n"; } print "
$Domain ($AccountDomainCounter{$key} access"; print "es" if ($AccountDomainCounter{$key} > 1); print ")
\n"; $LastUser=$authuser; } print "

\n"; print '


', '', "snowhare\@netimages.com\n"; select(STDOUT); sub byAccountthenhits { ($Accounta)=($a=~m#^(.+)\s#o); ($Accountb)=($b=~m#^(.+)\s#o); $inequality=($Accounta cmp $Accountb); if ($inequality) { $inequality; } else { $AccountDomainCounter{$b}<=>$AccountDomainCounter{$a}; } } # sample include entry for reference #
CP00023 (4703 accesses, last one at 09/Nov/1995:16:00:54 -0800)
#
dmn1-37.usa1.com (1235 accesses)
sub IncludeOldFile { local($day,$monthname,$year,$hour,$minute,$second,$tzone); local($TimeDate,$line,$datestring); if (! open (INCLUSION,$IncludeFile)) { warn "Could not open $IncludeFile for inclusion.\n$!"; return; } while ($line = ) { chop $line; if ($line =~ m#^
(\S+) \((\d+) access.* one at (.*)\)
#o) { $authuser = $1; $hitscounter += $2; $UserCounter{$authuser} += $2; $TimeDate = $3; ($day,$monthname,$year,$hour,$minute,$second,$tzone)= $TimeDate =~ m#^(\d+)/(\w+)/(\d+):(\d+):(\d+):(\d+)\s+(\S+)$#o; $month=$MonthToNumber{$monthname}; $hour = "0$hour" if (length($hour) ==1); $day = "0$day" if (length($day) ==1); $datestring="${year}${month}${day}${hour}${minute}${second}"; $UserLastAccessTick{$authuser} = $datestring; $UserLastAccessDisplay{$authuser} = $TimeDate; next; } next if (! $authuser); if ($line =~ m#^
(\S+) \((\d+) access#o) { $AccountDomainCounter{"$authuser $1"} += $2; } } close(INCLUSION); } sub Initialize { &ReadCommandLine('include:output:name:logtype'); # Old file to read (optional) $IncludeFile = $opt{'include'} if ($opt{'include'}); # Output file (optional - goes to STDOUT if not specified) $OutputFile = $opt{'output'} if ($opt{'output'}); # Type of log (legal: combined, referer) $LogType = $opt{'logtype'} if ($opt{'logtype'}); # Name of server $HTTPDSERVER=$opt{'name'} if ($opt{'name'}); } sub ReadCommandLine { # parse list has the form 'a:b:c' # flags with parse list entries must take values local($parselist)=$_[0]; local(@CommandLine)=@ARGV; local(@ParseList,%ParseRules,@GenericList); (@ParseList)=split(/:/,$parselist); foreach $item (@ParseList) { $ParseRules{$item}=1; } while ($parm=shift(@CommandLine)) { if ($parm =~ m#^\-([a-zA-Z]+)$#o) { $parm=$1; $opt{$parm}=1; if ($ParseRules{$parm}) { $value=shift(@CommandLine); if ($value eq "") { die ("Invalid comand line switch usage, '-$parm' requires value\n"); } $opt{$parm}=$value; } next; } push(@GenericList,$parm); } @ARGV=@GenericList; }