#!/usr/bin/perl # dspam_logrotate.pl - Removed old entries from DSpam log files. # Steve Pellegrin (spellegrin at convoglio dot com) # # History: # 1.0 2005-January-1 Original code # # Usage: # dspam_logrotate.pl -v -a days logfile ... # -v: Print verbose output # -a days: All log entries older than 'days' will be removed. # logfile: A list of one or more files to process. # ########################################################### # # Print usage info # sub usage { print "Usage: " . $0 . " -a age [-v] logfile ...\n"; } ########################################################### ########################################################### # # "Rotate" one log file # sub rotate { # Give names to input args. my($filename); my($cutoffTimestamp); my($printStats); ($filename, $cutoffTimestamp, $printStats) = @_; # Generate names for the temporary files. my($tempInputFile) = $filename . ".in"; my($tempOutputFile) = $filename . ".out"; # Rename the log file to the temporary input file name. rename $filename, $tempInputFile; # Open the temporary input and output files. open INFILE, "< $tempInputFile" or die "Cannot open input file: $tempInputFile\n$!"; open OUTFILE, "> $tempOutputFile" or die "Cannot open output file: $tempOutputFile\n$!"; # Read the input file and copy eligible records to the output. # Count the number of delete records in case printStats is true. my($linesDeleted) = 0; while (defined($thisLine = )) { # Get this line's timestamp. my($lineTimestamp) = substr($thisLine, 0, index($thisLine, "\t")); # Write lines with newer timestamps to the output file. if ($lineTimestamp >= $cutoffTimestamp) { print OUTFILE $thisLine; } else { $linesDeleted++; } } close INFILE; # It is possible that records have been written to the log file while # we have been processing the temporary files. If so, append them to # our temporary output file. if (-e $filename) { open INFILE, "< $filename" or die "Cannot open log file: $filename\n$!"; while (defined($thisLine = )) { print OUTFILE $thisLine; } close INFILE; } # Rename our temporary output file to the original log file name. close OUTFILE; rename $tempOutputFile, $filename; # Remove our temporary input file. unlink $tempInputFile; # Print statistics, if desired. if ($printStats != 0) { print "Deleted $linesDeleted lines from $filename \n"; } } ########################################################### ########################################################### # # Mainline # ########################################################### # Extract the command line arguments # -a days: All log entries older than 'days' will be removed. # -v: Print verbose output # logfile: A list of one or more files to process. # my($ageDays) = undef; my($logfiles); my($verbose) = 0; while ($arg = shift(@ARGV)) { if ($arg eq "-a") { $ageDays = shift(@ARGV); } elsif ($arg eq "-v") { $verbose = 1; } else { push(@logfiles, $arg); } } # # Quit now if the command line looks screwy. # if (!defined($ageDays) || (scalar @logfiles == 0)) { usage(); exit(-1); } # # Determine the earliest timestamp allowed to stay in the file. # my($minimumTimestamp) = (time - ($ageDays * 60 * 60 * 24)); # # Rotate each logfile specified on the command line. # foreach $logfile (@logfiles) { rotate($logfile, $minimumTimestamp, $verbose); # Done! }