How to rotate log files automatically using Perl?
Question
How to rotate log files automatically using Perl?
How to Rotate Log Files Automatically Using Perl
Log rotation is a common system administration task where old log files are archived or renamed, and new log files are created to keep log file sizes manageable and improve system performance. Although tools like logrotate are often used, implementing a simple log rotation in Perl can be useful for custom needs or embedded scripts.
This answer covers a Perl script that performs basic log rotation by:
- Renaming the current log file to a numbered backup (e.g.,
logfile.1,logfile.2, …) - Removing the oldest backup if a maximum number of backups is reached
- Creating a new empty log file for continued logging
Key Perl Concepts in This Example
rename: Perl's builtin function to rename files- File handling and error checking
- Use of sigils in arrays (
@), scalars ($), and strings ("") - Basic loop and file existence testing (
-e) - Version compatibility: This code runs on Perl 5.10+ with no special version dependencies
Common Gotchas
- Ensure no processes are writing to the log file during rotation to avoid data loss or corruption.
- Renaming files atomically is OS-dependent; Perl
renameis usually atomic on the same filesystem. - Be careful with hardcoding backup limits; ensure there is sufficient disk space.
Example Perl Script for Log Rotation
#!/usr/bin/perl
use strict;
use warnings;
# Configuration
my $log_file = "app.log"; # Current log file to rotate
my $max_backups = 5; # Maximum number of backups to keep
# Rotate backups: delete oldest, rename others up by one
for (my $i = $max_backups; $i >= 1; $i--) {
my $old = $log_file . "." . $i;
my $new = $log_file . "." . ($i + 1);
if (-e $old) {
if ($i == $max_backups) {
unlink $old or warn "Could not remove $old: $!";
print "Removed oldest backup $old\n";
} else {
rename $old, $new or warn "Failed to rename $old to $new: $!";
print "Renamed $old to $new\n";
}
}
}
# Rename current log file to log_file.1 if it exists
if (-e $log_file) {
rename $log_file, $log_file . ".1" or die "Couldn't rename $log_file to ".$log_file.".1: $!";
print "Rotated current log $log_file to ".$log_file.".1\n";
} else {
print "No current log file $log_file found, no rotation needed.\n";
}
# Create a new empty log file
open my $fh, ">", $log_file or die "Cannot create new log file $log_file: $!";
close $fh;
print "Created new empty log file: $log_file\n";
How This Script Works
The script first removes the oldest backup (e.g., app.log.5) if it exists. Then it renames other backups, incrementing their number (e.g., app.log.3 becomes app.log.4). This shifts older logs up by one. Finally, the current log file (app.log) is renamed to app.log.1, and a new empty app.log is created.
This rotation scheme keeps the most recent logs and limits the number of backup files. It's a simple but effective approach that can be run from cron or embedded in other scripts.
Summary
Using Perl's core file operations like rename, unlink, and file tests, you can create your own log rotation utility. This approach is flexible and requires no external dependencies, making it perfect for intermediate Perl users engaged in system administration and automation tasks.
Verified Code
Executed in a sandbox to capture real output. • v5.34.1 • 7ms
No current log file app.log found, no rotation needed.
Created new empty log file: app.log
(empty)