1

我正在尝试编写一个记录器角色(使用 Log::Dispatchouli,但这不重要),它告诉我来自哪个包、子、行等。我一直在发出日志消息。自然地,我尝试了调用者,但堆栈中充满了 Moose 类,并且帧数在不同情况下会发生变化。有没有办法使用 MOP 或 Moose 获得类似的信息?或者也许有一个模块来过滤调用者堆栈?非常感谢!

package logger

sub log {...}

#some_package
log "bla"

#intended output
some_package l.12 bla
4

1 回答 1

6

您可以使用Carp 的 longmess 函数来生成堆栈跟踪。它的文档记录很差,但它已经存在了很长时间并且使用起来非常安全。 cluck并且分别confess是公正warn longmessdie longmess

使用的优点longmess()Carp 有几个全局变量来控制它认为是“内部”的内容。这有效地阻止了它们出现在堆栈跟踪中。你关心的两个是@CARP_NOT%Carp::Internal。您应该使用哪个取决于您的日志记录方式。

@CARP_NOT仅影响源自 set 的包的堆栈跟踪@CARP_NOT。所以你可以这样写你的记录器:

package MyLogger;

use Carp;
our @CARP_NOT = qw(MyLogger Moose More::Moose::Stuff);

sub trace {
    # For example...
    warn Carp::longmess("Trace message");
}

MyLogger::trace()应该报告一条跟踪消息,但忽略它本身、Moose 以及您放入的任何其他内容@CARP_NOT

%Carp::Internal有点像这个的全球版本。如果您无法将 Carp 函数的调用位置集中到日志记录包中,则可以将包添加到%Carp::Internal. 不幸的是,这是全局的,并且存在设置全局变量的所有问题。如果您要弄乱它,请务必将包添加到它,例如$Carp::Internal{"Some::Module"}++. 不要像%Carp::Internal = ("Some::Module" => 1).

于 2012-12-15T21:35:25.070 回答