OpenWetWare:Software/Server/Urchin/Log Rotation/WebLogRotate

From OpenWetWare

Jump to: navigation, search
  1. !/usr/bin/perl -w
  2. RCS ID: $Revision: 1.7 $
  3. Script to rotate the specified logs and name them with yesterday's
  4. date. The script also restarts the web server with a specified command.
  5. and optionally compresses old logs and removes them after a certain period.
  6. Copyright (c) 2002, 2003, 2004 Urchin Software Corporation
  7. Usage: weblog_rotate.pl [--log /path/to/log [--log /path/to/log] \
  8. | [--loglist /path/to/loglist]] \
  9. --touchlog \
  10. --restart_cmd "apachectl restart" \
  11. --compress --days N --help
  12. Where:
  13. --loglist specifies the path to a file containing the full pathnames
  14. of all the logs that are to be rotated. This option cannot be used
  15. with the --log option.
  16. --log specifies the full path to the log file to be rotated
  17. (multiple --log entries are allowed)
  18. --touchlog specifies that a new log should be created once the
  19. original log is rotated.
  20. (default is not to create the log)
  21. --restart_cmd specifies the command to restart the web server
  22. (default is apachectl restart)
  23. --compress specifies whether or not to compress the logs with gzip
  24. (default is off)
  25. --noprune disables automatic pruning of archived logs
  26. (default is off)
  27. --days specifies how many days to keep archived logs
  28. (default is 60, minimum value is 1)
  29. --help shows this message\n\n";

use strict; use Time::localtime; use Getopt::Long;

  1. Initialize variables

my @logs = (); my $loglistfile = ""; my $restart_cmd = "apachectl restart"; my $days = 60; my $compress = 0; my $noprune = 0; my $touchlog = 0; my $gstatus; my $abslogpath; my $help = 0;

  1. Read in the options

$gstatus = GetOptions('loglist=s' => \$loglistfile, 'log=s' => \@logs, 'restart_cmd=s' => \$restart_cmd, 'noprune' => \$noprune, 'days=i' => \$days, 'touchlog' => \$touchlog, 'compress' => \$compress, 'help' => \$help); if ($help) { &Usage; exit; } if ($gstatus ne 1) { &Usage; exit(1); }

if ( $loglistfile ne "" ) { if ( @logs ) { print "FATAL error: \"--log\" and \"--loglist\" options are mutually exclusive\n"; &Usage; exit(1); } open(LOGLISTFILE, $loglistfile) || die "FATAL error: can't open log list file $loglistfile\n"; @logs = <LOGLISTFILE>; }

  1. Calculate the date string for 'yesterday'

my $yesterday = convert_epoch(time() - 86400);

  1. Ensure that '$days' is at least 1

if ($days <= 0) { $days = 1; }

  1. Calculate the date string for '$days' ago

my $cutoff_date = convert_epoch(time() - ($days * 86400));

  1. Rotate each log file inside its current directory

my ($log, $new_log, $dir); my ($mode, $uid, $gid); foreach $log (@logs) { chomp($log); # Create the name for the new log $new_log = "$log.$yesterday";

# Verify that $log exists and is readable if ((!-e $log) && (!-r $log)) { warn "Logfile: $log does not exist or is unreadable\n"; next; }

# Move $log to $new_log as long as it doesn't overwrite another file if ((-e $new_log) || ((-e "$new_log.gz") && $compress)) { warn "Logfile: $new_log already exists. Skipping rotation...\n"; } else { rename($log, $new_log) || warn "Unable to rename: $log to $new_log"; if ( $touchlog ) { ($mode,$uid,$gid) = (stat("$new_log"))[2,4,5]; open(LOG,"+>$log") || warn "Unable to create $log"; close(LOG); chown($uid,$gid,$log) || warn "Unable to change ownership/group of $log to UID $uid/GID $gid"; chmod($mode,$log) || warn "Unable to change permissions of $log to $mode"; } } }

  1. Restart the web server

if ($restart_cmd) { system($restart_cmd) && warn "$restart_cmd failed to restart web server properly"; }

  1. Loop through logs and prune and/or gzip as necessary.

foreach $log (@logs) { # Create the name for the new log $new_log = "$log.$yesterday";

# Determine the directory where the log file is located $_ = $log; ($dir) = m#(^/.*/)#;

# Compress the logs if set as option if ($compress) { # Verify that $new_log exists and is readable and compress the log if ((!-e $new_log) && (!-r $new_log)) { warn "Cannot compress $new_log since it does not exist or is not readable"; next; } else { system("/usr/bin/gzip $new_log") && warn "Problems gzipping $new_log"; } }

# Go to the next log if log pruning is disabled if ($noprune) { print "Skipping log pruning for $log\n"; next; }

# Remove outdated logs from the directory opendir(DIR, $dir) || warn "Unable to open archived logs directory: $dir"; while (my $file = readdir(DIR)) { $abslogpath = "$dir$file"; # Skip logs that don't match the same base logfile name if ( index($abslogpath,$log) == -1 ) { next; } # Skip remaining logs that don't have a YYYYMMDD suffix pattern if ($file =~ /(\d{8})/) { if ($1 < $cutoff_date) { unlink("$dir$file") || warn "Problems removing file: $dir$file"; } } } }

  1. Subroutine to show the usage of this script

sub convert_epoch { my $rawtime = $_[0]; my $formatedtime = "";

if ((! defined($rawtime)) || $rawtime eq "") { $formatedtime = 0; } else { $rawtime = localtime($rawtime); $formatedtime = sprintf("%04d%02d%02d", $rawtime->year+1900, $rawtime->mon+1, $rawtime->mday); } return($formatedtime); }


sub Usage {

  print "Usage: $0 [--loglist /path/to/loglist || --log /path/to/log [--log /path/to/log] ] \\

--touchlog \\

       --restart_cmd \"apachectl restart\" \\
       --compress [--noprune | --days N] --help 
  Where:
     --loglist specifies the path to a file containing the full pathnames
       of all the logs that are to be rotated. This option cannot be used
       with the --log option.
     --log specifies the full path to the log file to be rotated
       (multiple --log entries are allowed)
     --touchlog specifies that a new log should be created once the
       original log is rotated.

(default is not to create the log)

     --restart_cmd specifies the command to restart the web server
       (default is apachectl restart)
     --compress specifies whether or not to compress the logs with gzip
       (default is off)
     --noprune disables automatic pruning of archived logs
       (default is off)
     --days specifies how many days to keep archived logs
       (default is 60, minimum value is 1)
     --help shows this message\n\n";

}

Personal tools