2011-04-18 25 views
54

Estoy usando log4j para registrar el error y otra información del sistema. pero viene de la información registrada dos veces en el nivel INFO.log4j registrando dos veces

public static void main(final String... args) throws Exception { 

    LOGGER.info("program started"); 
    try { 
     // try body codes 
    } catch (Exception ex) { 
     LOGGER.info("program start-up failed.",ex); 
    } 
} 

sin embargo, cuando el programa se inicia o no la información registrada dos veces, cualquiera me puede ayudar a encontrar lo que podría ser la razón de ello.

+0

Puede haber un problema de configuración o de inicialización. ¿Dónde inicializa el registrador? ¿No llamas dos veces a Logger.getLogger (SomeClass.class)? Algún código adicional podría brindarnos más información para ayudarlo. – MaSEL

Respuesta

75

Parece que sus mensajes están siendo registrados una vez por el registrador raíz y nuevamente por el registrador específico ya que puede tener configurados los appenders (pueden estar en diferentes lugares -en un archivo de propiedades y luego en código).

Esto se puede resolver estableciendo additivity en falso en su registrador. Log4j manual menciona aditividad en la sección Anexos y diseño. Verifique

+2

¿Es así como * debes * resolverlo, o una curita que enmascara un problema de configuración más grande? –

+1

Sin el registrador, no se registra nada. Cuando vuelvo a agregar el registrador, se registra dos veces. Cuando establezco la aditividad en falso, se registra una vez. ¿Que está pasando aqui? –

+0

@DanielKaplan Si sus registradores tienen alguna estructura jerárquica, sí. Parafraseando desde el enlace manual, supongamos que solo desea mensajes de ERROR para todas las clases, excepto Foo, del que desea ver todos los mensajes. Establecería la aditividad del registrador Foo en falso, por lo que los mensajes de ERROR no continuarán hasta la raíz y se imprimirán nuevamente. Sin aditividad, la configuración sería mucho más complicada y menos sostenible, por lo que diría que es correcta. – whrrgarbl

29

De acuerdo con atlantis.

log4j.rootCategory=INFO, console 
log4j.logger.org.hibernate=INFO 

La configuración de propiedades anterior causará el doble de registro.

Sin embargo la adición de

log4j.additivity.org.hibernate=false 

ha solucionado el problema.

Echa un vistazo a la página 62 de este libro. http://books.google.com/books?id=hZBimlxiyAcC&printsec=frontcover#v=onepage&q&f=false

+6

¿no debería ser 'falso', no 'verdadero'? –

+0

Google books parece esconder al azar ciertas páginas. [Aquí está] (http://veerasundar.com/blog/2009/08/log4j-tutorial-additivity-what-and-why/) una publicación de blog que encontré útil. Incluye un ejemplo más extenso que incluye algunas entradas de ** log4j.category ... ** –

28

Para aquellos formato XML uso:

<logger name="package.class" additivity="false"> 
    <level value="info" /> 
    <appender-ref ref="file" /> 
    <appender-ref ref="console" /> 
</logger> 

Nota: Por defecto, los madereros tienen su bandera aditividad establece en true.

2

Si puede ejecutar el programa con un depurador Java, coloque un punto de interrupción en el programa donde ocurre una de estas llamadas de doble registro.

Examine el objeto del registrador en el depurador. Si es un org.apache.log4j.Logger (v 1.2.x), entonces puede tener un AppenderAttachableImpl. Puede consultar el AppenderAttachableImpl para la lista de appenders.

Si encuentra más de 1 apéndice, este podría ser el problema, y ​​una pista para solucionarlo.

2

Simplemente añadir

logger.setadditivity(false); 

a su código (Reference).

Estamos obteniendo resultados dobles en la consola, es porque los appenders no son singletons, son aditivos. Es decir, una categoría hereda todos los apéndices de sus antepasados ​​(por defecto). Si agregamos un appender a una categoría y escribe en la misma secuencia subyacente (consola, mismo archivo, etc.) que otro appender, el mismo mensaje de registro aparecerá dos veces (o más) en el registro. Además, si se configuran dos categorías en una jerarquía para usar el mismo nombre de apéndice, Log4j escribirá dos veces en ese appender. Configurado para esa categoría

0

Una posible alternativa para ajustar la propiedad additivity es examinar sus registradores de lo más específico a lo más genérico. En el siguiente ejemplo, esperaríamos ver el inicio de sesión doble en la consola para cualquier evento de registro que ocurra en foo.bar.LoggingExampleClass. Sería seguro eliminar el apilador de consola adicional de foo.bar.LoggingExampleClass Logger como ya está cubierto por el Root Logger.

<Logger name="foo.bar.LoggingExampleClass" level="DEBUG"> 
    <AppenderRef ref="Console" /> <!-- THIS APPENDER COULD BE REMOVED --> 
    <AppenderRef ref="FooBarPackageLogging" /> 
</Logger> 

<Root level="WARN"> 
    <AppenderRef ref="Console" /> 
    <AppenderRef ref="MainLogFile" /> 
</Root> 

hay ventajas y desventajas tanto para el enfoque de ajuste de aditividad y el enfoque de ajuste appender. Desactivar la adición podría inadvertidamente detener el uso de un appender de registrador de nivel genérico deseable. En el ejemplo anterior, establecer la propiedad additivity="false" en foo.bar.LoggingExampleClass Logger significaría que el evento de registro no se agregaría al MainLogFile al que se hace referencia en el Root Logger.

Por otro lado, confiar en los padres adjuntos podría ser problemático si se cambian los apéndices principales sin examinar los efectos en los registradores más granulares. Por ejemplo, supongamos que hay un requisito de que los eventos de registro foo.bar.LoggingExampleClass se escriban en la consola. Actualmente se encuentran en la configuración de ejemplo anterior debido a la adición, incluso si se elimina el apilador de la consola del foo.bar.LoggingExampleClass Logger. Sin embargo, si el apilador de consola también se eliminó del registrador de raíz sin ningún ajuste adicional, el requisito ya no se cumpliría.