2011-10-19 18 views
29

estoy usando logback, y yo estoy tratando de establecer el nombre del archivo de registro mediante programación dentro de mi programa Java (similar a Setting Logback Appender path programmatically), y yo trataba de adaptar dicha solución de la siguiente manera:Logback - ajuste el nombre de archivo de registro mediante programación

en logback-test.xml:

<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
    <file>log/${log_file_name}.log</file> 
    ... 

y luego otra vez en mi programa Java:

String logFileName = "" + System.currentTimeMillis(); // just for example 
System.setProperty("log_file_name", logFileName); 

LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory(); 
ContextInitializer ci = new ContextInitializer(lc); 
lc.reset(); 
try 
{ 
    // I prefer autoConfig() over JoranConfigurator.doConfigure() so I 
    // wouldn't need to find the file myself. 
    ci.autoConfig(); 
} 
catch (JoranException e) 
{ 
    // StatusPrinter will try to log this 
    e.printStackTrace(); 
} 
StatusPrinter.printInCaseOfErrorsOrWarnings(lc); 

Sin embargo, el resultado son dos registros, uno completo y nombrado como quería, por ejemplo, "131904 1145343.log ", y el otro está vacío y se llama" log_file_name_IS_UNDEFINED.log ". ¿Cómo evito que se cree este otro archivo de registro vacío?

+0

El único problema de su código parece ser que está configurando 'System.setProperty (" log_file_name ", logFileName);' demasiado tarde. Ejecútelo antes de que se haya ejecutado la configuración automática de Logback y tenga lo que desea. – Robert

+0

En realidad, se puede hacer mucho más fácilmente que en su fragmento de código: http://stackoverflow.com/a/21886071/709537 –

Respuesta

30

Creo que lo que está más cerca de lo que desea.

import ch.qos.logback.classic.Logger; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 
import ch.qos.logback.core.FileAppender; 
import ch.qos.logback.core.util.StatusPrinter; 
import org.slf4j.LoggerFactory; 
import ch.qos.logback.classic.LoggerContext; 

public class Main { 
    public static void main(String[] args) { 
    LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory(); 

    FileAppender fileAppender = new FileAppender(); 
    fileAppender.setContext(loggerContext); 
    fileAppender.setName("timestamp"); 
    // set the file name 
    fileAppender.setFile("log/" + System.currentTimeMillis()+".log"); 

    PatternLayoutEncoder encoder = new PatternLayoutEncoder(); 
    encoder.setContext(loggerContext); 
    encoder.setPattern("%r %thread %level - %msg%n"); 
    encoder.start(); 

    fileAppender.setEncoder(encoder); 
    fileAppender.start(); 

    // attach the rolling file appender to the logger of your choice 
    Logger logbackLogger = loggerContext.getLogger("Main"); 
    logbackLogger.addAppender(fileAppender); 

    // OPTIONAL: print logback internal status messages 
    StatusPrinter.print(loggerContext); 

    // log something 
    logbackLogger.debug("hello"); 
    } 
} 

Si todo lo que necesita es añadir una marca de tiempo del nombre de archivo de registro, ya logback supports the timestamp element. Por lo tanto, en realidad no necesita ningún código personalizado en absoluto.

+0

gracias por su ayuda, voy a probar esto. (Solo estaba usando una marca de tiempo como ejemplo, el nombre de archivo real sería diferente) – conorsomahony

+0

Gracias, esto funciona - en logback-test.xml Ya no estoy especificando un apéndice de archivo, y en el código Java estoy creando uno y adjuntando al registrador 'raíz'. – conorsomahony

+3

No es el objetivo de slf4j evitar la importación de ch.qos.logback.classic.Logger – Zombies

4

Parece que el registrador se inicializa dos veces. Primera vez, probablemente cuando la aplicación se carga y no pudo resolver el ${log_file_name}. Si inicia la aplicación con -Dlog_file_name=*something*, puede verificar este comportamiento si crea otro archivo de registro con el nombre *something*

+0

Lo que podría hacer para establecer programáticamente el nombre de archivo es crear una instancia de un apéndice de archivo con la configuración requerida (nombre, categoría, paquete, etc.) y agregarlo a la jerarquía de apéndices. – srkavin

+0

Gracias, agregué exactamente '-Dlog_file_name = verify' a los argumentos de VM, y de hecho obtuve un registro vacío llamado" verify.log "- ¿Hay alguna manera de detener el inicio de sesión del registrador dos veces? – conorsomahony

8

Esto es lo que puede hacer para ignorar los creation.Below archivo extra es el archivo de configuración

<configuration> 
<appender name="FILE" class="ch.qos.logback.core.FileAppender"> 
<!-- "application-name" is a variable --> 
<File>c:/logs/${application-name}.log</File> 
<layout class="ch.qos.logback.classic.PatternLayout"> 
<Pattern>%d %p %t %c - %m%n</Pattern> 
</layout> 
</appender> 
<root level="debug"> 
<appender-ref ref="FILE"/> 
</root> 
</configuration> 

Aquí está la parte java,

LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory(); 
JoranConfigurator jc = new JoranConfigurator(); 
jc.setContext(context); 
context.reset(); // override default configuration 
// inject the name of the current application as "application-name" 
// property of the LoggerContext 
context.putProperty("application-name", NAME_OF_CURRENT_APPLICATION); 
jc.doConfigure("/path/to/the/above/configuration/file.xml"); 

Tengo esto de aquí http://logback.qos.ch/faq.html#sharedConfiguration

+0

Otra forma que puede hacer es inicializar todas las variables del sistema antes de invocar Logger.This también funciona. –

+0

Terminó usando System.setProperty (..) en lugar de restablecer el contexto. Me parece más limpio. Gracias por el ej. –

+0

Desafortunadamente, el uso de las propiedades del sistema no puede funcionar cuando desea compartir la configuración – Brice

10

Para separar/tamizar los mensajes de registro en archivos diferentes según un atributo de tiempo de ejecución, es posible que desee utilizar ch.qos.logback.classic.sift.SiftingAppender.

En pocas palabras, esto le permite configurar un FileAppender (o cualquier otro appender) con <file>${userid}.log</file> donde ${userId} está sustituido basa en la MDC (Mapped Diagnostic Context) (por ejemplo, MDC.put("userid", "Alice");). Vea el primer enlace para el ejemplo completo.

Cuestiones relacionadas