perllogginglog4perl

How to record FATAL events to separate file with log4perl


I'm using log4perl and I want to record all FATAL events in the separate file.

Here is my script:

#!/usr/bin/perl

use strict;
use warnings FATAL => 'all';

use Log::Log4perl qw(get_logger);

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

my $l_aa = get_logger('AA');
$l_aa->fatal('fatal');

my $l_bb = get_logger('BB');
$l_bb->info('info');

And here is my config file:

## What to log

    log4perl.logger         = FATAL, FatalLog
    log4perl.logger.BB      = INFO, MainLog

## Logger MainLog

    log4perl.appender.MainLog          = Log::Log4perl::Appender::File
    log4perl.appender.MainLog.filename = log4perl_main.log

    log4perl.appender.MainLog.layout = PatternLayout

    log4perl.appender.MainLog.layout.ConversionPattern = \
        [%d{yyyy-MM-dd HH:mm:ss}] %p - %c - %m%n

## Logger FatalLog

    log4perl.appender.FatalLog          = Log::Log4perl::Appender::File
    log4perl.appender.FatalLog.filename = log4perl_fatal.log

    log4perl.appender.FatalLog.layout = PatternLayout

    log4perl.appender.FatalLog.layout.ConversionPattern = \
        [%d{yyyy-MM-dd HH:mm:ss}] %p - %c - %m%n

I'm expecting that with this setup the file log4perl_fatal.log will get only FATAL-level events. But here is what I get after running the script:

$ tail -f *log
==> log4perl_fatal.log <==
[2014-04-13 08:41:22] FATAL - AA - fatal
[2014-04-13 08:41:22] INFO - BB - info

==> log4perl_main.log <==
[2014-04-13 08:41:22] INFO - BB - info

Why I'm getting INFO-level event in log4perl_fatal.log?

How can I recordy only FATAL-level events in the separate file?

PS Here is a GitHub repo with this script & config.


Solution

  • This is the question that is coverd in log4perl FAQ — https://metacpan.org/pod/Log::Log4perl::FAQ#How-can-I-collect-all-FATAL-messages-in-an-extra-log-file

    In the example log4perl_fatal.log gets INFO level events because of appender additivity.

    To fix it this line should be added to config file:

    log4perl.appender.FatalLog.Threshold = FATAL
    

    Then the output files get the expected output:

    $ tail log4perl*log
    ==> log4perl_fatal.log <==
    [2014-05-04 20:00:39] FATAL - AA - fatal
    
    ==> log4perl_main.log <==
    [2014-05-04 20:00:39] INFO - BB - info