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 | } |
---|