我正在尝试编写一个记录器角色(使用Log :: Dispatchouli,但这无关紧要)告诉我从哪个包,子,行等我发出了日志消息。当然,我尝试使用调用者,但堆栈中充满了Moose类,并且帧的数量在不同情况下会发生变化。有没有办法使用MOP或Moose获得类似的信息?或者可能有一个模块来过滤来电堆栈?非常感谢!
package logger
sub log {...}
#some_package
log "bla"
#intended output
some_package l.12 bla
答案 0 :(得分:6)
您可以使用Carp's longmess function生成堆栈跟踪。它的记录很少,但它已存在很长时间并且使用起来非常安全。 cluck
和confess
分别仅为warn longmess
和die longmess
。
使用longmess()
的优势是Carp has several global variables来控制它认为是“内部”的内容。这有效地阻止它们出现在堆栈跟踪中。您关注的两个是@CARP_NOT
和%Carp::Internal
。您应该使用哪种方法取决于您的登录方式。
@CARP_NOT
仅影响源自设置@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)
那样覆盖它。