在Perl中,是否有任何方法可以告诉哪个.pl脚本初始化了这个模块实例?
具体来说,我想获得调用模块的脚本的名称,该模块有一个Log4perl
对象。这样,我就知道我想在模块中写入哪个.log文件。
我做错了吗?如果我在我的.pl脚本中定义$logger
,模块内的任何$logger
调用将写入与调用脚本相同的.log文件吗?
我还没有任何示例代码,但一直在阅读Log4perl
。基本上,如果我将Appender设置为文件caller.log
,这是我的调用脚本caller.pl
的文件Appender,我希望自定义导入模块中定义的任何日志记录也写入caller.log
(如果可能的话,隐式地—显然,我可以在初始化模块实例时传递日志名称的名称)。
如果不传递指定模块应该写入哪个文件追加器的参数,这是可能的吗?Log4perl
不是只使用一个$logger
实例吗?
还有,如果我没有办法,如果我应该考虑其他方法,请告诉我。
谢谢
编辑:对不起,在我发布这个之后,我看了相关链接,我猜我的搜索措辞不正确。看起来这是一个很好的解决方案:自记录Perl模块(没有Moose)
如果有人有任何其他的想法,请告诉我。
EDIT 2:最后测试了,并让它像我想要的那样工作——比想象的要容易得多!
这就是我的设置:
Module.pm
package Module;
use Log::Log4perl qw(get_logger :levels);
use Data::Dumper;
my $logger = get_logger("Module");
sub new {
my ($class, $name) = @_;
my @caller = caller(0);
$logger->debug("Creating new Module. Called by " . Dumper(@caller));
my $object = { 'name' => $name };
return bless($object, $class);
}
caller.pl
use Module;
use Log::Log4perl qw(get_logger :levels);
use Data::Dumper;
my $PATH = "$ENV{'APPS'}/$ENV{'OUTDIR'}";
my $SCRIPT = "caller";
my $logger = get_logger("Module");
$logger->level($DEBUG);
my $file_appender = Log::Log4perl::Appender->new("Log::Dispatch::File",
filename=> "$PATH/$SCRIPT.log",
mode => "append",);
$logger->add_appender($file_appender);
my $layout = Log::Log4perl::Layout::PatternLayout->new("%d %p> %F{1}:%L %M - %m%n");
$file_appender->layout($layout);
my $lib = Module->new('Chris');
$logger->info(Dumper($lib));
您可以继承Log4perl,覆盖它的构造函数。在您的自定义构造函数中,使用caller()
获取调用构造函数的文件名,并将其放在$self
中。
您可以在@INC
中放入一个子例程钩子,它可以运行任意代码,如perldoc -f require
中所述。例如:
# UseLogger.pm
package UseLogger;
sub import { unshift @INC, &UseLogger::log_use }
sub log_use {
my ($self, $filename) = @_;
my @c = caller(0);
print "Module $filename required in file $c[1] line $c[2]n";
return 0;
}
1;
$ perl -MUseLogger my_script.pl
Module feature.pm required in file my_script.pl line 2
Module Encode.pm required in file my_script.pl line 5
Module XSLoader.pm from /usr/lib/perl5/5.14.0/cygwin-thread-multi-64int/Encode.pm line 13
...
$0
包含脚本的路径。如果你想要文件名组件,可以使用File::Basename的basename
。