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

log4perl, perl

Solution

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
    )
);

Problem

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?

Original source