是否可以在不依赖默认级别的情况下使用Log :: Log4perl将一些结果写入文件?

问题描述

我想将一些结果记录到文件中,而又弄乱了我的日志水平。是否可以使用Log::Log4perl来做到这一点。我尝试遵循该文档,但是我只能发现它依赖于日志级别来打印文件?如here所示:

og::Log4perl->easy_init( { level    => $DEBUG,file     => ">>test.log",layout   => '%F{1}-%L-%M: %m%n' },{ level    => $DEBUG,file     => "STDOUT",layout   => '%m%n' },);

但是我想继续在屏幕上记录我的内容,而仅将其他消息放入日志文件中。但是我一直无法找到一种将结果记录到日志中的方法

use strict;
use warnings;
use Log::Log4perl;
use Win32::Console::ANSI;

my $results = "result.txt";
my $conf = q(
  log4perl.appender.SCREEN         = Log::Log4perl::Appender::ScreenColoredLevels
  log4perl.appender.SCREEN.layout  = Log::Log4perl::Layout::PatternLayout
  log4perl.appender.SCREEN.color.INFO = bright_white    
  log4perl.appender.SCREEN.color.WARN = bright_yellow    
  log4perl.appender.SCREEN.color.ERROR = bright_red    
  log4perl.appender.SCREEN.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %m  %50C::%L %n
);

my $log_level = "TRACE";
my $log_level_conf = "log4perl.category.".__FILE__." = ".$log_level.",SCREEN\n";   
$conf = $log_level_conf.$conf;
    
Log::Log4perl::init( \$conf );

my $log = Log::Log4perl::get_logger(__FILE__);

$log->info("INFO");
$log->debug("DEBUG");
$log->error("error");
$log->fatal("FATAL");
$log->trace("TRACE");

print "\n\n";

$log->info("Im doing foo");
$log->debug( "doing foo");
$log->trace( "crap from foo");
$log->info( "Im doing bar");
$log->debug( "Im doing foo");
$log->trace( "crap from bar");

# $log->result "Foo and bar done";

说结果的那一行是我要寻找的那一行,它是使用相同的$log将不同的功能写入日志的某种方式。

这可能吗?

编辑:按照@amit bhosale的建议,我仍然无法使其工作:

use strict;
use warnings;
use Log::Log4perl;
use Win32::Console::ANSI;


my $conf = q(

    log4perl.category = TRACE,AppResult

    log4perl.appender.SCREEN         = Log::Log4perl::Appender::ScreenColoredLevels
    log4perl.appender.SCREEN.layout  = Log::Log4perl::Layout::PatternLayout
    log4perl.appender.SCREEN.color.INFO = bright_white    
    log4perl.appender.SCREEN.color.WARN = bright_yellow    
    log4perl.appender.SCREEN.color.ERROR = bright_red    
    log4perl.appender.SCREEN.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %m  %50C::%L %n
    
    
    # Custom RESULT logs
    log4perl.filter.ResultsFilter  = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.ResultsFilter.LevelToMatch  = RESULT
    log4perl.filter.ResultsFilter.AcceptOnMatch = true  
     
    log4perl.appender.AppResult = Log::Log4perl::Appender::File
    log4perl.appender.AppResult.filename = results.log
    log4perl.appender.AppResult.mode=append  
    log4perl.appender.AppResult.Filter   = ResultsFilter
    log4perl.appender.AppResult.layout  = Log::Log4perl::Layout::PatternLayout
    log4perl.appender.AppResult.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %m  %50C::%L %n


);

my $log_level = "TRACE";
my $log_level_conf = "log4perl.category.".__FILE__." = ".$log_level.",SCREEN\n";   
$conf = $log_level_conf.$conf;

Log::Log4perl::Logger::create_custom_level("RESULT","WARN");
Log::Log4perl::init( \$conf );

my $log = Log::Log4perl::get_logger(__FILE__);

$log->info("INFO");
$log->debug("DEBUG");
$log->error("ERROR");
$log->warn("WARN");
$log->fatal("FATAL");
$log->trace("TRACE");

print "\n\n";

$log->info("Im doing foo");
$log->debug( "doing foo");
$log->trace( "crap from foo");
$log->info( "Im doing bar");
$log->debug( "Im doing foo");
$log->trace( "crap from bar");

$log->log('RESULT',"Foo and bar done");  

我遇到了priority RESULT isn't numeric at test_logs.pl line 60.异常

解决方法

另一种实现方式(无需创建自定义级别)。 (以上解决方案有效,这只是另一种方式)

创建的log.conf文件

############################################################
# A simple root logger with a Log::Log4perl::Appender::File 
# file appender in Perl.
############################################################
#There are six predefined log levels: FATAL,ERROR,WARN,INFO,DEBUG,and TRACE
# (in descending priority). Your configured logging level has to at least match 
#the priority of the logging message.

#If your configured logging level is TRACE,then messages logged with info(),#debug(),and trace() fatal(),error() and warn() will make their way through,#because their priority is higher or equal than the configured setting.

#This enables messages of priority TRACE or higher in the root hierarchy
# if a function/method wants a reference to the logger,it just calls the Logger's static get_logger($category) 
#method to obtain a reference to the one and only possible logger object 
#of a certain category.
log4perl.category.My.SCREEN = TRACE,Screen
#Appenders will be triggered whenever the configured logging 
#level requires a message to be logged
# log a message (display) on screen
log4perl.appender.Screen        = Log::Log4perl::Appender::ScreenColoredLevels
log4perl.appender.Screen.layout  = Log::Log4perl::Layout::PatternLayout
log4perl.appender.Screen.color.INFO = bright_white    
log4perl.appender.Screen.color.WARN = bright_yellow    
log4perl.appender.Screen.color.ERROR = bright_red    
log4perl.appender.Screen.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %m  %50C::%L %n

