如何在Log :: Log4perl中设置两个具有不同日志级别的appender?

时间:2015-10-23 15:23:31

标签: perl logging configuration log4perl

我有一个带两个appender的记录器(一个Screen和其他File)。我希望有一个可以更改的可变日志级别的Screen appender和无论如何都会记录所有内容的File appender。因此,例如,您可以禁用任何输出到屏幕(Screen appender),但在日志文件(File appender)中获取完整日志记录到TRACE级别。我成功地改变了屏幕appender,但我无法将同一记录器的File appender设置为TRACE级别。我尝试使用不同的阈值设置,但没有成功。

# Define a category logger
my $log = Log::Log4perl->get_logger("main");

# Define a layout
my $layout = Log::Log4perl::Layout::PatternLayout->new("[%d{yyyy/MM/dd HH:mm:ss,SSS}]%m%n");

# Define a file appender
my $file_appender = Log::Log4perl::Appender->new(
                    "Log::Log4perl::Appender::File",
                    name      => "Logfile",
                    filename  => "$logfile",
                    autoflush => 1,
                    umask => 022,
                    header_text => "INVOCATION:$0 @ARGV", 
                    #Threshold => "TRACE",  DOES NOT WORK
                );

# Define a stderr appender
my $stderr_appender =  Log::Log4perl::Appender->new(
                    "Log::Log4perl::Appender::ScreenColoredLevels",
                    name      => "Screen",
                    stderr    => 1,
                );

# Have both appenders use the same layout (could be different)
$stderr_appender->layout($layout);
$file_appender->layout($layout);

#add both appenders to logger
$log->add_appender($stderr_appender);
$log->add_appender($file_appender);

#add a level to logger
#$log_level coming from command line or configuration
$log->level($log_level);

#$file_appender->threshold( "TRACE" );   THIS DOES NOT WORK
#Log::Log4perl->appender_thresholds_adjust(-1, ['Logfile']);   NOR THIS

#check your appenders
#print Dumper( Log::Log4perl->appenders() );   

1 个答案:

答案 0 :(得分:3)

来自log4perl FAQ

  

我想将ERROR和WARN消息记录到不同的文件中!我怎么能这样做?

     

假设您希望根据语句的优先级将每个日志记录语句写入不同的文件。具有优先级WARN的消息应该转到/tmp/app.warn,优先级为ERROR的事件应该以/tmp/app.error结束。

     

现在,如果您定义两个appender AppWarn和AppError并将它们分配给根记录器,由于Log4perl的消息传播功能,两个appender将记录从下面任何记录器冒出的消息。如果您通过appender阈值机制限制其暴露并将AppWarn的阈值设置为WARN,并将AppError设置为ERROR,则仍会在AppWarn中收到ERROR消息,因为AppWarn的WARN设置只会过滤掉优先级低于WARN的消息 - ERROR是更高,将被允许通过。

     

我们需要的是一个Log4perl自定义过滤器,可与Log :: Log4perl 0.30一起使用。

     

两个appender都需要验证即将到来的消息的优先级是否与appender应该记录消息的优先级完全匹配。为了完成这个任务,让我们定义两个自定义过滤器,MatchError和MatchWarn,当它们附加到它们的appender时,会将传递给它们的消息限制为与给定优先级匹配的消息:

   log4perl.logger = WARN, AppWarn, AppError
        # Filter to match level ERROR
    log4perl.filter.MatchError = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.MatchError.LevelToMatch  = ERROR
    log4perl.filter.MatchError.AcceptOnMatch = true
        # Filter to match level WARN
    log4perl.filter.MatchWarn  = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.MatchWarn.LevelToMatch  = WARN
    log4perl.filter.MatchWarn.AcceptOnMatch = true
        # Error appender
    log4perl.appender.AppError = Log::Log4perl::Appender::File
    log4perl.appender.AppError.filename = /tmp/app.err
    log4perl.appender.AppError.layout   = SimpleLayout
    log4perl.appender.AppError.Filter   = MatchError
        # Warning appender
    log4perl.appender.AppWarn = Log::Log4perl::Appender::File
    log4perl.appender.AppWarn.filename = /tmp/app.warn
    log4perl.appender.AppWarn.layout   = SimpleLayout
    log4perl.appender.AppWarn.Filter   = MatchWarn
  

上面定义的appenders AppWarn和AppError分别登录到/tmp/app.warn和/tmp/app.err,并附加了自定义过滤器MatchWarn和MatchError。此设置将在系统中的任何位置发出的所有WARN消息都指向/tmp/app.warn(和ERROR消息到/tmp/app.error) - 没有任何重叠。

另请参阅log4perl及其子模块的CPAN文档:

http://search.cpan.org/~mschilli/Log-Log4perl-1.46/lib/Log/Log4perl/Filter.pm