#!/usr/bin/perl # Name: ~/www/bin/rotate_logs Author: part of iServer from Verio # Purpose: Rotates the Apache logs and compresses them. Optional logresolve. # # 20000403 PJL - creation of script # 20010807 PJL - modified for use with Confluence and streamlined a bit # 20010807 PJL - Fixed a bug not deleting the old compressed logs # 20010809 PJL - Mainly matched Confluence's control panel format # # Modifications done by js-cgi@inwap.com # 20011031 JMS - Change naming convention to YYYY/MMDD-acc and YYYY/MMDD-err. # 20011101 JMS - Use `logresolve` on the files specified on the command line. # use POSIX qw(strftime); use File::Copy; use strict; #my @logs = ('access_log','error_log','script.error_log','controlpanel.log'); my @logs = qw(access_log error_log referer_log); # Keep other 2 as is my $CURLOG_DIR = "$ENV{'HOME'}/www/logs"; my $GZIP = "/usr/bin/gzip"; my $LOGRESOLVE = "/usr/local/apache/bin/logresolve"; # Get the date for the filename extension # First strftime() returns "Thu-Nov-01-2001:16:10:26" #my $curstr = strftime("%a-%b-%d-%Y:%H:%M:%S",localtime(time)); my @now = localtime(time); # $wday = strftime("%a", @now); my $yyyy = strftime("%Y", @now); my $mmdd = strftime("%m%d",@now); my $dst_dir = "$CURLOG_DIR/$yyyy"; mkdir $dst_dir,0755 unless -d $dst_dir; # Make two passes over the list of log files # 1st pass: Quickly copy and truncate each log my %logs; foreach my $log (@logs) { my $src = "$CURLOG_DIR/$log"; my $dst = "$dst_dir/$mmdd-" . substr($log,0,3); if (-s $src) { $logs{$log} = $dst; copy($src,$dst) || warn "copy($src,$dst): $!\n"; copy("/dev/null",$src) || warn "copy(null,$src): $!\n"; } } # If 'access_log' is specified on the command line, convert numeric IP # addresses in it to host names. It can take 60 minutes to do 40000 lines. lookup_dns($_) foreach @ARGV; # Use "www/bin/rotate_logs access_log" # 2nd pass: Compress the logs. die "gzip is not available!" unless -x $GZIP; compress_log($_) for values %logs; exit(0); ##################################################################### sub do_warn (@) { warn @_; system qw(quota -v); # Error may be due to disk quota exceeded system qw(ls -alt); # Show size of newest files } sub compress_log { my $path = shift; my $output = "$path.gz"; return warn "$output already exists" if -f $output; system($GZIP, "--best", $path); do_warn "'$GZIP $path' returned $?" if $?; } sub lookup_dns { my $file = shift; # Original file name my $log = $logs{$file}; # Where it got copied to if (-s $log) { my $tmp = "$log.$$"; my $mtime = (stat $log)[9]; # Preserve modification time system "$LOGRESOLVE <$log >$tmp"; do_warn "$LOGRESOLVE returned $?" if $?; move($tmp,$log) || warn "move($tmp,$log): $!\n"; utime($mtime,$mtime,$log) || warn "utime($log): $!\n"; } else { warn "Did not run $LOGRESOLVE on $file ($log)\n"; } } 1;