# RESULT appender
log4perl.category.My.Result= INFO,resultlog
# log a message to log file (in this case app.result file)
log4perl.appender.resultlog= Log::Log4perl::Appender::File
log4perl.appender.resultlog.filename = app.result
log4perl.appender.resultlog.mode=append
log4perl.appender.resultlog.layout=PatternLayout
log4perl.appender.resultlog.layout.ConversionPattern=[%p] %F %L %c - %m%n 

主要perl脚本

use strict;
use warnings;
use Log::Log4perl;
use Win32::Console::ANSI;

#configuration file is saved as log.conf,you need to read it in the startup section of your code
# After this done somewhere in the code,you can retrieve logger objects anywhere in the code.
# provide log configuration file path
Log::Log4perl->init("log.conf");

#Log::Log4perl uses categories to determine if a log statement 
#in a component should be executed or suppressed at the current logging level. 
#Most of the time,these categories are just the classes the log statements
my $log_screen = Log::Log4perl->get_logger("My::SCREEN");
my $log_result = Log::Log4perl->get_logger("My::Result");
# sample logging statement
$log_screen->info("INFO");
$log_screen->debug("DEBUG");
$log_screen->error("ERROR");
$log_screen->warn("WARN");
$log_screen->fatal("FATAL");
$log_screen->trace("TRACE");
# result
$log_result->info("this is a result message1");

输出到文件(示例)

[INFO] log.pl 24 My.Result - this is a result message1

输出到屏幕(不同颜色)

[2020-08-16 20:52:40.721] [INFO ] INFO                                                main::16
[2020-08-16 20:52:40.723] [DEBUG] DEBUG                                                main::17
[2020-08-16 20:52:40.723] [ERROR] ERROR                                                main::18
[2020-08-16 20:52:40.725] [WARN ] WARN                                                main::19
[2020-08-16 20:52:40.726] [FATAL] FATAL                                                main::20
[2020-08-16 20:52:40.727] [TRACE] TRACE                                                main::21
,

最后,由于@amit bhosale的建议,我得以使其工作。由于他没有发送回复,因此如果有人需要,我会举这个测试示例:

use strict;
use warnings;
use Log::Log4perl;
use Win32::Console::ANSI;

my $result_file = "results.log";
my $conf = <<EOT;

    log4perl.category = FATAL,AppResult

    log4perl.appender.SCREEN         = Log::Log4perl::Appender::ScreenColoredLevels
    log4perl.appender.SCREEN.layout  = Log::Log4perl::Layout::PatternLayout
    log4perl.appender.SCREEN.color.INFO = bright_white    
    log4perl.appender.SCREEN.color.WARN = bright_yellow    
    log4perl.appender.SCREEN.color.ERROR = bright_red    
    log4perl.appender.SCREEN.layout.ConversionPattern = [%d{yyyy-MM-dd HH:mm:ss.SSS}] [%-5p] %m  %50C::%L %n
    
    # Filter to match RESULT
    log4perl.filter.MatchResult               = Log::Log4perl::Filter::LevelMatch
    log4perl.filter.MatchResult.LevelToMatch  = RESULT
    log4perl.filter.MatchResult.AcceptOnMatch = true
    
    # Custom RESULT logs     
    log4j.appender.AppResult            = Log::Log4perl::Appender::File
    log4j.appender.AppResult.filename   = $result_file
    log4j.appender.AppResult.Filter     = MatchResult
    log4j.appender.AppResult.layout     = Log::Log4perl::Layout::SimpleLayout
    log4j.category.result               = RESULT,AppResult
    log4j.additivity.result             = 0


);
EOT

my $log_level = "TRACE";
my $log_level_conf = "log4perl.category.".__FILE__." = ".$log_level.",SCREEN\n";   
$conf = $log_level_conf.$conf;


Log::Log4perl::Logger::create_custom_level("RESULT","FATAL");
Log::Log4perl::init( \$conf );


my $log = Log::Log4perl::get_logger(__FILE__);
my $result = Log::Log4perl->get_logger("result");

$log->info("INFO");
$log->debug("DEBUG");
$log->error("ERROR");
$log->warn("WARN");
$log->fatal("FATAL");
$log->trace("TRACE");

print "\n\n";

$log->info("Im doing foo");
$log->debug( "doing foo");
$log->error( "error in foo");
$log->trace( "crap from foo");
$log->info( "Im doing bar");
$log->debug( "Im doing foo");
$log->trace( "crap from bar");

$result->result("this is a result message");

我不太了解这个库,但是似乎在配置中您将类别设置为最低级别,我写了FATAL。

然后为新过滤器创建过滤器,以仅显示自定义级别。然后,使用该自定义级别的附加程序,然后创建一个子类别,您调用该子类别,而不是只为结果而创建的主$log

我通过将该测试作为参考来使其工作: https://github.com/apple-opensource-mirror/CPANInternal/blob/35e8475f777c3c6eb7d4629f37daac0a1d2ea10e/Log-Log4perl-1.44/t/025CustLevels.t

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...