14

Log4perl是一个很棒的日志记录工具。

warnings pragma 也是一个必不可少的工具。

但是,当 Perl 脚本作为守护进程运行时,Perl 警告会打印到 STDERR 中,没有人可以看到它们,而不是打印到相关程序的 Log4perl 日志文件中。

有没有办法将 Perl 警告捕获到 Log4perl 日志中?

例如,此代码将很好地记录到日志文件中,但如果它作为守护程序运行,则 Perl 警告将不会包含在日志中:

#!/usr/bin/env perl
use strict;
use warnings;

use Log::Log4perl qw(get_logger);

# Define configuration
my $conf = q(
                log4perl.logger                    = DEBUG, FileApp
                log4perl.appender.FileApp          = Log::Log4perl::Appender::File
                log4perl.appender.FileApp.filename = test.log
                log4perl.appender.FileApp.layout   = PatternLayout
);

# Initialize logging behaviour
Log::Log4perl->init( \$conf );

# Obtain a logger instance
my $logger = get_logger("Foo::Bar");
$logger->error("Oh my, an error!");

$SIG{__WARN__} = sub {
    #local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
    $logger->warn("WARN @_");
};

my $foo = 100;
my $foo = 44;

这仍然会打印到 STDERR:

"my" variable $foo masks earlier declaration in same scope at log.pl line 27.

并且日志文件没有捕捉到这个警告。

4

2 回答 2

15

您可以安装一个WARN处理程序来执行此操作。Log4perl FAQ中提到了它。

我的程序已经使用了 warn() 和 die()。如何切换到 Log4perl?

如果您的程序已经使用 Perl 的 warn() 函数来输出错误消息,并且您希望将它们引导到 Log4perl 世界,只需在您的程序或模块所在的位置定义一个WARN处理程序:

use Log::Log4perl qw(:easy);
$SIG{__WARN__} = sub {
    local $Log::Log4perl::caller_depth =
        $Log::Log4perl::caller_depth + 1;
    WARN @_;
};

这将捕获warn程序中的任何显式使用,以及有关使用未初始化值等的 Perlish 警告。

于 2010-01-17T17:21:26.950 回答
10

它在 Log4perl FAQ 中,因为Some 模块将消息打印到 STDERR。如何将它们汇集到 Log::Log4perl?我的程序已经使用了warn() 和die()。如何切换到 Log4perl?.

您的特定问题增加了您看到编译时警告的皱纹,因此您需要调整常见问题解答建议以尽早在编译时设置日志记录。在BEGIN尽可能靠近源顶部的块中执行此操作:

 BEGIN {
     ... all of your logging setup
     }

您可以通过运行启用警告的语法检查来判断它是否是编译时警告:

 % perl -cw program

如果您在语法检查期间看到警告,则它是编译时警告。

不过,我宁愿在开发中捕获编译时警告。他们不应该通过生产系统。:)

于 2010-01-17T17:23:48.383 回答