Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much

log4Perl dynamic filename

by fritz1968 (Sexton)
on May 16, 2013 at 12:24 UTC ( #1033823=perlquestion: print w/replies, xml ) Need Help??
fritz1968 has asked for the wisdom of the Perl Monks concerning the following question:


I am trying to setup a logging using log4perl where the filename can be set dynamically. Of course I am having troubles. Here is my current code:

my $logFile="$logDir/$logfileName"; $logConf = q( log4perl.category.Foo.Bar = INFO, Logfile, Screen log4perl.appender.Logfile = log::Log4perl::Appender::File log4perl.appender.Logfile.filename = logs/frank.txt log4perl.appender.Logfile.layout = Log::Log4perl::Layou +t::PatternLayout log4perl.appender.Logfile.layout.ConversionPattern = %d + %-25M %X{logref} %p %m %n log4perl.appender.Screen = Log::Log4perl::Appende +r::Screen log4perl.appender.Screen.stderr = 0 log4perl.appender.Screen.layout = Log::Log4perl::Layout:: +SimpleLayout ); Log::Log4perl->init(\$logConf);

The problem is that I don't want each file name to be named "logs/frank.txt". I would rather have something like:


Any help would be greatly appreciated.

Replies are listed 'Best First'.
Re: log4Perl dynamic filename
by stefbv (Deacon) on May 16, 2013 at 12:46 UTC

    Use a sub reference function to return the file name, like this:

    log4perl.appender.Logfile.filename = sub { get_log_filename(); }

    Regards, Stefan


Re: log4Perl dynamic filename
by Anonymous Monk on May 16, 2013 at 13:23 UTC
Re: log4Perl dynamic filename
by dd-b (Monk) on May 16, 2013 at 22:47 UTC

    I do it like this:

    use Log::Log4perl; my $logfile = 'clean.log'; unlink $logfile; # ignore errors do { # Isolate # Log configuration. # If you go for interpolation, escape the {} in the pattern or use # different delimiters or something. my $lconf = q{ log4perl.logger = TRACE, ap1 log4perl.appender.ap1 = Log::Log4perl::Appender::File log4perl.appender.ap1.filename = } . $logfile . q' log4perl.appender.ap1.layout = Log::Log4perl::Layout::PatternLayou +t log4perl.appender.ap1.layout.ConversionPattern = %d{yyyyMMdd HH:mm +:ss.SSSS} %5p %F{1} %L: %m %n log4perl.appender.ap2 = Log::Log4perl::Appender::Screen log4perl.appender.ap2.layout = Log::Log4perl::Layout::PatternL +ayout log4perl.appender.ap2.layout.ConversionPattern = %d{yyyyMMdd H +H:mm:ss.SSSS} %5p %F{1} %L: %m %n '; # unclear, but this MIGHT mean something. Log::Log4perl::init ( \$lconf ) or die "Log init failed"; }; # Isolate my $logger = Log::Log4perl->get_logger('Test');
    That is, by using substitution within the quoted string config.

    You could also do it using function-call config, and possibly by doing a string config and then overriding that one thing with a function call, I believe, but I haven't done that, so I won't give you fake example code.

      Hello fritz1968, I personally prefer to use config files for configuration purposes, so I have a file pllog.conf:
      log4perl.rootLogger = TRACE, FileApp, XMLAppender, ScreenApp log4perl.appender.FileApp = Log::Log4perl::Appender::File log4perl.appender.FileApp.filename = sub { my $Me=$0; $Me =~ s/^.*\\// +; $Me =~ s/\..*//; return "$Me.log" } log4perl.appender.FileApp.layout = PatternLayout log4perl.appender.FileApp.layout.ConversionPattern = %d{ISO8601} (%- +13F: %04L) %m%n
      And somewhere in perl code:
      use Log::Log4perl qw(get_logger); Log::Log4perl->init("pllog.conf"); my $logger = get_logger("My_Tools.$Me");
      Used in this way, you get a logfile with the same name as your perl file but with .log instead of .pl. I only showed the file appender path, as you requsted. You can change this approach easily to fit your needs. And you can change the whole log4perl thing without changing your code.
Re: log4Perl dynamic filename
by periapt (Hermit) on May 20, 2013 at 12:24 UTC
    For many projects, I like to define a simple functional logging configuration.
    sub InitLogger { my $logfile = shift; my $logconf = q| log4perl.logger.[package_name] = INFO, Log +File log4perl.appender.LogFile = Log::Log4perl::Appende +r::File log4perl.appender.LogFile.filename = LOGFILE log4perl.appender.LOG.mode = append log4perl.appender.LogFile.layout = PatternLa +yout log4perl.appender.LogFile.layout.ConversionPattern = %d %5p> % +m%n |; $logconf =~ s/LOGFILE/$logfile/; Log::Log4perl->init( \$logconf ); return Log::Log4perl::get_logger("[package_name"); } # end InitLogger();
    I set the log4perl.appender.LogFile.filename option to an arbitrary value 'LOGNAME' so that I can replace it in the string later. Not sure why but I've found this to be more stable than using variable substitution inside the config string itself.

    If my projects grows to encompass several program files with almost identical log specs (except maybe for filename), I can pull the function into a library and share

    use strict; use warnings; use diagnostics;

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1033823]
Approved by Corion
Front-paged by Arunbear
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others romping around the Monastery: (4)
As of 2017-07-23 06:53 GMT
Find Nodes?
    Voting Booth?
    I came, I saw, I ...

    Results (345 votes). Check out past polls.