Search code examples
perllog4perl

How can log4perl write to STDERR and a file at the same time?


I tried to set up two appenders, but it seems to only write to STDERR:

my $header = "######$scriptname $version";
use Log::Log4perl qw(:easy);
Log::Log4perl->easy_init($DEBUG);
my $logger = get_logger();
my $layout = Log::Log4perl::Layout::PatternLayout->new(
"%d %p> %F{1}:%L %M - %m%n");
my $appender = Log::Log4perl::Appender->new(
        "Log::Dispatch::File",
        filename=>$scriptname.".log",
        mode => "append"
);
$appender->layout($layout);
my $stderr = Log::Log4perl::Appender::Screen->new(
        stderr =>0,
        );

$stderr->layout($layout);
$logger->info($header);

Solution

  • It's not a good idea to mix easy_init with custom appenders. You can fix this by adding appender to logger $logger->add_appender($appender). But this will result in duplicated messages, because you've already set appender in easy_init.

    I suggest you to use configuration instead. You can embed configuration in you code:

    use strict; use warnings;
    
    use Log::Log4perl;
    
    Log::Log4perl->init(\<<CONFIG);
    log4perl.rootLogger = DEBUG, screen, file
    
    log4perl.appender.screen = Log::Log4perl::Appender::Screen
    log4perl.appender.screen.stderr = 0
    log4perl.appender.screen.layout = PatternLayout
    log4perl.appender.screen.layout.ConversionPattern = %d %p> %F{1}:%L %M - %m%n
    
    log4perl.appender.file = Log::Log4perl::Appender::File
    log4perl.appender.file.filename = 1.log
    log4perl.appender.file.mode = append
    log4perl.appender.file.layout = PatternLayout
    log4perl.appender.file.layout.ConversionPattern = %d %p> %F{1}:%L %M - %m%n
    CONFIG
    
    my $logger = Log::Log4perl->get_logger();
    $logger->info("my message");