我使用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);
答案 0 :(得分:3)
一种方法是将custom "cspecs"添加到PatternLayout
。使用API
Log::Log4perl::Layout::PatternLayout::add_global_cspec( 'A', sub { ... } ); # can now use %A
这需要在调用new
之前进行,然后可以使用%A
说明符。
这可以在configuration中进行设置,如链接文档中所示。或者可以在add_global_cspec
对象上调用$layout
方法(但我无法弄清楚界面。)
匿名子接收
($layout, $message, $category, $priority, $caller_level)
layout:调用它的PatternLayout对象
消息:记录消息(%m)
类别:例如groceries.beverages.adult.beer.schlitz
优先权:例如DEBUG | WARN |信息| 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: some info more info INFO: info more and more info
这样的自定义说明符当然可以与提供的自定义说明符组合。
由于info(...)
中的列表被记录器连接到一个传递给appender的字符串,我们可以通过明显的接口决定调用者的标题
$logger->info('*', "... message ..."); # * for heading (add INFO:)
上面的第一个字符串是cspec
查找的正则表达式。
根据内容格式化每个日志行。更加圆润的选项是write your own appender (FAQ),这是一个相当简单的类,您可以根据需要保留和操作行。例如,请参阅bundling messages (FAQ)的示例。
最后,通过添加category来微调消息选择方式的正确方法。然后,您可以拉出一个新的记录器并将其配置为显示INFO:
(对于标题行),而该组中的其余消息由另一个记录器进行,配置为不显示它。有关简单示例,请参阅this post。
缺点是现在跟记录器,追加器和布局有很多关系,而且在这种情况下只需要进行一些小调整。
如果这些不合适,请说明您如何决定将哪些印刷品分组。