Как я могу улавливать предупреждения Perl в журналах Log4perl?
Log4perl - отличный инструмент для ведения журнала.
warnings прагма также является важным инструментом.
Однако, когда скрипты 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.
И файл журнала не распознает это предупреждение.
Ответы
Ответ 1
Это в Log4perl FAQ как Некоторые модули печатают сообщения в STDERR. Как я могу их перехватить в Log:: Log4perl? и Моя программа уже использует warn() и die(). Как переключиться на Log4perl?.
В вашей конкретной проблеме есть добавленная морщина, которую вы видите во время компиляции, поэтому вам необходимо настроить часто задаваемые вопросы, чтобы настроить регистрацию во время компиляции как можно раньше. Сделайте это в блоке BEGIN
как можно ближе к верхней части источника:
BEGIN {
... all of your logging setup
}
Вы можете узнать, было ли это предупреждение о компиляции, выполнив проверку синтаксиса с включенными предупреждениями:
% perl -cw program
Если вы видите предупреждение во время проверки синтаксиса, это предупреждение о компиляции.
Я бы предпочел поймать предупреждения во время компиляции в разработке. Они не должны проходить через производственную систему.:)
Ответ 2
Для этого можно установить обработчик WARN
. Он упоминается в Log4perl FAQ.
Моя программа уже использует warn() и die(). Как я могу переключиться на Log4perl?
Если ваша программа уже использует функцию perl warn() для извлечения сообщений об ошибках и вы хотите перенаправить их в мир Log4perl, просто определите обработчик WARN, где находится ваша программа или модуль:
use Log::Log4perl qw(:easy);
$SIG{__WARN__} = sub {
local $Log::Log4perl::caller_depth =
$Log::Log4perl::caller_depth + 1;
WARN @_;
};
Это позволит зафиксировать любое явное использование WARN
в вашей программе, а также предупреждения Perlish об использовании неинициализированных значений и т.д.