Background
Recently while cruising StackOverflow I came across this question where a user was trying to use the Perl module Log::Log4Perl. Log4Perl provides a mechanism similar to log4j (logging for Java) for logging mesages to various outputs such as the console or a log file. I’ve used this module a couple of times in the past and the users question seemed pretty straightforward.
He was trying to make use of the Log4Perl appender Log::Dispatch::FileRotate to rotate 2 log files once a day and wasn’t having much luck. Log::Dispatch::FileRotate automatically rotates log files according to different constraints such as daily, file size, etc.
This seemed like a interesting problem so I spent a couple of minutes re-familiarizing myself with Log4Perl and tried to see if I could solve his problem.
Solution
The key piece this user was missing with Log::Dispatch::FileRotate was that he needed to include the mode = truncate. Here’s a working example log4perl.conf file which shows how to rotate a log file every minute.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
log4perl.logger.Fizz = INFO, FizzAppender log4perl.logger.Buzz = INFO, BuzzAppender log4perl.appender.FizzAppender = Log::Dispatch::FileRotate log4perl.appender.FizzAppender.filename = fizz-log.txt log4perl.appender.FizzAppender.max = 1 log4perl.appender.FizzAppender.DatePattern = yyyy-MM-dd-HH-MM log4perl.appender.FizzAppender.TZ = EST log4perl.appender.FizzAppender.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.FizzAppender.layout.ConversionPattern = %d %m %n log4perl.appender.FizzAppender.mode = truncate log4perl.appender.BuzzAppender = Log::Dispatch::FileRotate log4perl.appender.BuzzAppender.filename = buzz-log.txt log4perl.appender.BuzzAppender.max = 1 log4perl.appender.BuzzAppender.DatePattern = yyyy-MM-dd-HH-MM log4perl.appender.BuzzAppender.TZ = EST log4perl.appender.BuzzAppender.layout = Log::Log4perl::Layout::PatternLayout log4perl.appender.BuzzAppender.layout.ConversionPattern = %d %m %n log4perl.appender.BuzzAppender.mode = truncate |
NOTE: The DatePattern parameter is what’s causing the log file to be rotated every 1 minute. The other interesting parameters are max = 1 and mode = truncate. max controls how many files will be rotated, in this case there will be 1.
Using the following 2 scripts, 2 log files will initially get created and then rotated a minute later.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/usr/bin/perl #- log4perl_Fizz.pl use strict; use warnings; use Log::Log4perl; my $log_conf = "log4perl.conf"; Log::Log4perl::init($log_conf); # In one script the logger is a "Fizz" logger (like below), and in the other # script the logger is a "Buzz" logger. my $logger = Log::Log4perl->get_logger("Fizz"); while (1) { $logger->info("This should work."); sleep 1; } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
#!/usr/bin/perl #- log4perl_Buzz.pl use strict; use warnings; use Log::Log4perl; my $log_conf = "log4perl.conf"; Log::Log4perl::init($log_conf); # In one script the logger is a "Fizz" logger (like below), and in the other # script the logger is a "Buzz" logger. my $logger = Log::Log4perl->get_logger("Buzz"); while (1) { $logger->info("This should work."); sleep 1; } |
Now if we run the following watch command to “monitor” the directory with the log files like so:
1 2 3 4 5 6 7 8 9 |
% watch ls -l ... ... Every 2.0s: ls -l Thu Dec 20 21:16:51 2012 total 12 -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Buzz.pl -rw-rw-r-- 1 saml saml 978 Dec 20 21:07 log4perl.conf -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Fizz.pl |
Now run the 2 scripts, log4perl_Buzz.pl & log4perl_Fizz.pl.
1 2 |
% log4perl_Buzz.pl & % log4perl_Fizz.pl & |
The watch command now shows 2 log files, buzz-log.txt and fizz-log.txt, being created.
1 2 3 4 5 6 7 8 |
Every 2.0s: ls -l Thu Dec 20 21:17:56 2012 total 20 -rw-rw-r-- 1 saml saml 39 Dec 20 21:17 buzz-log.txt -rw-rw-r-- 1 saml saml 39 Dec 20 21:17 fizz-log.txt -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Buzz.pl -rw-rw-r-- 1 saml saml 978 Dec 20 21:07 log4perl.conf -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Fizz.pl |
Waiting another ~2 minutes watch’s output now shows the 2 log files being rotated to the same names with the suffix .1 added and new versions of the log files taking there place.
1 2 3 4 5 6 7 8 9 10 |
Every 2.0s: ls -l Thu Dec 20 21:19:05 2012 total 28 -rw-rw-r-- 1 saml saml 195 Dec 20 21:19 buzz-log.txt -rw-rw-r-- 1 saml saml 2340 Dec 20 21:18 buzz-log.txt.1 -rw-rw-r-- 1 saml saml 234 Dec 20 21:19 fizz-log.txt -rw-rw-r-- 1 saml saml 2301 Dec 20 21:18 fizz-log.txt.1 -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Buzz.pl -rw-rw-r-- 1 saml saml 978 Dec 20 21:07 log4perl.conf -rwxrwxr-x 1 saml saml 358 Dec 20 20:15 log4perl_Fizz.pl |
And that’s how you can rotate log files in Perl, using Log::Log4Perl.