2010-01-17 69 views
13

Log4perl是一個偉大的日誌記錄工具。如何將Perl警告捕獲到Log4perl日誌中?

warnings附註也是一個必不可少的工具。

但是,當Perl腳本作爲守護程序運行時,Perl警告將打印到STDERR中,在這些腳本中沒有人可以看到它們,而不是在相關程序的Log4perl日誌文件中。

有沒有辦法將Perl警告捕獲到Log4perl日誌中?

例如,該代碼將記錄蠻好的日誌文件,但如果這是作爲後臺進程運行,Perl的警告,將不會被包括在日誌中:

#!/usr/bin/env perl 
use strict; 
use warnings; 

use Log::Log4perl qw(get_logger); 

# Define configuration 
my $conf = q(
       log4perl.logger     = DEBUG, FileApp 
       log4perl.appender.FileApp   = Log::Log4perl::Appender::File 
       log4perl.appender.FileApp.filename = test.log 
       log4perl.appender.FileApp.layout = PatternLayout 
); 

# Initialize logging behaviour 
Log::Log4perl->init(\$conf); 

# Obtain a logger instance 
my $logger = get_logger("Foo::Bar"); 
$logger->error("Oh my, an error!"); 

$SIG{__WARN__} = sub { 
    #local $Log::Log4perl::caller_depth = $Log::Log4perl::caller_depth + 1; 
    $logger->warn("WARN @_"); 
}; 

my $foo = 100; 
my $foo = 44; 

這仍然打印出到STDERR:

"my" variable $foo masks earlier declaration in same scope at log.pl line 27. 

並且日誌文件不會收到此警告。

+0

您看到的警告是編譯器警告。在BEGIN塊中設置'$ SIG {__ WARN __}'處理程序:'my $ logger; BEGIN {$ logger = get_logger('Foo :: Bar'); $ SIG {__ WARN__} = sub {$ logger-> warn(「WARN @_」);' – daotoad 2010-01-17 23:25:40

+0

對!感謝所有人的答案,使用BEGIN塊中的$ SIG {__ WARN__}處理程序執行這個技巧,捕獲所有警告,包括編譯時警告。 – Freddie 2010-01-18 07:01:04

+2

你可能已經接受了答案,說::) – 2010-01-18 17:20:10

回答

10

它在Log4perl常見問題解答中爲Some module prints messages to STDERR. How can I funnel them to Log::Log4perl?My program already uses warn() and die(). How can I switch to Log4perl?

你的具體問題有一個額外的皺紋,你會看到一個編譯時警告,所以你需要調整FAQ的建議,儘早在編譯時設置日誌記錄。這樣做,在一個BEGIN塊儘量靠近源的頂部,你可以站在:

BEGIN { 
    ... all of your logging setup 
    } 

如果你可以告訴它是一個編譯時警告通過運行帶有警告語法檢查啓用:

% perl -cw program 

如果在語法檢查過程中看到警告,這是編譯時警告。

我寧願趕上開發中的編譯時警告。他們不應該通過生產系統。 :)

+0

我已經在常見問題解答中試過這些例子,但它們似乎沒有捕獲Perl警告,只有在程序中使用WARN – Freddie 2010-01-17 17:38:48

+0

的明確警告您必須先啓動日誌記錄警告開始顯示:) – 2010-01-18 02:16:51

15

您可以安裝一個WARN處理程序來執行此操作。它在Log4perl FAQ中提到。

我的程序已經使用warn()和die()。我如何切換到Log4perl?

如果你的程序已經使用Perl的警告()函數來噴涌出來的錯誤信息和你想引導那些到Log4perl世界,只是定義WARN處理你的程序或模塊所在:

use Log::Log4perl qw(:easy); 
$SIG{__WARN__} = sub { 
    local $Log::Log4perl::caller_depth = 
     $Log::Log4perl::caller_depth + 1; 
    WARN @_; 
}; 

這將捕獲在您的程序中任何顯式使用warn,以及Perlish有關使用未初始化值的警告等。