In Unix, I need to be able to archive log files into monthly folders, labelled accordingly. How do I do this in Perl?
When I have had this task, I use cronolog.
The package includes a Perl script called cronosplit
that you can use to split an existing monolithic log file into %Y/%m/%d
subdirectories.
Cronolog itself is a binary written in C that can be used as a piped target for logging. For example, you can use it in an Apache httpd.conf:
CustomLog "|/usr/sbin/cronolog /web/logs/%Y/%m/%d/access.log"
Does it have to be Perl? Have you tried logrotate?
As far as a Perl solution: mkdir will create the directories, and if you use POSIX 'strftime';, then you'll be able to generate nice directory names based on the current time (ie, my $dirname = strftime('%Y-%m-%d',localtime()) will generate a YYYY-MM-DD string), and you can move the files using rename. That's just core Perl, there are a ton of CPAN modules that do some or all of this (such as File::Copy, instead of rename).
Let's provide an actual Perl idea, since that's what was asked for:
use File::Path qw<mkpath>;
use File::Spec;
use POSIX qw<strftime>;
use Smart::Comments;
my $directory
= File::Spec->catfile( $BASE_LOG_DIRECTORY
, strftime( "%Y-%B", localtime ) #2009-January
);
### $directory
unless ( -e $directory ) {
mkpath( $directory, { verbose => 1 } );
}
my $log_file_path = File::Spec->catfile( $directory, 'system.log' );
### $log_file_path
Output is
### $directory: '/my/base/directory/2009-January'
### $log_file_path: '/my/base/directory/2009-January/system.log'
Notes
- Install
Smart::Comments
, or comment it out. - The constant
$BASE_LOG_DIRECTORY
is written in Readonly/PBP style - Everything else should just come with Perl.