3

Perlでは、どの.plスクリプトがモジュールのこのインスタンスを初期化したかを知る方法はありますか?

Log4perl具体的には、オブジェクトを持つモジュールを呼び出すスクリプトの名前を取得したいと思います。そうすれば、モジュール内でどの.logファイルに書き込みたいかがわかります。

私はこれを間違っていますか?$logger.plスクリプトでを定義した場合$logger、モジュール内の呼び出しは、呼び出し元のスクリプトと同じ.logファイルに書き込みますか?

私はまだサンプルコードを持っていませんが、を読んでいLog4perlます。基本的にcaller.log、呼び出し元のスクリプトのファイルアペンダーであるファイルにアペンダーを設定した場合caller.pl、カスタムインポートされたモジュールで定義されたログも書き込みますcaller.log(暗黙的に、可能であれば-明らかに私はできます)モジュールインスタンスを初期化するときに、ログ名の名前を渡すだけです)。

これは、モジュールが書き込むファイルアペンダーを指定する引数を渡さなくても可能ですか?1つのインスタンス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));
4

3 に答える 3

2

Log4perlをサブクラス化して、そのコンストラクターをオーバーライドすることができます。カスタムコンストラクターで、を使用caller()してコンストラクターを呼び出したファイル名を取得し、に配置し$selfます。

于 2011-08-23T14:29:02.667 に答える
2

@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
...
于 2011-08-23T16:10:11.223 に答える
2

$0スクリプトへのパスが含まれています。basenameファイル名コンポーネントが必要な場合は、File::Basenameを使用できます。

于 2011-08-23T18:04:56.823 に答える