log4perl: группировка сообщений
Я использую log4perl
регистрировать сообщения от perl
скрипт. С mwe.pl
как показано ниже, я получаю следующий (желательный) вывод в test.log
INFO: some information
more information
Моя текущая реализация использует:
my $logmessage = "some information\n";
$logmessage .= "more information";
$logger->info($logmessage);
В частности, обратите внимание, что я указал разрыв строки вручную, используя \n
, чего я бы хотел избежать.
Есть ли способ, которым я могу достичь желаемого результата (test.log
), без необходимости ремонтировать мой вход в систему?
mwe.pl
#!/usr/bin/env perl
use strict;
use warnings;
use Log::Log4perl qw(get_logger :levels);
my $logger = get_logger();
$logger->level($INFO);
my $layout = Log::Log4perl::Layout::PatternLayout->new("%p: %m{indent}%n");
my $appender = Log::Log4perl::Appender->new(
"Log::Dispatch::File",
filename => "test.log",
mode => "write",
);
$appender->layout($layout);
$logger->add_appender($appender);
my $logmessage = "some information\n";
$logmessage .= "more information";
$logger->info($logmessage);
exit(0);
1 ответ
Одним из способов является добавление пользовательских "cspecs" к вашему PatternLayout
, Использование API
Log::Log4perl::Layout::PatternLayout::add_global_cspec( 'A', sub { ... } ); # can now use %A
где это должно прийти до вызова new
которые затем могут использовать %A
спецификатор.
Это можно настроить в конфигурации, как показано в связанных документах. Или же add_global_cspec
метод может быть вызван на $layout
объект (но я не мог понять интерфейс.)
Анонимный саб получает
($layout, $message, $category, $priority, $caller_level)
макет: объект PatternLayout, который вызвал его
сообщение: сообщение в журнале (%m)
категория: например, бакалейные товары. напитки.адульт.бир.шлитц
приоритет: например, DEBUG | WARN | INFO | ERROR | FATAL
caller_level: на скольких уровнях необходимо выполнить резервное копирование стека вызовов, чтобы найти вызывающего
что можно использовать для реализации критериев форматирования отпечатков.
Вот простой пример, определяющий весь формат
use strict;
use warnings;
use Log::Log4perl qw(get_logger :levels);
my $logger = get_logger();
$logger->level($INFO);
Log::Log4perl::Layout::PatternLayout::add_global_cspec(
'A', sub { return (
$_[1] !~ /^more/ # /^more/ taken to indicate
? "$_[3]: " # the continuation criterion,
: ' ' x length $_[3] . ' ' # or start with 'INFO: '
) . $_[1]
});
my $layout = Log::Log4perl::Layout::PatternLayout->new("%A%n");
my $appender = Log::Log4perl::Appender->new(
"Log::Dispatch::File",
filename => "new_test.log",
mode => "write",
);
$logger->info('some info');
$logger->info('more info');
$logger->info('info');
$logger->info('more and more info');
который печатает
ИНФОРМАЦИЯ: немного информации больше информации ИНФО: информация все больше и больше информации
Такой пользовательский спецификатор, конечно, можно комбинировать с предоставленными.
Поскольку список в info(...)
присоединяется регистратором в строку, которая передается appender(s), мы можем выбрать заголовок в вызывающей стороне с очевидным интерфейсом
$logger->info('*', "... message ..."); # * for heading (add INFO:)
где первая строка выше является любым регулярным выражением в нашем cspec
ищет.
Это форматирует каждую строку журнала в зависимости от ее содержимого. Более округлый вариант - написать свой собственный appender (FAQ), который является довольно простым классом, в котором вы можете хранить строки и манипулировать ими по мере необходимости. См. Пример связывания сообщений (FAQ), например.
Наконец, правильный способ точной настройки способа выбора сообщений - добавление категории. Затем вы можете вытащить новый регистратор и настроить его для отображения INFO:
(для строки заголовка), в то время как остальные сообщения в этой группе отправляются другим регистратором, настроенным на его отображение. Смотрите этот пост для простого примера.
Недостатком является то, что теперь есть гораздо больше общего с регистраторами, приложениями и макетом, и все это только для небольшой настройки в этом случае.
Если они не соответствуют требованиям, уточните, как вы решаете, какие отпечатки следует сгруппировать.