2010-01-17 12 views
13

Log4perl es una gran herramienta para el registro.¿Cómo puedo detectar las advertencias de Perl en los registros de Log4perl?

El pragma warnings es también una herramienta esencial.

Sin embargo, cuando las secuencias de comandos de Perl se ejecutan como daemons, las advertencias de Perl se imprimen en STDERR donde nadie puede verlas, y no en el archivo de registro Log4perl del programa correspondiente.

¿Hay alguna forma de detectar las advertencias de Perl en el log Log4perl?

Por ejemplo, este código registrará muy bien para el archivo de registro, pero en caso de que esto se ejecuta como un demonio, las advertencias de Perl se no se incluirán en el 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; 

impresiones Esto todavía fuera de STDERR:

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

Y el archivo de registro no capta esta advertencia.

+0

La advertencia que ve es una advertencia del compilador. Establezca el controlador '$ SIG {__ WARN __}' en un bloque BEGIN: 'my $ logger; COMIENZO {$ logger = get_logger ('Foo :: Bar'); $ SIG {__ WARN__} = sub {$ logger-> warn ("WARN @_"); ' – daotoad

+0

¡Correcto! Gracias a todos por las respuestas, usando el manejador $ SIG {__ WARN__} en un bloque BEGIN es el truco, detecta todas las advertencias, incluidas las advertencias de tiempo de compilación. – Freddie

+2

Podrías haber aceptado la respuesta que decía :) –

Respuesta

10

Está en las preguntas más frecuentes de Log4perl como Some module prints messages to STDERR. How can I funnel them to Log::Log4perl? y My program already uses warn() and die(). How can I switch to Log4perl?.

Su problema específico tiene el inconveniente adicional de que está viendo una advertencia en tiempo de compilación, por lo que debe ajustar el consejo de Preguntas frecuentes para configurar el registro en tiempo de compilación lo antes posible. Hacer que en un bloque BEGIN tan cerca de la parte superior de la fuente que usted puede estar parado:

BEGIN { 
    ... all of your logging setup 
    } 

Puede decir si es una advertencia de tiempo de compilación mediante la ejecución de una comprobación de sintaxis con advertencias activada:

% perl -cw program 

Si ve la advertencia durante la verificación de sintaxis, es una advertencia en tiempo de compilación.

Preferiría detectar las advertencias en tiempo de compilación en desarrollo. No deberían pasar a un sistema de producción. :)

+0

He intentado estos ejemplos en las preguntas frecuentes, pero no parecen captar las advertencias de Perl, solo advertencias explícitas en el programa usando WARN – Freddie

+0

Tienes que iniciar el registro antes las advertencias comienzan a aparecer :) –

15

Puede instalar un controlador WARN para hacerlo. Se menciona en Log4perl FAQ.

Mi programa ya usa warn() y die(). ¿Cómo puedo cambiar a Log4perl?

Si el programa ya utiliza la función de Perl advertir() para vomitar mensajes de error y que le gustaría canalizar aquellos en el mundo Log4perl, simplemente definen un WARN manejador donde su programa o módulo reside:

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

Esto capturará cualquier uso explícito de warn en su programa, así como advertencias de Perlish sobre el uso de valores no inicializados y similares.

Cuestiones relacionadas