Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I change a log4perl appender's filters at run time?

Tags:

perl

log4perl

I'v been trying to figure out if I can change an appender's filter at run-time that I've defined via a configuration file.

log4perl.filter.M1               = Log::Log4perl::Filter::LevelMatch
log4perl.filter.M2               = Log::Log4perl::Filter::LevelMatch
log4perl.filter.M1.LevelToMatch  = INFO
log4perl.filter.M1.AcceptOnMatch = true
log4perl.filter.M2.LevelToMatch  = WARN
log4perl.filter.M2.AcceptOnMatch = true
log4perl.filter.MyBoolean0       = Log::Log4perl::Filter::Boolean
log4perl.filter.MyBoolean0.logic = M1
log4perl.filter.MyBoolean1       = Log::Log4perl::Filter::Boolean
log4perl.filter.MyBoolean1.logic = M1 || M2

log4perl.appender.SCREEN.Filter  = MyBoolean0 

I'd like to change this filter from MyBoolean0 for the SCREEN to MyBoolean1, but do it after my program has started running.

Poking at the APPENDER_BY_NAME hash for SCREEN using Data::Dumper shows the following:

$VAR1 = bless( {
     'appender' => bless( {
                            'Filter' => 'MyBoolean0',
                            'color' => {
...
...
     'filter' => bless( {·
                          'params' => {·
                                        'M3' => bless( {·
                                                         'LevelToMatch' => 'ERROR',
                                                         'name' => 'M3',
                                                         'AcceptOnMatch' => 1
                                                       }, 'Log::Log4perl::Filter::LevelMatch' ),
                                        'M1' => bless( {·
                                                         'LevelToMatch' => 'INFO',
                                                         'name' => 'M1',
                                                         'AcceptOnMatch' => 1
                                                       }, 'Log::Log4perl::Filter::LevelMatch' ),
                                        'M2' => bless( {·
                                                         'LevelToMatch' => 'WARN',
                                                         'name' => 'M2',
                                                         'AcceptOnMatch' => 1
                                                       }, 'Log::Log4perl::Filter::LevelMatch' )
                                      },
                          'name' => 'MyBoolean0',
                          'eval_func' => sub { "DUMMY" },
                          'logic' => 'M1 || M2 || M3'
                        }, 'Log::Log4perl::Filter::Boolean' ),
     'warp_message' => undef,
     'name' => 'SCREEN'
   }, 'Log::Log4perl::Appender' );

But mucking with this HASH seems hackish to me. Is there a better way to change an appender's filters?

like image 543
slm Avatar asked Jan 31 '14 18:01

slm


1 Answers

You may use undocumented appender's property filter:

$Log::Log4perl::Logger::APPENDER_BY_NAME{'SCREEN'}->filter(
    Log::Log4perl::Filter::by_name('MyBoolean1')
);

Also you may use two appenders:

log4perl.appender.SCREEN0.Filter = MyBoolean0
log4perl.appender.SCREEN1.Filter = MyBoolean1

And change it in runtime:

$logger->remove_appender('SCREEN0', 1);
$logger->add_appender(
    Log::Log4perl::Config::create_appender_instance(
        $Log::Log4perl::Config::OLD_CONFIG,
        'SCREEN1',
        \%Log::Log4perl::Logger::APPENDER_BY_NAME
    )
);
like image 67
Denis Ibaev Avatar answered Sep 29 '22 17:09

Denis Ibaev