Как я могу перехватить предупреждения Perl в журналах Log4perl? - PullRequest
13 голосов
/ 17 января 2010

Log4perl - отличный инструмент для ведения журнала.

Предупреждения Прагма также является важным инструментом.

Однако, когда сценарии Perl работают как демоны, предупреждения Perl выводятся в STDERR, где их никто не видит, а не в файл журнала Log4perl соответствующей программы.

Есть ли способ перехватить предупреждения Perl в журнале Log4perl?

Например, этот код будет нормально протоколироваться в файл журнала, но в случае, если он запускается как демон, предупреждения Perl не будут включены в журнал:

#!/usr/bin/env perl
use strict;
use warnings;

use Log::Log4perl qw(get_logger);

# Define configuration
my $conf = q(
                log4perl.logger                    = DEBUG, FileApp
                log4perl.appender.FileApp          = Log::Log4perl::Appender::File
                log4perl.appender.FileApp.filename = test.log
                log4perl.appender.FileApp.layout   = PatternLayout
);

# Initialize logging behaviour
Log::Log4perl->init( \$conf );

# Obtain a logger instance
my $logger = get_logger("Foo::Bar");
$logger->error("Oh my, an error!");

$SIG{__WARN__} = sub {
    #local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1;
    $logger->warn("WARN @_");
};

my $foo = 100;
my $foo = 44;

Это все еще выводится на STDERR:

"my" variable $foo masks earlier declaration in same scope at log.pl line 27.

И файл журнала не перехватывает это предупреждение.

Ответы [ 2 ]

15 голосов
/ 17 января 2010

Вы можете установить обработчик WARN для этого. Это упомянуто в Log4perl FAQ .

Моя программа уже использует warn () и die (). Как я могу переключиться на Log4perl?

Если ваша программа уже использует функцию warn () Perl для вывода сообщений об ошибках, и вы хотите направить их в мир Log4perl, просто определите обработчик WARN , в котором находится ваша программа или модуль:

use Log::Log4perl qw(:easy);
$SIG{__WARN__} = sub {
    local $Log::Log4perl::caller_depth =
        $Log::Log4perl::caller_depth + 1;
    WARN @_;
};

Это позволит отразить любое явное использование warn в вашей программе, а также предупреждения Perlish об использовании неинициализированных значений и т. П.

10 голосов
/ 17 января 2010

Это в FAQ по Log4perl как Некоторые модули печатают сообщения в STDERR. Как я могу направить их в Log :: Log4perl? и Моя программа уже использует warn () и die (). Как я могу переключиться на Log4perl? .

Ваша конкретная проблема имеет добавленную морщину, что вы видите предупреждение во время компиляции, поэтому вам нужно настроить совет FAQ, чтобы настроить ведение журнала во время компиляции как можно раньше. Сделайте это в блоке BEGIN как можно ближе к верху источника:

 BEGIN {
     ... all of your logging setup
     }

Вы можете определить, является ли это предупреждением во время компиляции, запустив проверку синтаксиса с включенными предупреждениями:

 % perl -cw program

Если вы видите предупреждение во время проверки синтаксиса, это предупреждение во время компиляции.

Я бы предпочел перехватить предупреждения времени компиляции в процессе разработки. Они не должны пройти через производственную систему. :)

...