2010-09-27 4 views
18

J'essaie de définir le chemin d'accès au programme de journalisation par programmation. (RollingFileAppender avec FixedWindowRollingPolicy pour être exact)Définition du chemin d'accès au programme d'ouverture de session par programme

Je fais cela parce que je veux permettre à mes utilisateurs de définir le chemin du journal dans une boîte de dialogue de préférence (Eclipse RCP)

J'ai essayé quelque chose comme ça, mais Je ne change pas le chemin du journal de ce qui est défini dans le fichier de configuration:

Logger logback_logger = (ch.qos.logback.classic.Logger)LoggerFactory 
    .getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME); 
RollingFileAppender<ILoggingEvent> rfappender = 
    (RollingFileAppender<ILoggingEvent>)logback_logger.getAppender("FILE"); 
rfappender.setFile(newFile); 
FixedWindowRollingPolicy rollingPolicy = 
    (FixedWindowRollingPolicy)rfappender.getRollingPolicy(); 
rollingPolicy.setFileNamePattern(newPattern); 

Répondre

13

Utilisation des propriétés du système et en rechargeant le fichier de configuration semble plus propre:

modifier le fichier logback.xml:

<file>${log_path:-}myfile.log</file> 
.... 
<FileNamePattern>${log_path:-}myfile.%i.log</FileNamePattern> 

Cela va régler l'emplacement par défaut dans le répertoire de travail. Ensuite, utilisez:

System.setProperty("log_path", my_log_path); 

//Reload: 
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); 
+2

L'utilisation de ContextInitializer est tout à fait incorrecte. Voir ma réponse pour l'approche correcte. – Ceki

+1

choses cool! Une chose que j'ai changé: j'utilise lc.putProperty ("log_path", my_log_path) au lieu de System.setProperty. Ça a l'air mieux puisque 0 globals utilisés. – Sasha

5

en regardant le code Logback, j'ai trouvé une solution de contournement:

rollingPolicy.stop(); 
rfappender.stop(); 
rollingPolicy.start(); 
rfappender.start(); 

Cela provoque Logback à utiliser les nouvelles définitions. Il se sent toujours comme une solution de contournement, cependant.

26

Une fois que vous configurez votre programme appender, vous devez invoquer sa méthode start(). Si l'appender a des sous-composants, appelez d'abord start() sur les sous-composants. Vous ajoutez ensuite l'appender à l'enregistreur de votre choix.

est un exemple:

import ch.qos.logback.classic.Logger; 
import ch.qos.logback.classic.encoder.PatternLayoutEncoder; 
import ch.qos.logback.core.rolling.FixedWindowRollingPolicy; 
import ch.qos.logback.core.rolling.RollingFileAppender; 
import ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy; 
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(); 

    RollingFileAppender rfAppender = new RollingFileAppender(); 
    rfAppender.setContext(loggerContext); 
    rfAppender.setFile("testFile.log"); 
    FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy(); 
    rollingPolicy.setContext(loggerContext); 
    // rolling policies need to know their parent 
    // it's one of the rare cases, where a sub-component knows about its parent 
    rollingPolicy.setParent(rfAppender); 
    rollingPolicy.setFileNamePattern("testFile.%i.log.zip"); 
    rollingPolicy.start(); 

    SizeBasedTriggeringPolicy triggeringPolicy = new ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy(); 
    triggeringPolicy.setMaxFileSize("5MB"); 
    triggeringPolicy.start(); 

    PatternLayoutEncoder encoder = new PatternLayoutEncoder(); 
    encoder.setContext(loggerContext); 
    encoder.setPattern("%-4relative [%thread] %-5level %logger{35} - %msg%n"); 
    encoder.start(); 

    rfAppender.setEncoder(encoder); 
    rfAppender.setRollingPolicy(rollingPolicy); 
    rfAppender.setTriggeringPolicy(triggeringPolicy); 

    rfAppender.start(); 

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

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

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

Le code ci-dessus est l'expression programmatique des mesures prises par le configurateur XML du logback, à savoir Joran, quand il analyse le fichier RollingFixedWindow.xml.

+4

(C'est un peu gênant d'être en désaccord avec vous sur la journalisation, mais) ce n'est pas ce que j'essaie de faire - je veux configurer mon enregistreur avec XML, et ne changer que l'emplacement par code. De cette façon, les utilisateurs avancés peuvent contrôler les propriétés de journalisation fine et les utilisateurs débutants utilisent l'interface utilisateur. Redémarrer l'appender par code fonctionne; en utilisant les propriétés du système et ContextInitializer fonctionne mieux et moins codé en dur, pourquoi est-ce incorrect? – yshalbar

+0

Cette approche est-elle toujours valide avec les versions récentes de Logback? –

+0

Le lien vers 'RollingFixedWindow.xml' est rompu –

Questions connexes