[c5c522c] | 1 | #!/usr/bin/perl |
---|
| 2 | # |
---|
| 3 | # $Id: dspam_logrotate,v 1.00 2009/12/22 12:25:59 sbajic Exp $ |
---|
| 4 | # |
---|
| 5 | # dspam_logrotate - Removed old entries from DSPAM log files. |
---|
| 6 | # Steve Pellegrin <spellegrin@convoglio.com> |
---|
| 7 | # |
---|
| 8 | # Patched for working on dspam installation with thousends of users. |
---|
| 9 | # Norman Maurer <nm@byteaction.de> |
---|
| 10 | # |
---|
| 11 | # Usage: |
---|
| 12 | # dspam_logrotate -v -a days logfile ... |
---|
| 13 | # -v: Print verbose output |
---|
| 14 | # -a days: All log entries older than 'days' will be removed. |
---|
| 15 | # -l logfile: A list of one or more files to process. |
---|
| 16 | # -d dspamdir: The home directory of dspam. |
---|
| 17 | |
---|
| 18 | ########################################################### |
---|
| 19 | # |
---|
| 20 | # Print usage info |
---|
| 21 | # |
---|
| 22 | sub usage { |
---|
| 23 | print "Usage: " . $0 . " -a age [-v] -l logfiles\n"; |
---|
| 24 | print "or\n"; |
---|
| 25 | print "Usage: " . $0 . " -a age [-v] -d /var/dspam\n"; |
---|
| 26 | } |
---|
| 27 | ########################################################### |
---|
| 28 | |
---|
| 29 | |
---|
| 30 | ########################################################### |
---|
| 31 | # |
---|
| 32 | # "Rotate" one log file |
---|
| 33 | # |
---|
| 34 | sub rotate { |
---|
| 35 | # Give names to input args. |
---|
| 36 | my($filename); |
---|
| 37 | my($cutoffTimestamp); |
---|
| 38 | my($printStats); |
---|
| 39 | ($filename, $cutoffTimestamp, $printStats) = @_; |
---|
| 40 | |
---|
| 41 | # Generate names for the temporary files. |
---|
| 42 | my($tempInputFile) = $filename . ".in"; |
---|
| 43 | my($tempOutputFile) = $filename . ".out"; |
---|
| 44 | |
---|
| 45 | # Rename the log file to the temporary input file name. |
---|
| 46 | rename $filename, $tempInputFile; |
---|
| 47 | |
---|
| 48 | # Open the temporary input and output files. |
---|
| 49 | open INFILE, "< $tempInputFile" |
---|
| 50 | or die "Cannot open input file: $tempInputFile\n$!"; |
---|
| 51 | open OUTFILE, "> $tempOutputFile" |
---|
| 52 | or die "Cannot open output file: $tempOutputFile\n$!"; |
---|
| 53 | |
---|
| 54 | # Read the input file and copy eligible records to the output. |
---|
| 55 | # Count the number of delete records in case printStats is true. |
---|
| 56 | my($linesDeleted) = 0; |
---|
| 57 | while (defined($thisLine = <INFILE>)) { |
---|
| 58 | # Get this line's timestamp. |
---|
| 59 | my($lineTimestamp) = substr($thisLine, 0, index($thisLine, "\t")); |
---|
| 60 | |
---|
| 61 | # Write lines with newer timestamps to the output file. |
---|
| 62 | if ($lineTimestamp >= $cutoffTimestamp) { |
---|
| 63 | print OUTFILE $thisLine; |
---|
| 64 | } else { |
---|
| 65 | $linesDeleted++; |
---|
| 66 | } |
---|
| 67 | } |
---|
| 68 | close INFILE; |
---|
| 69 | |
---|
| 70 | # It is possible that records have been written to the log file while |
---|
| 71 | # we have been processing the temporary files. If so, append them to |
---|
| 72 | # our temporary output file. |
---|
| 73 | if (-e $filename) { |
---|
| 74 | open INFILE, "< $filename" |
---|
| 75 | or die "Cannot open log file: $filename\n$!"; |
---|
| 76 | while (defined($thisLine = <INFILE>)) { |
---|
| 77 | print OUTFILE $thisLine; |
---|
| 78 | } |
---|
| 79 | close INFILE; |
---|
| 80 | } |
---|
| 81 | |
---|
| 82 | close OUTFILE; |
---|
| 83 | |
---|
| 84 | #Set the original uid, gid and perms |
---|
| 85 | my @filestat = stat($tempInputFile); |
---|
| 86 | chmod @filestat[2], $tempOutputFile; |
---|
| 87 | chown @filestat[4], @filestat[5], $tempOutputFile; |
---|
| 88 | |
---|
| 89 | # Rename our temporary output file to the original log file name. |
---|
| 90 | rename $tempOutputFile, $filename; |
---|
| 91 | |
---|
| 92 | # Remove our temporary input file. |
---|
| 93 | unlink $tempInputFile; |
---|
| 94 | |
---|
| 95 | # Print statistics, if desired. |
---|
| 96 | if ($printStats != 0) { |
---|
| 97 | print "Deleted $linesDeleted lines from $filename \n"; |
---|
| 98 | } |
---|
| 99 | } |
---|
| 100 | ########################################################### |
---|
| 101 | |
---|
| 102 | |
---|
| 103 | ########################################################### |
---|
| 104 | # |
---|
| 105 | # Mainline |
---|
| 106 | # |
---|
| 107 | ########################################################### |
---|
| 108 | |
---|
| 109 | # Extract the command line arguments |
---|
| 110 | # -a days: All log entries older than 'days' will be removed. |
---|
| 111 | # -v: Print verbose output |
---|
| 112 | # logfile: A list of one or more files to process. |
---|
| 113 | # |
---|
| 114 | my($ageDays) = undef; |
---|
| 115 | my($logfiles); |
---|
| 116 | my($help) = 0; |
---|
| 117 | my($verbose) = 0; |
---|
| 118 | |
---|
| 119 | while ($arg = shift(@ARGV)) { |
---|
| 120 | if ($arg eq "-a") { |
---|
| 121 | $ageDays = shift(@ARGV); |
---|
| 122 | } elsif ($arg eq "-v") { |
---|
| 123 | $verbose = 1; |
---|
| 124 | } elsif ($arg eq "-l") { |
---|
| 125 | @logfiles = @ARGV; |
---|
| 126 | } elsif ($arg eq "-d") { |
---|
| 127 | my $dspamdir = shift(@ARGV); |
---|
| 128 | @logfiles = split(/\n/, `find $dspamdir -name \"*.log\"`); |
---|
| 129 | } elsif ($arg eq "-h") { |
---|
| 130 | $help = 1; |
---|
| 131 | } |
---|
| 132 | } |
---|
| 133 | |
---|
| 134 | # |
---|
| 135 | # Quit now if the command line looks screwy. |
---|
| 136 | # |
---|
| 137 | if (!defined($ageDays) || (scalar @logfiles == 0) || $help == 1) { |
---|
| 138 | usage(); |
---|
| 139 | exit(-1); |
---|
| 140 | } |
---|
| 141 | |
---|
| 142 | # |
---|
| 143 | # Determine the earliest timestamp allowed to stay in the file. |
---|
| 144 | # |
---|
| 145 | my($minimumTimestamp) = (time - ($ageDays * 60 * 60 * 24)); |
---|
| 146 | |
---|
| 147 | # |
---|
| 148 | # Rotate each logfile specified on the command line. |
---|
| 149 | # |
---|
| 150 | foreach $logfile (@logfiles) { |
---|
| 151 | rotate($logfile, $minimumTimestamp, $verbose); |
---|
| 152 | } |
---|