如果我在内部使用Log4Perl创建一个抽象函数,那么它将输出$logger->error_die($m)
行所在的行号,而不是fatalError()
函数的位置。
sub fatalError {
my $m = shift;
email($m, $c->{subject});
unlink $c->{lock};
$logger->error_die($m);
}
fatalError("Directory $d ...");
在Bash中,我通过在每条错误消息的末尾写[###]
来解决问题,并在病房之后解析Bash脚本以用唯一数字替换[###]
。这样我就知道错误输出的确切位置。但是,让第二个脚本修改源代码并不是最佳选择。
问题
有没有办法让Log4Perl
来编写调用fatalError()
函数的行号,或者如何解决问题?
答案 0 :(得分:3)
您可以使用caller获取子程序上方级别的详细信息。
但是,您也可以使用代码refs调用Log4perl方法。您可以执行所需的额外处理并返回您喜欢的消息:
$logger->error_die( sub { ... do some stuff ...; $log_message } );
对于电子邮件位,我想我会添加另一个appender来处理它。
答案 1 :(得分:2)
简单的方法是将此行添加到fatalError
方法中:
local $Log::Log4perl::caller_depth++;
这将使Log4perl"跳过"来自调用者上下文的当前子例程。
或者,如果您有许多这样的包装器方法,请将它们封装在一个包中,并使用Log4perl注册它们,如下所示:
Log::Log4perl->wrapper_register('My::Logger');
Log::Log4perl
documentation。
答案 2 :(得分:1)
令我感到震惊的是,如果您使用类Log::Dispatch::Email
之类的其他appender或朋友,并将其绑定到ERROR或FATAL级别,并在unlink
的子例程中执行$SIG{__DIE__}
{ {1}}或DESTROY
类的$c
方法,则您的子fatalError
将变得不必要,从而解决您的问题。
答案 3 :(得分:1)
从偷看Log4Perl的源代码中我可以看出,看起来它尊重warn
/ die
惯例,只是将位置信息附加到不会发送消息的消息上以换行结束。这意味着您可以通过您的函数添加位置并停止Log4Perl附加它:
sub fatalError {
my $m = shift;
my (undef, $file, $line) = caller;
my $at = " at $file line $line.\n";
email($m, $c->{subject});
unlink $c->{lock};
$logger->error_die($m . $at);
}