Может ли один Perl-скрипт, работающий в фоновом режиме, содержать несколько экземпляров Log4Perl? - PullRequest
2 голосов
/ 28 ноября 2011

У меня есть сценарий "server.pl", который работает в фоновом режиме и который самостоятельно регистрируется с использованием Log4Perl.

Этот сценарий постоянно читает в каталоге и обнаруживает новые файлы, созданные в нем с помощью модуля Linux :: Inotify2.

Каждый обнаруженный файл является сохраняемым объектом, который представляет собой конвейер, который необходимо запустить, и который долженнапишите в своем лог-файле.Моя проблема в том, что когда я вызываю 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;
}

РЕДАКТИРОВАТЬ: глобально это означает, что мне понадобится регистратор в зависимости от каждого экземпляра, а не регистратор, определенный только на уровне сценария.Есть идеи ?Спасибо

1 Ответ

1 голос
/ 29 ноября 2011

Я не скажу «НЕТ», но поскольку Log4perl послушен шаблону синглтона, это не очень хорошая идея, идти против течения!

Если вы действительно заинтересованы в этом, вы можете (или не можете!) использовать некоторые преимущества потоков и их общих данных, но создание и уничтожение потоков perl будет постепенно увеличивать объем используемой памяти без возможности возврата назад, что является проблемой для долгоживущих приложений!

...