#!/usr/bin/perl -w # modlogrun.pl -- run modlogan onto a set of cronolog log files # with optional splitting into vhosts # # Copyright 2003 Erich Schubert # written for Drinsama IT Services GmbH # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; use File::stat; use File::Basename; my $modlogan='/usr/bin/sudo -u modlogan /usr/bin/modlogan'; my $logresbin='/usr/bin/jdresolve'; my $gzip='/bin/gzip'; my $logresolve=$logresbin.' --recursive --nostats --mask="unknown...%c"'. ' --database=/var/lib/jdresolve/jdresolve.db -'; my $vhostdir="vhosts"; ########################################################################## ### predefinitions sub mkdirpc($$); sub chownref($$); sub splitlog($$); # command line parameters my ($logdir,$vhostmode) = @ARGV; # remember which vhosts do exist and need to be processed my %vhosts; # Some checks if (! -d "$logdir") { die "Log-Direcotry not found!\n"; } if (! -e "$logdir/modlogan.conf") { die "Configuration file not found!\n"; } ### resolve logs, starting with yesterdays log. my $time=time(); while(1) { $time -= 60*60*24; my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time); $mon++; $year+=1900; # Generate file names. my $reslog=sprintf("%04d/%02d/resolved.log-%04d.%02d.%02d",$year,$mon,$year,$mon,$mday); my $acclog=sprintf("%04d/%02d/access.log-%04d.%02d.%02d",$year,$mon,$year,$mon,$mday); # Check if the log was already resolved if (-e "$logdir/$reslog" || -e "$logdir/$reslog.gz") { # it was resolved. This was the last log we have to try. last; } if (! -e "$logdir/$acclog" || -e "$logdir/$reslog.gz") { # If there was no log file the whole month (dir doesn't exist), # we won't search for older logs any more. if (! -d "$logdir/".sprintf("%04d/%02d",$year,$mon)) { last; } # single days without a log file are skipped this way. next; } print "Resolving logfile $acclog...\n"; system("$logresolve < \"$logdir/$acclog\" > \"$logdir/$reslog\""); chownref("$logdir/$reslog","$logdir/$acclog"); # Compress unresolved log file after resolving. system("$gzip \"$logdir/$acclog\""); # Do we need to split the logfile into vhosts? if ($vhostmode) { print "Splitting $reslog into vhosts...\n"; my @this_vhosts = splitlog($logdir,$reslog); # Build a map of existing vhosts foreach my $vhost (@this_vhosts) { $vhosts{$vhost}=1; } } } ### Configuration generation for vhosts. foreach my $vhost (keys %vhosts) { # generate missing vhost modlogan config files... if (! -e "$logdir/$vhostdir/$vhost/modlogan.conf") { open(TEMPLATE,"<$logdir/$vhostdir/modlogan.conf.template"); open(OUTPUT,">$logdir/$vhostdir/$vhost/modlogan.conf"); my $hostnameesc=$vhost; $hostnameesc =~ s/\./\\./g; $hostnameesc =~ s/^www\./(www\\.)?/; while(