有没有办法使用
Log::Log4perl制作一个智能自记录模块,即使没有调用脚本没有初始化Log4perl,也可以将其操作记录到文件中?据我从文档中可以看出,使用Log4perl的唯一方法是从配置中运行脚本初始化它,然后实现Log4perl调用的模块根据调用者的Log4perl配置自行记录.
相反,我希望模块为Log4perl提供默认的初始化配置.这将为模块的类别提供默认文件追加器.然后,我可以通过在调用者中使用不同的配置启动Log4perl来覆盖此行为,如果需要,所有内容都可以正常工作.
这种防御性日志记录行为是否可行,或者我是否需要依赖于在调用我想要记录的模块的每个.pl脚本中启动Log4perl?
解决方法
我在
Moose中的自定义日志角色中执行此操作(删除了无关的复杂代码):
package MyApp::Role::Log; use Moose::Role; use Log::Log4perl; my @methods = qw( log trace debug info warn error fatal is_trace is_debug is_info is_warn is_error is_fatal logexit logwarn error_warn logdie error_die logcarp logcluck logcroak logconfess ); has _logger => ( is => 'ro',isa => 'Log::Log4perl::Logger',lazy_build => 1,handles => \@methods,); around $_ => sub { my $orig = shift; my $this = shift; # one level for this method itself # two levels for Class:;MOP::Method::Wrapped (the "around" wrapper) # one level for Moose::Meta::Method::Delegation (the "handles" wrapper) local $Log::Log4perl::caller_depth; $Log::Log4perl::caller_depth += 4; my $return = $this->$orig(@_); $Log::Log4perl::caller_depth -= 4; return $return; } foreach @methods; method _build__logger => sub { my $this = shift; my $loggerName = ref($this); Log::Log4perl->easy_init() if not Log::Log4perl::initialized(); return Log::Log4perl->get_logger($loggerName) };
如您所见,日志对象是自我初始化的 – 如果尚未调用Log :: Log4perl-> init,则调用easy_init.您可以轻松地修改它以允许每个模块自定义其记录器 – 我使用可选的角色参数,使用ref($this)作为默认回退.
PS.您可能还想查看MooseX::Log::Log4perl,这是我在使用上面的记录器角色之前开始的地方.有一天,当我开始讨论它时,我会向MX模块提交一些急需的补丁,以包含我添加的一些功能.