使用Log :: Log4perl制作自记录模块 [英] Making self-logging modules with Log::Log4perl

查看:136
本文介绍了使用Log :: Log4perl制作自记录模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有一种方法可以使用 Log :: Log4perl 做一个聪明的自我-logging模块即使在没有调用脚本的情况下也无法将Log4perl初始化的情况下仍将其操作记录到文件中?据我所知,使用Log4perl的唯一方法是从配置中的运行脚本中对其进行初始化,然后实现Log4perl的模块将根据调用者的Log4perl配置进行日志记录.

Is there a way to use Log::Log4perl to make a smart self-logging module that logs its operations to a file even in the absence of the calling script not initializing Log4perl? As far as I can tell from the documentation, the only way to use Log4perl is to initialize it in the running script from a configuration, then modules implementing Log4perl calls log themselves based on the caller's Log4perl config.

相反,我希望这些模块为Log4perl提供默认的初始化配置.这将提供模块类别的默认文件追加器.然后,如果需要,我可以通过使用不同的配置在调用方中初始化Log4perl来覆盖此行为,希望一切都可以正常工作.

Instead, I'd like the modules to provide a default initialization config for Log4perl. This would provide the default file appender for the module's category. Then, I could override this behavior by initing Log4perl in the caller with a different config if needed, and everything would hopefully just work.

这种防御性的日志记录行为是否可能发生?还是我需要在每个调用要记录的模块的.pl脚本中依赖于启动Log4perl?

Is this sort of defensive logging behavior possible or am I going to need to rely on initing Log4perl in every .pl script that calls the module I want logged?

推荐答案

我在 Moose (已删除无关的复杂代码):

I do this in a custom Log role in Moose (irrelevant complicated code removed):

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)作为默认后备.

As you can see, the log object is self-initializing -- if Log::Log4perl->init has not been called, then easy_init is called. You could easily modify this to allow each module to customize its logger -- I do so with optional role parameters, with ref($this) as the default fallback.

PS.您可能还需要查看 MooseX :: Log :: Log4perl ,这是我使用上面的记录器角色之前开始的地方.有一天,当我解决它时,我将向该MX模块提交一些急需的补丁,以合并我添加的一些功能.

PS. You may also want to look at MooseX::Log::Log4perl, which is where I started before I used the logger role above. Someday when I get around to it I will submit some much-needed patches to that MX module to incorporate some features I have added.

这篇关于使用Log :: Log4perl制作自记录模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