哪个脚本初始化了模块?

发布于 2024-12-01 12:05:59 字数 1990 浏览 2 评论 0原文

在 Perl 中,有没有办法知道哪个 .pl 脚本已经初始化了模块的 this 实例?

具体来说,我想获取调用模块的脚本的名称,该模块有一个 Log4perl 对象。这样,我就知道要写入模块内的哪个 .log 文件。

我这样做错了吗?如果我在 .pl 脚本中定义 $logger,模块内的任何 $logger 调用是否会写入与调用脚本相同的 .log 文件?

我还没有任何示例代码,但一直在阅读 Log4perl。基本上,如果我将 Appender 设置为文件 caller.log,这是我的调用脚本 caller.pl 的文件附加程序,我希望定义任何日志记录在自定义导入的模块中,还可以写入caller.log(如果可能的话,隐式地 - 显然我可以在初始化模块实例时传递日志名称的名称)。

如果不传递指定模块应写入哪个文件附加程序的参数,这是否可能? Log4perl 不是只使用一个 $logger 实例吗?

另外,请告诉我我是否已经出路,以及我是否应该考虑其他方法。

谢谢

编辑:抱歉,在我发布此内容后,我查看了相关链接,我想我的搜索措辞不正确。看起来这是一个非常好的解决方案: 自记录 Perl 模块(没有 Moose)

如果有人有任何其他想法,请告诉我。

编辑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));

In Perl, is there any way to tell which .pl script has initialized this instance of a module?

Specifically, I'd like to get the name of the script calling a module, which has a Log4perl object it. That way, I'll know which .log file I want to write to within the module.

Am I doing this wrong? If I define the $logger in my .pl script, will any $logger calls within the module write to the same .log file as the calling script?

I don't have any sample code yet, but have been reading up on Log4perl. Basically, if I set an Appender to a file, caller.log, which is the file appender for my calling script, caller.pl, I'd want any logging defined in the custom imported module, to also write to caller.log (implicitly, if possible -- obviously I could just pass the name of the log name when I initialize the module instance).

Is this possible without passing arguments specifying which File Appender the module should write to? Doesn't Log4perl use just one $logger instance?

Also, let me know if I'm way out, and if there's a different approach I should be considering.

Thank you

EDIT: Sorry, after I posted this, I looked at the Related Links, and I guess my search wording just wasn't correct. It looks like this is a pretty good solution: Self logging Perl modules (without Moose)

If anyone has any other ideas, though, please let me know.

EDIT 2: Finally tested, and got it to work as I had wanted -- was a lot easier than was making it out to be, too!

This is my setup, pretty much:

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));

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

故事↓在人 2024-12-08 12:05:59

您可以子类化 Log4perl,覆盖其构造函数。在自定义构造函数中,使用 caller() 获取调用构造函数的文件名并将其放入 $self 中。

You could subclass Log4perl, overriding its constructor. In your custom constructor, use caller() to get the filename that called the constructor and put it in $self.

听,心雨的声音 2024-12-08 12:05:59

您可以将子例程挂钩放入可以运行任意代码的 @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
...

You can put a subroutine hook into @INC that can run arbitrary code, as documented in perldoc -f require. For example:

# 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
...
云淡月浅 2024-12-08 12:05:59

$0 包含脚本的路径。如果您想要文件名组件,可以使用 File::Basename 的 basename

$0 contains the path to the script. You can use File::Basename's basename if you want to want the file name component.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文