3

I want to limit the size of log files created with log4perl. I don't want my log file to grow to more than about 100mb; I only need the last 100mb (or thereabouts) of data. Ideally, it would truncate earlier data and only keep the last bits. I'm aware of the Log::Dispatch::FileRotate module, but that doesn't quite meet my requirements, as I don't want multiple log files.

Is this possible?

Full code, including inline config, below (minus the use statements):

my $log_conf = q/ 
    log4perl.category = DEBUG, Logfile
    log4perl.appender.Logfile = Log::Dispatch::FileRotate
    log4perl.appender.Logfile.filename = sub { return get_log_fn(); }
    log4perl.appender.Logfile.mode = truncate
    log4perl.appender.Logfile.autoflush = 1 
    log4perl.appender.Logfile.size =  104857600
    log4perl.appender.Logfile.layout    = Log::Log4perl::Layout::PatternLayout     
    log4perl.appender.Logfile.layout.ConversionPattern = %d %P %M(%L) %p %m %n
/;

Log::Log4perl::init( \$log_conf );
my $logger = Log::Log4perl::get_logger();

INFO "Starting $0";
my $upper = 100000000;
for(my $i=0;$i < $upper;$i++) {
    DEBUG $i;
}

sub get_log_fn 
{
    use File::Basename;
    return sprintf "%s.log", basename( $0, '.pl' );     
}
Rachel
  • 83
  • 1
  • 8

2 Answers2

3

I just read a bit and did an experiment. It seems if you leave off the max attribute, keep the size attribute, and use the truncate attribute rather than append while using Log::Dispatch::FileRotate you can get what you want:

#!/usr/bin/env perl

use Modern::Perl;
use Log::Log4perl;

Log::Log4perl::init('./log4perl.conf');

my $logger = Log::Log4perl->get_logger('LOG1');

for my $num ( 1..1000 ) {
    $logger->debug($num);
}

$logger->debug('blah');

With the associated config file:

###############################################################################
#                              Log::Log4perl Conf                             #
###############################################################################
log4perl.rootLogger              = DEBUG, LOG1
log4perl.appender.LOG1           = Log::Dispatch::FileRotate
log4perl.appender.LOG1.filename  = ./mylog.log
log4perl.appender.LOG1.mode      = truncate
log4perl.appender.LOG1.autoflush = 1
log4perl.appender.LOG1.size      = 1024
#log4perl.appender.LOG1.max       = 5
log4perl.appender.LOG1.layout    = Log::Log4perl::Layout::PatternLayout
log4perl.appender.LOG1.layout.ConversionPattern = %d %p %m %n

That leaves me with a 130 byte mylog.log with 4 lines in it:

2012/07/25 08:23:14 DEBUG 998
2012/07/25 08:23:14 DEBUG 999
2012/07/25 08:23:14 DEBUG 1000
2012/07/25 08:23:14 DEBUG blah

UPDATE

It looks like FileRotate will always make at least a .1 file even when max is set to 0.

If that absolutely won't work from you, you'll need to write your own apender.

Craig Treptow
  • 834
  • 7
  • 19
  • Thanks, I've tried that. It's still doing the same thing - creating a new log file (called logtest.log.1), rolling the main file (logtest.log) into it, then emptying it and starting again. – Rachel Jul 25 '12 at 15:35
  • Would you please post your config file and a small script that illustrates this? – Craig Treptow Jul 25 '12 at 15:42
  • Is your sub get_log_fn() just returning logtest.log each time, or is it tacking on a number? You might try this with a hard coded name like I showed to see if it behaves differently. – Craig Treptow Jul 25 '12 at 16:00
  • It derives the name from the codefile. The full code is now pasted above. I'll try it with the hardcoded name, but we won't be able to do this in practice because of how we manage the log files. – Rachel Jul 26 '12 at 09:25
  • Ok, thanks for your help. I suspected that might be the case. I will consider my options... – Rachel Jul 26 '12 at 14:53
0

I had the same problem and found this module:

http://search.cpan.org/dist/Log-Log4perl-Appender-File-FixedSize/lib/Log/Log4perl/Appender/File/FixedSize.pm

Perhaps two years late, but I figured other people who landed here might benefit from this

Jason Hamje
  • 511
  • 1
  • 5
  • 15