在多个模块中使用root logger

时间:2014-02-19 19:09:59

标签: perl log4perl

WinXP上的ActiveState Perl 5.12

我最近成为Log4perl的转换器并成功使用它,我为构成我的应用程序的每个模块定义了一个特定的记录器。例如:

Upload.pm -----

my $logger = get_logger("Upload");  # specific logger
my $layout = Log::Log4perl::Layout::PatternLayout->new( "%d %p> %F{1}:%L %M - %m%n");
my $appender = Log::Log4perl::Appender->new( "Log::Dispatch::File",
                                     filename => "Upload.log",
                                     mode     => "append"
                    );
$appender->layout($layout);
$logger->level($OFF);    #  or $INFO
$logger->add_appender($appender)
....

这很有效但很难跟踪众多日志文件中的程序流,例如Upload.log,Parse.log,FileRead.log等。快速解决方案:在所有记录器中使用相同的文件名。 这样做效果要好得多,但只要程序按顺序连续使用就可以了。

现在为皱纹 - 假设模块Upload.pm由几个程序使用,即readMyFiles.pl,readHerFiles.pl和dumpAllFiles.pl。运行readMyFiles.pl时,我希望Upload.pm中的记录器写入readMyFiles.pl.log,当runnng dumpAllFiles.pl希望Upload.pm中的记录器写入dumpAllFiles.pl.log

一种方法可能是在我的.pl文件中声明我们的变量$ logFileName,并在我的所有模块中使用它,如下所示:

                                      filename => $logFileName,

另一种可能是从我的.pm中删除所有记录器并仅在.pl中定义它们 - 但那么我如何在.pm中引用$ logger?

所有的想法和建议都表示赞赏。

仍在学习史蒂夫

1 个答案:

答案 0 :(得分:1)

在调用者中配置日志记录设置,而不是在模块中。如果其他人使用您的模块,他们可能不希望将事物记录到您执行的相同位置。他们可能还希望以不同方式格式化日志消息,或使用不同类型的appender,或者......列表继续。

您的模块应该只获取记录器并向其写入消息:

MyModule.pm

#!/usr/bin/perl

package MyModule;

use strict;

use Log::Log4perl qw(get_logger);

sub foo {
    my $logger = get_logger("Foo");
    $logger->debug("Hello from MyModule");
}

1;

您的主程序应配置和初始化日志记录:

logtest

#!/usr/bin/perl

use strict;
use warnings;

use Log::Log4perl qw(get_logger);
use MyModule;

Log::Log4perl->init("log4perl.cfg");

my $logger = get_logger("Foo");
$logger->debug("Hello from main");

MyModule::foo();

我更喜欢为Log4perl设置使用单独的配置文件:

log4perl.cfg

log4perl.logger.Foo=DEBUG, Screen

log4perl.appender.Screen=Log::Dispatch::Screen
log4perl.appender.Screen.Threshold=DEBUG
log4perl.appender.Screen.layout=Log::Log4perl::Layout::PatternLayout
log4perl.appender.Screen.layout.ConversionPattern=[%r] %F %L %c - %m%n

输出:

[0] logtest 12 Foo - Hello from main
[0] MyModule.pm 11 Foo - Hello from MyModule

请注意,在尝试模块中的Log::Log4perl->init之前,您必须在调用者中使用get_logger初始化日志记录。如果不这样做,将忽略来自模块的日志消息,您将收到以下警告:

Log4perl: Seems like no initialization happened.
Forgot to call init()?

有关详细信息,请参阅documentation