Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
create_custom_level()需要声明在哪里(log4perl)?_Perl_Logging - Fatal编程技术网

create_custom_level()需要声明在哪里(log4perl)?

create_custom_level()需要声明在哪里(log4perl)?,perl,logging,Perl,Logging,我试图在Perl中创建一个自定义消息级别的“警报”(介于警告和错误之间),但始终得到错误消息: create_custom_level must be called before init or first get_logger() call at /usr/share/perl5/Log/Log4perl/Logger.pm line 705. 我的自定义级别声明如下所示: use Log::Log4perl qw(get_logger); use Log::Log4perl::Level

我试图在Perl中创建一个自定义消息级别的“警报”(介于警告和错误之间),但始终得到错误消息:

create_custom_level must be called before init or first get_logger() call at /usr/share/perl5/Log/Log4perl/Logger.pm line 705.
我的自定义级别声明如下所示:

use Log::Log4perl qw(get_logger); 
use Log::Log4perl::Level; 
Log::Log4perl::Logger::create_custom_level("ALERT", "ERROR");
据我所知,将其放在任何打算使用自定义级别的文件的顶部就足够了。所以我不知道我做错了什么。查看从中引发错误的文件Logger.pm显示,在声明自定义级别之前,正在初始化记录器。有人知道这是怎么发生的吗

另外,我向您保证,在这里创建自定义关卡是正确的选择,即使不赞成

编辑:问题已回答!上面的答案更像是调试指南,所以我想从评论部分复制我的解决方案,以便将来的读者更可能看到它

我发现有两个步骤可以解决我的问题:

  • 我需要将create_custom_level放在BEGIN{…}语句中,以便它在编译时运行,因为它显然被编译时调用的记录器初始化打败了

  • 我意识到,在主脚本(.pl)及其模块(.pm)中放置相同的create_custom_级别行是多余的,并且导致了部分问题。根据在编译时执行语句的顺序(如“use”和“BEGIN”),在多个文件中调用create_custom_level可能会导致多个文件之间的顺序:“create custom level”、“initialize logger”、“create custom level”。我没有弄清楚记录器是在什么地方被初始化的,但是我能够通过尽早创建自定义级别来绕过这个问题(对于其他没有经验的程序员来说,使用perl调试器是理解行和文件执行顺序的关键)。最好将create_custom_级别放在原始脚本或它使用的第一个模块中


  • 希望这对其他人有帮助

    您提供的代码不会产生错误

    也许您的脚本后面还有一些在编译时进行计算的代码——在
    use
    语句中加载的模块,或者在
    BEGIN{…}
    块中加载的一些代码——用于初始化记录器

    如果不清楚这可能发生在何处,可以使用Perl调试器找出记录器调用可能来自何处。首先,将这一行放在文件的
    uselog::Log4perl之后
    使用Log::Log4perl::Level语句:

    BEGIN { $DB::single=1 }
    
    此语句将使调试器在编译时阶段停在此行,并允许您在编译阶段的其余部分停在断点处。然后启动调试器

    $ perl -d the_script.pl
    
    在关键
    Log::Log4perl
    函数上设置断点

    DB<1> b Log::Log4perl::init
    DB<2> b Log::Log4perl::get_logger
    
    DB b Log::Log4perl::init
    DB b Log::Log4perl::get_logger
    
    开始执行代码

    DB<3> c
    
    dbc
    
    当代码停止时,获取堆栈跟踪

    Log::Log4perl::get_logger(/usr/local/lib/perl5/site_perl/5.18.1/Log/Log4perl.pm:371):
    371:        my $category;
    
    DB<4> T
    
    Log::Log4perl::get_logger(/usr/local/lib/perl5/site_perl/5.18.1/Log/Log4perl.pm:371):
    371:我的$category;
    分贝
    
    如果它实际上是在BEGIN块中运行的或通过use运行的,那么在查找perl调试器教程后,您不能设置断点,除非太晚。我明白您的意思。感谢您将我设置为正确的路径。可能的解决方案是在编译时使用BEGIN执行create_custom_级别行吗?这似乎可以保证它先于任何初始化,只要它在每个文件中都排在第一位。@Max-是的,值得一试。就是这样!谢谢你的帮助。对于遇到相同问题的未来读者,我还意识到在主脚本(.pl)及其模块(.pm)中放置相同的create_custom_级别行是多余的,并且导致了我的部分问题。根据在编译时执行语句的顺序(如“use”和“BEGIN”),在多个文件中调用create_custom_level可能会导致以下顺序:“create custom level”、“initialize logger”、“create custom level”。最好在原始脚本或第一个“使用”模块中放置一次。