Log4perl是一个很棒的日志记录工具。
warnings编译指示也是必不可少的工具。
但是,当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.
日志文件没有捕获此警告。
答案 0 :(得分: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警告。
答案 1 :(得分:10)
它位于Log4perl常见问题解答Some module prints messages to STDERR. How can I funnel them to Log::Log4perl?和My program already uses warn() and die(). How can I switch to Log4perl?。
您遇到的编译时警告会增加您的特定问题,因此您需要调整FAQ建议,以便尽早在编译时设置日志记录。在BEGIN
块中尽可能靠近源顶部执行此操作:
BEGIN {
... all of your logging setup
}
通过运行语法检查并启用警告,您可以判断它是否是编译时警告:
% perl -cw program
如果在语法检查期间看到警告,则为编译时警告。
我宁愿在开发中捕获编译时警告。他们不应该通过生产系统。 :)