How can I change a log file path on the fly in Logback?
In my web application user can change the place where some e-mail attachments will be saved and processed. The user can access this path and see if happened some errors after processing, so I want to create a log file in this path. To accomplish this I’ve tried use this Logback configuration:
<configuration debug="true" scan="true" scanPeriod="30 seconds">
<property scope="context" resource="com/hrgi/configuracoes/recuperadorNFe.properties" />
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{dd/MM/yyyy;HH:mm:ss} [%thread] %-5level %logger - %msg%n %ex{full}</pattern>
</encoder>
</appender>
<appender name="importador" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${recuperadorNFe.diretorioDeArmazenamento}/logs/importador.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${recuperadorNFe.diretorioDeArmazenamento}/logs/%d{yyyy/MM}/importador-%d{dd}.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>(%date{dd/MM/yyyy;HH:mm:ss} [%-5level]) -> %msg%n %nopex</pattern>
</encoder>
</appender>
<logger name="com.hrgi.nfe" level="info">
<appender-ref ref="importador" />
</logger>
<root level="info">
<appender-ref ref="console" />
</root>
</configuration>
Like you can see, my hope was restart logger context so perhaps it could see that the properties file’s content was changed and load the right values. Doesn’t work:
private void restartLogContext(){
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
loggerContext.stop();
loggerContext.start();
StatusPrinter.print(loggerContext);
}
So I’ve tried remove logger appender and create a new one. At least the log file was created in the new path, but the logging is happening in console:
private void restartLog(){
LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logbackLogger = loggerContext.getLogger("com.hrgi.nfe");
logbackLogger.detachAndStopAllAppenders();
TimeBasedRollingPolicy policy= new TimeBasedRollingPolicy();
policy.setContext(loggerContext);
policy.setFileNamePattern(modeloPopup.getConfiguracoes().getDiretorioDeArmazenamento()+"/logs/%d{yyyy/MM}/importador-%d{dd}.log");
RollingFileAppender fileAppender = new RollingFileAppender();
fileAppender.setContext(loggerContext);
fileAppender.setName("importador");
fileAppender.setFile(modeloPopup.getConfiguracoes().getDiretorioDeArmazenamento()+"/logs/importador.log");
fileAppender.setRollingPolicy(policy);
policy.setParent(fileAppender);
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
encoder.setContext(loggerContext);
encoder.setPattern("(%date{dd MMM yyyy;HH:mm:ss} [%-5level]) -> %msg%n %nopex");
encoder.start();
fileAppender.setEncoder(encoder);
fileAppender.start();
logbackLogger.addAppender(fileAppender);
StatusPrinter.print(loggerContext);
}
Could someone explain me what I’m doing wrong?
I’d just extend
ch.qos.logback.core.rolling.TimeBasedRollingPolicyand pass it toRollingFileAppender.It looks like appender can use it as a triggering and rolling policy. Just make it do
rolloverevery time configuration changes somewhere and return next file name based on your configuration.You should look at the methods
isTriggeringEvent– this makes appender rollover, androllover– this actually does a rollover, andgetNewActiveFileName.Look at (RollingFileAppender source)[http://grepcode.com/file/repo1.maven.org/maven2/ch.qos.logback/logback-core/0.9.3/ch/qos/logback/core/rolling/RollingFileAppender.java] to get the idea how to hook it up. It should be easier than struggling with configuration.