0

如果我在内部使用 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(),或者应该如何解决问题?

4

4 回答 4

3

您可以使用caller获取子例程上方级别的详细信息。

但是,您也可以使用代码引用调用 Log4perl 方法。您执行所需的额外处理并返回您喜欢的消息:

$logger->error_die( sub { ... do some stuff ...; $log_message } );

对于电子邮件位,我想我会添加另一个附加程序来处理它。

于 2014-07-30T13:56:04.127 回答
2

简单的方法是将此行添加到您的fatalError方法中:

local $Log::Log4perl::caller_depth++;

这将使 Log4perl 从调用者上下文中“跳过”当前子例程。

或者,如果您有许多这样的包装方法,请将它们封装在一个包中,然后使用 Log4perl 注册它们,如下所示:

Log::Log4perl->wrapper_register('My::Logger');

该主题包含在Log::Log4perl 文档中。

于 2014-07-30T15:47:54.293 回答
1

令我震惊的是,如果您使用了类似Log::Dispatch::Email或朋友的类的附加附加程序并将其绑定到 ERROR 或 FATAL 级别,并在其中一个或类的方法unlink引用的子例程中执行了该操作,那么您的子程序将变得不必要,从而解决您的问题。$SIG{__DIE__}DESTROY$cfatalError

于 2014-07-30T13:47:19.660 回答
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);
}
于 2014-07-30T13:58:52.683 回答