2012-05-17 20 views
11

Estoy tratando de configurar archivos de registro separados para diferentes paquetes. Estoy usando una clase Wrapper para un registrador log4j. Cada clase en mi aplicación llama a la misma clase contenedora. Mi clase de contenedor:¿Cómo crear diferentes archivos de registro para diferentes paquetes utilizando el mismo log4j logger?

public class MyLogger 
{ 
    private static Logger logger = Logger.getLogger(MyLogger.class.getName()); 
    .... 
    .... 
} 

Se llama así:

MyLogger.write(, ,); 

¿Hay una manera de configurar log4j de forma que produzca el registro de diferentes paquetes a diferentes archivos?

Gracias!

Editar:

Aquí es mi log4j.properties archivo:

log4j.rootLogger=DEBUG, infoout, aar 
log4j.logger.com.businessservice.datapopulation=DEBUG, aar 
log4j.additivity.com.businessservice.datapopulation=false 

log4j.appender.infoout = org.apache.log4j.RollingFileAppender 
log4j.appender.infoout.file=/app/aar_frontend.log 
log4j.appender.infoout.append=true 
log4j.appender.infoout.Threshold=DEBUG 
log4j.appender.infoout.MaxFileSize=2MB 
log4j.appender.infoout.MaxBackupIndex=10 
log4j.appender.infoout.layout = org.apache.log4j.PatternLayout 
log4j.appender.infoout.layout.ConversionPattern = %m%n 

log4j.appender.aar = org.apache.log4j.RollingFileAppender 
log4j.appender.aar.file=/app/aar/aar_backend.log 
log4j.appender.aar.append=true 
log4j.appender.aar.Threshold=DEBUG 
log4j.appender.aar.MaxFileSize=2MB 
log4j.appender.aar.MaxBackupIndex=10 
log4j.appender.aar.layout = org.apache.log4j.PatternLayout 
log4j.appender.aar.layout.ConversionPattern = %m%n 

Respuesta

4

Si crea un registrador estático dentro de la clase MyLogger, entonces tiene una instancia de Logger, con el nombre establecido en MyLogger. Cuando llama a ese registrador desde otros paquetes, Log4j no puede determinar el origen de esas llamadas, ya que todas usan el mismo registrador.

La mejor manera de manejar la situación, es definir un registrador por separado dentro de cada clase, pero si desea utilizar una clase como un punto de contacto con Log4j, entonces usted puede hacer esto:

package com.daniel.logger; 
import org.apache.log4j.Logger; 

import com.daniel.package1.ClassA; 
import com.daniel.package2.ClassB; 

public class MyLogger{ 

    public static void write(String message, Class<?> clazz){ 
     Logger.getLogger(clazz).info(message); 
    } 

    public static void main(String[] args){ 
     ClassA.log(); 
     ClassB.log(); 
    } 
} 

entonces, uno de la clase utilizando podría verse como:

package com.daniel.package1; 

import com.daniel.logger.MyLogger; 

public class ClassA { 

    public static void log(){ 
     MyLogger.write("ClassA",ClassA.class); 
    } 
} 

y el archivo log4j.properties se vería así:

log4j.appender.package1=org.apache.log4j.FileAppender 
log4j.appender.package1.File=package1.log 
log4j.appender.package1.layout=org.apache.log4j.PatternLayout 

log4j.appender.package2=org.apache.log4j.FileAppender 
log4j.appender.package2.File=package2.log 
log4j.appender.package2.layout=org.apache.log4j.PatternLayout 

log4j.logger.com.daniel.package1=DEBUG,package1 
log4j.logger.com.daniel.package2=DEBUG,package2 

Si no desea pasar la clase de claseA, se puede usar una mala pasada con la reflexión, que recibe el nombre de la clase llamada, pero yo no recomendaría que, debido a un impacto en el rendimiento:

public class MyLogger 
{ 

    public static void write(String message){ 
     StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace(); 
     Logger.getLogger(stackTraceElements[2].getClassName()).info(message); 
    } 

    public static void main(String[] args){ 
     ClassA.log(); 
     ClassB.log(); 
    } 
} 
+0

¡Gracias !.1 pregunta más por favor: ¿Puedo verificar (en java) si el appender para la clase en particular está definido o no en el archivo de configuración de log4j? – HashimR

0

Usted puede hacer esto así (com.myco.a y com.myco.b siendo los 2 paquetes diferentes):

log4j.logger.com.myco.a=DEBUG, infoout 
log4j.logger.com.myco.b=DEBUG, aar 

Cheers.

+0

Intenté. ¡Sin suerte! – HashimR

+0

¿Está utilizando el mismo registrador en su código? Se supone que debes crear un registrador en cada clase – Philippe

+0

Estoy usando la misma clase de registrador contenedora en todas mis aplicaciones. También mencionado en la pregunta. – HashimR

0

Creando 2 appenders y 2 loggers harían lo que quisieran.

+0

¿No se puede lograr usando un solo 'Registrador'? – HashimR

0

Lea la ubicación del archivo personalizado requerido desde un archivo de propiedad más o menos para cada paquete. A continuación, puede utilizar el siguiente método para actualizar la ubicación del archivo log4j establecida en el archivo log4j prop:

private void updateLog4jConfiguration(String logFile) { 
    java.util.Properties properties = new Properties(); 
    try { 
     InputStream configStream = getClass().getResourceAsStream("/log4j.properties"); 
     properties.load(configStream); 
     configStream.close(); 
     } 
    catch (IOException e) { 
     System.out.println("Error: Cannot laod configuration file "); 
     } 
    properties.setProperty("log4j.appender.FILE.file", logFile); 
    org.apache.log4j.LogManager.resetConfiguration(); 
    org.apache.log4j.PropertyConfigurator.configure(properties); 
} 
+1

Eso no va a funcionar demasiado bien. Log4j deberá cambiar entre dos archivos todo el tiempo, cerrando el flujo a uno y abriendo al otro. – daniel

Cuestiones relacionadas