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

发布于 2024-12-18 07:38:20 字数 2201 浏览 0 评论 0原文

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

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

I have a script "server.pl" which is running in background and which is self-logging using Log4Perl.

This script continuously reads in a directory and detects new files created in it with Linux::Inotify2 module.

Each detected file is a Storable object which is a pipeline to be run and that must write in its own logfile. My problem is that when I call Log4Perl::init to initialize the logger for a pipeline, server.pl doesn't log itself anymore because the new initialization has overwritten the previous one. So the question is how can I make the 'server.pl' script hold multiple instances (undefined number in advance) of Log4Perl ?

Here follows a truncated version of 'server.pl' (without boring stuff)

#!/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;
}

EDIT : Globally, this means that I would need a logger depending on each instance rather than a logger only defined at the script level. Any ideas ?
Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

遇见了你 2024-12-25 07:38:20

我不会说“不”,但由于 Log4perl 遵循单例模式,逆潮流而动并不是一个好主意!

如果您真的对此感兴趣,您可能(或可能不会!)利用线程及其非共享数据的一些优势,但是创建和销毁 Perl 线程会逐渐增加使用的内存量,并且无法恢复,这是长期应用程序的一个问题!

I will not say 'NO' but since Log4perl is obedient to the singleton pattern isn't a very good idea go against the tide!

If you are really interested on it you may (or may not!) take some advantages of threads and its unshared data, but create and destroy perl threads will increase,little by little, the amount of used memory with no way back, which is a problem for long living applications!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文