Какой скрипт инициализировал модуль? - PullRequest
3 голосов
/ 23 августа 2011

В Perl, есть ли способ узнать, какой скрипт .pl инициализировал этот экземпляр модуля?

В частности, я хотел бы получить имя скрипта, вызывающего модуль, который имеет объект Log4perl. Таким образом, я буду знать, какой файл .log я хочу записать в модуле.

Я делаю это неправильно? Если я определю $logger в моем скрипте .pl, будут ли любые вызовы $logger внутри модуля записываться в тот же файл .log, что и вызывающий скрипт?

У меня еще нет примера кода, но я читал о Log4perl. По сути, если я установлю для Appender файл caller.log, который является файловым приложением для моего вызывающего сценария caller.pl, я бы хотел, чтобы любая запись в журнале, определенная в пользовательском импортированном модуле, также записывалась в caller.log ( неявно, если это возможно - очевидно, я мог бы просто передать имя имени журнала, когда я инициализирую экземпляр модуля).

Возможно ли это без передачи аргументов, указывающих, в какой File Appender должен записываться модуль? Разве 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));

Ответы [ 3 ]

2 голосов
/ 23 августа 2011

В @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
...
2 голосов
/ 23 августа 2011

$0 содержит путь к скрипту.Вы можете использовать File :: Basename's basename, если хотите использовать компонент имени файла.

2 голосов
/ 23 августа 2011

Вы можете создать подкласс Log4perl, переопределяя его конструктор. В вашем пользовательском конструкторе используйте caller(), чтобы получить имя файла, который вызвал конструктор, и поместить его в $self.

...