2010-01-17 22 views
13

Log4perl è un ottimo strumento per la registrazione.Come posso catturare gli avvisi Perl nei log di Log4perl?

Il pragma warnings è anche uno strumento essenziale.

Tuttavia, quando gli script Perl sono in esecuzione come daemon, gli avvisi Perl vengono stampati in STDERR dove nessuno può vederli e non nel file di log Log4perl del programma in questione.

C'è un modo per catturare gli avvisi Perl nel log di Log4perl?

Ad esempio, questo codice sarà il login bene nel file di registro, ma nel caso in cui questo viene eseguito come un demone, gli avvertimenti Perl saranno non essere inclusi nel registro:

#!/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; 

stampe questa immagine Ancora out to STDERR:

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

E il file di registro non rileva questo avviso.

+0

L'avviso visualizzato è un avviso del compilatore. Imposta il gestore '$ SIG {__ WARN __}' in un blocco BEGIN: 'my $ logger; INIZIA {$ logger = get_logger ('Foo :: Bar'); $ SIG {__ WARN__} = sub {$ logger-> warn ("WARN @_"); ' – daotoad

+0

Giusto! Grazie a tutti per le risposte, l'utilizzo del gestore $ SIG {__ WARN__} in un blocco BEGIN fa il trucco, cattura tutti gli avvertimenti, inclusi gli avvisi di compilazione. – Freddie

+2

Avresti potuto accettare la risposta che diceva :) –

risposta

10

È nelle domande frequenti di Log4perl come Some module prints messages to STDERR. How can I funnel them to Log::Log4perl? e My program already uses warn() and die(). How can I switch to Log4perl?.

Il tuo problema specifico ha la rugosità aggiunta che stai vedendo un avviso in fase di compilazione, quindi è necessario regolare il consiglio delle FAQ per impostare la registrazione in fase di compilazione il prima possibile. Farlo in un BEGIN blocco più vicino alla parte superiore della sorgente di come si può stare:

BEGIN { 
    ... all of your logging setup 
    } 

Si può dire se si tratta di un avvertimento in fase di compilazione eseguendo un controllo della sintassi con avvisi abilitato:

% perl -cw program 

Se viene visualizzato l'avviso durante il controllo della sintassi, si tratta di un avviso in fase di compilazione.

Preferisco comunque rilevare gli avvisi in fase di compilazione in fase di sviluppo. Non dovrebbero passare attraverso un sistema di produzione. :)

+0

Ho provato questi esempi nelle FAQ, ma non sembrano catturare avvisi Perl, solo avvisi espliciti nel programma usando WARN – Freddie

+0

Devi avviare la registrazione prima gli avvertimenti iniziano a mostrare :) –

15

È possibile installare un gestore WARN per eseguire questa operazione. È menzionato nel Log4perl FAQ.

Il mio programma utilizza già warn() e die(). Come posso passare a Log4perl?

Se il programma utilizza già la funzione di Perl warn() a vomitare messaggi di errore fuori e si vorrebbe incanalare quelli nel mondo log4perl, basta definire un WARN handler in cui il vostro programma o modulo risiede:

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

In questo modo verrà catturato qualsiasi utilizzo esplicito di warn nel programma, nonché avvisi Perlish sull'utilizzo di valori non inizializzati e simili.

Problemi correlati