#!YOUR_PERL_BINARY
# ==========================================================================
# Copyright (c) 1996 Regents of the University of California.
#
# This software has been developed by Roy Fielding <fielding@ics.uci.edu> as
# part of the WebSoft project at the University of California, Irvine.
#         <http://www.ics.uci.edu/pub/websoft/wwwstat/>
# See the file LICENSE for licensing and redistribution information.
#
# This program is provided ONLY as an example.  It is not needed to run
# wwwstat and is not supported by the author.
#
sub usage {
    die <<"EndUsage";
USAGE:  monthly

  THIS PROGRAM MUST ONLY BE RUN ONCE PER MONTH, DURING THE FIRST WEEK
  It assumes a lot, like that you use wwwstat and archive your logfiles
  once per month.  You will need to configure it for your server before
  it can be used.

  Reads the logfile (assumed to contain more than one month's worth
  of WWW common logfile entries) and moves the prior month's entries
  into a separate file.  The new file is created on TMPDIR (to avoid
  filling up the disk), compressed using gzip, and then moved to the
  archive directory.  The program also restarts the httpd server.

EndUsage
}
if ($#ARGV >= 0) { &usage; }
# ==========================================================================
# Get defaults

umask(022);

# Compression command and extension

$zcommand    = 'gzip -9';
$zextension  = '.gz';

$wstatcmd    = 'wwwstat';

# Set up the filenames to be used

$ServerRoot = '/usr/local/etc/httpd';

$NewLog   = $ServerRoot . '/logs/access_log';    # Current logfile
$OldLog   = $NewLog . '.old';                    # and temp location

$PidFile  = $ServerRoot . '/logs/httpd.pid';     # Server's PID file
$ErrorLog = $ServerRoot . '/logs/error_log';     # Server's Error Log

$TempLog = "/tmp/templog-$$.txt";      # Temporary file for last month's log

print "Got the defaults\n";

# ==========================================================================
# Figure out the archive name

$ArcName = "/dc/ud/www/oldlogs/%M_access_log" . $zextension;

@MoY = ('Jan','Feb','Mar','Apr','May','Jun',
        'Jul','Aug','Sep','Oct','Nov','Dec');

($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
if ($mon == 0) { $mon = 11; $year -= 1; }
else           { $mon -= 1; }

$LastMonth = $MoY[$mon];

$ArcName  =~ s/%M/$LastMonth$year/;

$ArcStats = '/dc/ud/www/documentroot/Admin/stats-19' . $year .
            '/' . $LastMonth . '.wwwstats.html';

print "Figured out that last month was $LastMonth $year\n";

# ==========================================================================
# Open logfiles

if (-e $OldLog)             { die "$OldLog already exists, stopped"; }

rename($NewLog, $OldLog)   || die "$!: Failed to rename $NewLog, stopped";

open(OLDLOG, $OldLog)      || die "$!: Failed to open $OldLog, stopped";

open(TEMPLOG, ">$TempLog") || die "$!: Failed to open $TempLog, stopped";

open(NEWLOG, ">$NewLog")   || die "$!: Failed to open $NewLog, stopped";

print "Successfully opened the log files\n";

# ==========================================================================
# Iterate through the old logfile

print "Splitting $NewLog\n";

LINE: while (<OLDLOG>)
{
    #
    # First, parse the common log format into its seven basic components
    #

    ($host, $rfc931, $authuser, $timestamp, $request, $status, $bytes) =
        /^(\S+) (\S+) (\S+) \[([^\]]*)\] \"([^"]*)\" (\S+) (\S+)/;

    # Now, is this garbage or is it memorex?  Note that $bytes can be 0

    if (!($host && $rfc931 && $authuser && $timestamp && $request && $status))
    {
        next LINE;
    }

    # Finally, extract the month and determine where to write this entry

    $month = substr($timestamp, 3, 3);

    if ($month eq $LastMonth) { print TEMPLOG; }
    else                      { print NEWLOG; }
}
close(OLDLOG);
close(TEMPLOG);
close(NEWLOG);

print "Successfully processed the logfiles\n";

# Restart the httpd server

if ($PidFile)
{
    rename($ErrorLog, $ErrorLog . '.old');   # Reset the error log as well
    if (open(PID, $PidFile))
    {
        chop($_ = <PID>);
        kill 1, $_;
        close(PID);
        print "Restarted httpd at $_\n";
    }
}

# Delete the old logfile

print "Deleting $OldLog\n";
system('rm','-f', $OldLog);
if (-e $OldLog) { print STDERR "Warning: Failed to delete $OldLog\n"; }

# Run wwwstat on the temporary log to get last month's stats

print "Creating monthly stats in $ArcStats\n";
system("$wstatcmd $TempLog > $ArcStats");
system("$zcommand $ArcStats");

# Compress the temporary logfile

print "Compressing last month's log\n";

system("$zcommand $TempLog");
if (-e $TempLog) { die "Failed to $zcommand $TempLog\n"; }
$TempLog .= $zextension;

# Move the temporary logfile to its archive location

print "Moving last month's log to $ArcName\n";
system('mv','-f', $TempLog, $ArcName);
if (!(-e $ArcName)) { die "Failed to move $TempLog to $ArcName\n"; }

print "Finished Job\n";

exit(0);

