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: (для строки заголовка), в то время как остальные сообщения в этой группе отправляются другим регистратором, настроенным на его отображение. Смотрите этот пост для простого примера.

Недостатком является то, что теперь есть гораздо больше общего с регистраторами, приложениями и макетом, и все это только для небольшой настройки в этом случае.

Если они не соответствуют требованиям, уточните, как вы решаете, какие отпечатки следует сгруппировать.

Другие вопросы по тегам