log4perl:分组消息

log4perl: grouping messages

我正在使用 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);

一种方法是将 custom "cspecs" 添加到您的 PatternLayout。使用 API

Log::Log4perl::Layout::PatternLayout::add_global_cspec(
    'A', sub { ... }
);                    # can now use %A

这需要在调用 new 之前出现,然后可以使用 %A 说明符。

这可以在 configuration 中设置,如链接文档所示。或者可以在$layout object 上调用add_global_cspec 方法(但我想不通接口。)

匿名子收到

($layout, $message, $category, $priority, $caller_level)  

layout: the PatternLayout object that called it
message: the logging message (%m)
category: e.g. groceries.beverages.adult.beer.schlitz
priority: e.g. DEBUG|WARN|INFO|ERROR|FATAL
caller_level: how many levels back up the call stack you have to go to find the caller

什么可以用来实现打印格式的标准。

这里是一个简单的例子custom-specifying整个格式

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: some info
      more info
INFO: info
      more and more info

这样的自定义说明符当然可以与提供的说明符结合使用。

由于 info(...) 中的列表由记录器连接成一个字符串,该字符串传递给附加程序,我们可以通过明显的界面决定调用者的标题

$logger->info('*', "... message ...");  # * for heading (add INFO:)

上面的第一个字符串是 cspec 中的正则表达式查找的内容。

这会根据其内容格式化每个日志行。例如,更全面的选择是 write your own appender (FAQ), which is a rather simple class where you can keep and manipulate lines as needed. See an example of bundling messages (FAQ)

最后,fine-tune 如何选择消息的正确方法是添加一个 category. Then you can pull a new logger and configure it to display INFO: (for the header line), while the rest of messages in that group go by the other logger, configured to not display it. See this post 作为简单示例。

缺点是现在有很多与记录器、追加器和布局有关的事情,在这种情况下所有这些都只是一个小的调整。

如果这些不符合要求,请说明您如何决定将哪些印刷品分组。