Использование Log :: Log4perl с MCE (многоядерный движок) Perl - PullRequest
0 голосов
/ 29 апреля 2019

Я использую MCE для параллельной обработки для одного из моих проектов.Я сталкиваюсь с проблемой при записи выходных данных из MCE (для ведения журнала я использую Log4perl).

Я просмотрел предоставленные примеры и обнаружил, что они печатаются в STDOUT / STDERR или в какой-то файл журнала, предоставленный в то время.Доступны опции MCE-> sendto () и MCE-> print (), но я не уверен, как использовать их с log4perl.

package ABC;
use strict;
use warnings;
use MCE;

sub new {
    my $class = shift;
    my ($self) = {@_};
    return bless $self, $class;
}

sub initialize_mce {
     my $mce = MCE->new(
        max_workers => 5,
        input_data => \@input_data,
        on_post_exit => \&on_post_exit,
        user_begin => \&user_begin,
        user_end   => \&user_end,
        user_func => \&run_function
    );

}
sub on_post_exit {
    my ($self, $e) = @_;
    # I want to write something like this -
    # I want to log to my global log file using Log4perl which is initialized in some other package and passed to this package

    # $self->{'logger'}->info("$e->{wid}: $e->{pid}: $e->{status}: $e->{msg}: $e->{id}");

    print "$e->{wid}: $e->{pid}: $e->{status}: $e->{msg}: $e->{id}\n";
}

sub user_begin {                   ## Called once at the beginning
    my ($self, $e) = @_;
    print "$$ start";
}

sub user_end {                     ## Called once at the end
    my $self = shift;
    #$self->{'logger'}->info("$$ end");
    print "$$ end";
}

sub run_function {
    my ($self) = @_;
    my $wid = MCE->wid;
    $self->{'logger'}->info("Running...$wid");
    my $input_data = $_;
    ###
    #Rest of subroutine 
    ####
}
1;

1 Ответ

0 голосов
/ 01 мая 2019

Я нашел решение. Если кто-то также столкнулся с этой проблемой, он может попробовать это -

Вы должны инициализировать 'user_output' и 'user_error'. Из документации MCE -

    user_error => \&user_error,         ## Default undef
    user_output => \&user_output,       ## Default undef

    # MCE will forward data to user_error/user_output,
    # when defined, for the following methods.

    # MCE->sendto(\*STDERR, "sent to user_error\n");
    # MCE->printf(\*STDERR, "%s\n", "sent to user_error");
    # MCE->print(\*STDERR, "sent to user_error\n");
    # MCE->say(\*STDERR, "sent to user_error");

    # MCE->sendto(\*STDOUT, "sent to user_output\n");
    # MCE->printf("%s\n", "sent to user_output");
    # MCE->print("sent to user_output\n");
    # MCE->say("sent to user_output");

Так что в моем случае -

sub initialize_mce {
     my $mce = MCE->new(
        max_workers => 5,
        input_data => \@input_data,
        on_post_exit => \&on_post_exit,
        user_begin => \&user_begin,
        user_end   => \&user_end,
        user_func => \&run_function,
        user_output => sub {
            $logger->info($_[0]);            # Log4perl Obj
        },
        user_error => sub {
            $logger->error($_[0]);          # Log4perl Obj
        }
    );
}

А в других функциях вам просто нужно «напечатать» в STDOUT / STDERR Например .-

sub user_begin {                   ## Called once at the beginning
    my ($self, $e) = @_;
    $mce->print("Process Id : ".$$." start");
    # OR to log error 
    $mce->print(\*STDERR, "Exception/Error Found");
}

Я не уверен, что это единственный способ, или есть какой-то другой эффективный способ, но пока он выполняет свою работу.

...