2

バックグラウンドで実行され、Log4Perl を使用して自己ログ記録するスクリプト「server.pl」があります。

このスクリプトは、ディレクトリを継続的に読み取り、Linux::Inotify2 モジュールで作成された新しいファイルを検出します。

検出された各ファイルは、実行されるパイプラインであり、独自のログファイルに書き込む必要がある Storable オブジェクトです。私の問題は、パイプラインのロガーを初期化するために Log4Perl::init を呼び出すと、新しい初期化によって以前の初期化が上書きされたため、server.pl 自体がログに記録されなくなることです。問題は、「server.pl」スクリプトに Log4Perl の複数のインスタンス (事前に未定義の数) を保持させるにはどうすればよいかということです。

以下は、'server.pl' の切り詰められたバージョンです (退屈なものはありません)。

#!/usr/bin/perl
use warnings;
use strict;
use Carp;
use Log::Log4perl;
use Linux::Inotify2;
use Storable;

Log::Log4perl->init('/.../log4perl.conf');
my $server_logger = Log::Log4perl->get_logger("server");

my $tracker = PipelineBatchTracker->new( _logger => $server_logger);

my $inotify = new Linux::Inotify2()
      or $server_logger->logcroak("Unable to create new inotify object: $!");

# Sets non-blocking inotify
$inotify->blocking(0);

# define watcher
$inotify->watch
    (
        "/.../serial/",
        IN_CREATE,
        sub {
            my $e = shift;
            my $pipe;
            my $serial = $e->{name};
            my $full = $e->{w}{name} . ${serial};

            $server_logger->info(${serial} . " was created in " . $e->{w}{name}) if $e->IN_CREATE;

            eval {
                my $pipe = retrieve("${full}");
                $server_logger->logcroak("Unable to retrieve storable object") unless defined $pipe;

                $server_logger->info(${serial} . " loaded into a Synegie::Pipeline object");
                # This methods call Log::Log4perl->init
                # and this is bad cause the server and former
                # running pipelines are not logging anymore !!!
                $pipe->setLogger();

                $tracker->addPipeline($pipe);
            };
            if ($@) {
                $server_logger->error("server : Failed to add pipeline : $@");
            }
        }
    );


while (1) {
    $server_logger->trace("--------------------- AND AGAIN -------------------------");
    $inotify->poll;
    sleep 2;

    eval {
        $tracker->poke();
    };
    if ($@) {
        $server_logger->error("server : $@");
    }

    sleep 30;
}

編集:グローバルに、これは、スクリプトレベルでのみ定義されたロガーではなく、各インスタンスに応じてロガーが必要になることを意味します。何か案は ?ありがとう

4

1 に答える 1

1

「いいえ」とは言いませんが、Log4perl はシングルトン パターンに従順であるため、流れに逆らうのはあまり良い考えではありません。

本当に興味があるなら、スレッドとその共有されていないデータを利用するかもしれません (またはしないかもしれません!)。長生きするアプリケーションの問題!

于 2011-11-28T23:15:35.010 に答える