3

我有一个带有两个附加程序(一个屏幕和另一个文件)的记录器。我想要一个具有可以更改的可变日志级别的屏幕附加程序和无论如何都会记录所有内容的文件附加程序。因此,例如,您可以禁用任何到屏幕的输出(屏幕附加程序),但在您的日志文件(文件附加程序)中将完整的日志记录到 TRACE 级别。我成功地更改了 Screen 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() );   
4

1 回答 1

4

log4perl 常见问题解答

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

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

现在,如果您定义两个附加程序 AppWarn 和 AppError 并将它们都分配给根记录器,由于 Log4perl 的消息传播功能,从下面的任何记录器冒泡的消息都将由两个附加程序记录。如果您通过 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

上面定义的附加程序 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

于 2016-02-14T19:27:36.990 回答