2008-09-17 17 views
13

Tenemos varios trabajos que se ejecutan simultáneamente que tienen que usar la misma información de configuración para log4j. Todos ellos están volcando los registros en un archivo usando el mismo appender. ¿Hay alguna forma de que cada trabajo nombre dinámicamente su archivo de registro para que permanezcan separados?log4j nombres de archivo de registro?

Gracias
Tom

Respuesta

21

Se puede pasar una propiedad del sistema Java para cada puesto de trabajo? Si es así, se puede parametrizar como esto:

java -Dmy_var=somevalue my.job.Classname 

Y luego, en sus log4j.properties:

log4j.appender.A.File=${my_var}/A.log 

Usted podría poblar la propiedad del sistema Java con un valor del entorno del host (por ejemplo) que identificaría de manera única la instancia del trabajo.

0

Se puede configurar mediante programación log4j al inicializar el trabajo.

También puede establecer el archivo log4j.properties en tiempo de ejecución a través de una propiedad del sistema. Desde el manual:

Establecer la variable de cadena de recursos para el valor de la propiedad log4j.configuration sistema. La forma preferida de especificar el archivo de inicialización predeterminado es a través de la propiedad del sistema log4j.configuration. En caso de que la propiedad del sistema log4j.configuration no esté definida, entonces establezca el recurso de variable de cadena en su valor predeterminado "log4j.properties".

Suponiendo que ejecuta los trabajos desde diferentes comandos de Java, esto les permitirá usar diferentes archivos log4j.properties y diferentes nombres de archivo para cada uno.

Sin un conocimiento específico de cómo se ejecutan sus trabajos, ¡es difícil de decir!

0

Tom puede especificar y anexar para cada trabajo. Vamos que tiene 2 puestos de trabajo correspondientes a dos diferentes paquetes de Java com.tom.firstbatch y com.tom.secondbatch, tendría algo como esto en log4j.xml:

<category name="com.tom.firstbatch"> 
     <appender-ref ref="FIRST_APPENDER"/> 
    </category> 
    <category name="com.tom.secondtbatch"> 
     <appender-ref ref="SECOND_APPENDER"/> 
    </category> 
3

Si los nombres de los trabajos son conocidos por delante de vez, podría incluir el nombre del trabajo cuando realice la llamada a getLogger(). A continuación, puede vincular diferentes apéndices a diferentes registradores, con nombres de archivo separados (u otros destinos).

Si no se puede saber el nombre del trabajo antes de tiempo, podría configurar el registrador en tiempo de ejecución en lugar de utilizar un archivo de configuración:

FileAppender appender = new FileAppender(); 
appender.setFileName(...); 
appender.setLayout(...); 
Logger logger = Logger.getLogger("com.company.job."+jobName); 
logger.addAppender(appender); 
2

Puede hacer que cada trabajo establezca NDC o MDC y luego escribir un apéndice que varíe el nombre basado en el valor NDC o MDC. Crear un nuevo appender no es demasiado difícil. También puede haber un appender que se ajuste a la factura en el sandbox log4j.Comience a buscar en http://svn.apache.org/viewvc/logging/log4j/trunk/contribs/

0

puede aplicar lo siguiente:

  • Portavarillas ThreadLocal para la identidad de su trabajo.
  • Extienda FileAppender, su FileAppender tiene que mantener un Map que tenga un QuietWriter para cada identidad de trabajo. En subAppend método, se obtiene la identidad de su trabajo desde el ThreadLocal, miras hacia arriba (o crear) la Quietwriter y escribir en él ...

te despache un código por correo si lo desea ..

3

Tenemos algo similar implementado en nuestro sistema. Almacenamos los registradores específicos en un HashMap e inicializamos los appenders para cada uno de ellos según sea necesario.

He aquí un ejemplo:

public class JobLogger { 
private static Hashtable<String, Logger> m_loggers = new Hashtable<String, Logger>(); 
private static String m_filename = "..."; // Root log directory 

public static synchronized void logMessage(String jobName, String message) 
{ 
    Logger l = getJobLogger(jobName); 
    l.info(message); 
} 

public static synchronized void logException(String jobName, Exception e) 
{ 
    Logger l = getJobLogger(partner); 
    l.info(e.getMessage(), e); 
} 

private static synchronized Logger getJobLogger(String jobName) 
{ 
    Logger logger = m_loggers.get(jobName); 
    if (logger == null) { 
     Layout layout = new PatternLayout("..."); 
     logger = Logger.getLogger(jobName); 
     m_loggers.put(jobName, logger); 
     logger.setLevel(Level.INFO); 
     try { 
      File file = new File(m_filename); 
      file.mkdirs(); 
      file = new File(m_filename + jobName + ".log"); 
      FileAppender appender = new FileAppender(layout, file.getAbsolutePath(), false); 
      logger.removeAllAppenders(); 
      logger.addAppender(appender); 
    } 
     catch (Exception e) 
    { ... } 
    } 
    return logger; 
} 
} 

Luego de utilizar esto en su trabajo sólo tiene que utilizar una entrada de una línea como la siguiente:

Esto creará un archivo de registro para cada trabajo nombre y colóquelo en su propio archivo con ese nombre de trabajo en el directorio que especifique.

Puede juguetear con otros tipos de apéndices y tal como está escrito continuará añadiéndose hasta que se reinicie la JVM, lo que puede no funcionar si ejecuta el mismo trabajo en un servidor que siempre está activo, pero esto da la idea general de cómo puede funcionar

0

log4j.logger.com.foo.admin =, AdminFileAppender log4j.logger.com.foo.report =, ReportFileAppender

Es otra manera de hacer esta tarea .. aquí es la com.foo.admin nombre completo del paquete

1

Basado en la respuesta de shadit. Si cada trabajo puede identificarse mediante el método principal de la clase que se inició, puede usar la propiedad del sistema sun.java.command que contiene el nombre completo de la clase iniciada. Por ejemplo a esto:

log4j.appender.LOGFILE.File=${sun.java.command}.log 

lo uso junto con un TimestampFileAppender así:

log4j.appender.LOGFILE=TimestampFileAppender 
log4j.appender.LOGFILE.TimestampPattern=yyyy_MM_dd__HH_mm 
log4j.appender.LOGFILE.File=${sun.java.command}_{timestamp}.log 

De esta manera cuando estoy desarrollando en Eclipse consigo un nuevo archivo de registro para cada nuevo proceso que yo ejecutar, identificado por el nombre de clase de la clase con el método principal y la hora en que se inició.

Cuestiones relacionadas