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?
所有的想法和建议都表示赞赏。
仍在学习史蒂夫
答案 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。