在后台运行的单个 perl 脚本可以保存多个 Log4Perl 实例吗?

Posted

技术标签:

【中文标题】在后台运行的单个 perl 脚本可以保存多个 Log4Perl 实例吗?【英文标题】:Can a single perl script running in background hold multiple instances of 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->wname . $serial;

            $server_logger->info($serial . " was created in " . $e->wname) 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】:

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

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

【讨论】:

感谢cime1000。然后我可以动态修改配置文件,但它看起来像一个非常肮脏的解决方案,尤其是当我将有 200 个管道同时运行时......!

以上是关于在后台运行的单个 perl 脚本可以保存多个 Log4Perl 实例吗?的主要内容,如果未能解决你的问题,请参考以下文章

在 /etc/init.d 脚本中调用守护进程被阻塞,不在后台运行

使用 Perl,如何在保持参照完整性的同时从单个表加载多个表?

从 Bash 或 Perl 脚本运行 SQL 语句?

从另一个环境调用 Perl 在后台

oracle sql (toad) - 执行多个查询,保存到单个 excel 文件

如何在 localhost 中运行 perl 脚本?