【问题标题】:Can a single perl script running in background hold multiple instances of Log4Perl?在后台运行的单个 perl 脚本可以保存多个 Log4Perl 实例吗?
【发布时间】:2011-11-28 15:54:54
【问题描述】:

我有一个脚本“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;
}

编辑:在全球范围内,这意味着我需要一个取决于每个实例的记录器,而不是仅在脚本级别定义的记录器。有任何想法吗 ? 谢谢

【问题讨论】:

    标签: perl inotify log4perl


    【解决方案1】:

    我不会说“不”,但由于 Log4perl 服从单例模式,因此逆潮流而动不是一个好主意!

    如果你真的对它感兴趣,你可能会(也可能不会!)利用线程及其非共享数据的一些优势,但是创建和销毁 perl 线程会一点一点地增加,使用的内存量无法恢复,这是长寿命应用程序的问题!

    【讨论】:

    • 感谢cime1000。然后我可以动态修改配置文件,但它看起来像一个非常肮脏的解决方案,尤其是当我将有 200 个管道同时运行时......!
    猜你喜欢
    • 1970-01-01
    • 2015-10-31
    • 2011-01-15
    • 1970-01-01
    • 2015-05-19
    • 2010-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多