Monday, April 30, 2012

How to Programmatically Set Log File Path in Logback

This example uses SLF4J with Logback. In order to programmatically set log file path, we need to programmatically create a FileAppender and append it into our own logger (in this example it's "MY_LOGGER").
LogbackFileUtils.java
package test;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;

class LogbackFileUtils {
    
    public static final String MY_LOGGER = "MY_LOGGER";
    private static FileAppender<ILoggingEvent> fileAppender;
    private static boolean initialized = false;
    
    public static void init() {
        if (!initialized) {
            LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
            Logger myLogger = loggerContext.getLogger(MY_LOGGER);
            
            PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            encoder.setContext(loggerContext);
            encoder.setPattern("%d{HH:mm:ss.SSS} [%-5level] %msg %n");
            encoder.start();
            
            fileAppender = new FileAppender<ILoggingEvent>();
            fileAppender.setContext(loggerContext);
            fileAppender.setName("MY_FILE_LOGGER");
            fileAppender.setAppend(false);
            fileAppender.setEncoder(encoder);
            myLogger.addAppender(fileAppender);
            
            initialized = true;
        }
    }
    
    public static void start(String filePath) {
        init();
        stop();
        fileAppender.setFile(filePath);
        fileAppender.start();
    }
    
    public static void stop() {
        if (fileAppender.isStarted()) {
            fileAppender.stop();
        }
    }
}
This example hardcodes the pattern. We can improve this example by copying the pattern from "STDOUT" logger.

logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%-5level] %msg %n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
LogbackTest.java
package test;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogbackTest {

    private static Logger logger = LoggerFactory.getLogger(LogbackFileUtils.MY_LOGGER);
    
    public static void main(String[] args) {
        LogbackFileUtils.start("first.log");
        logger.info("1st file - This is an info message");
        logger.debug("1st file - This is a debug message");
        logger.error("1st file - This is an error message");
        LogbackFileUtils.stop();
        
        LogbackFileUtils.start("second.log");
        logger.info("2nd file - This is an info message");
        logger.debug("2nd file - This is a debug message");
        logger.error("2nd file - This is an error message");
        LogbackFileUtils.stop();
        
        logger.info("console only - This is an info message");
        logger.debug("console only - This is a debug message");
        logger.error("console only - This is an error message");
    }
}
We need to make sure we call the right logger (MY_LOGGER) and not anything else. There will be two files generated, first.log and second.log.

1 comment:

  1. Hi,
    I am trying to integrate logback in my jboss7.1.1 and JSF application.
    I want to know exactly what is this MY_LOGGER is.
    How it woks.

    ReplyDelete