Search code examples
javalogback

Programmatic Logback setup and file logging issue


In a base app i have 3 dependencies :

<dependencies>
    <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>

    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.29</version>
    </dependency>

</dependencies>

My objective is to code a logger using logback. My constraint was to develop this programmatically. I created a configuration class for my logger

public class LogbackConfig {
    public static Logger getLogger(LoggerContext logCtx, String name) {
        Logger log = logCtx.getLogger(name);
        log.setAdditive(false);
        log.setLevel(Level.INFO);
        log.addAppender(getLogConsoleAppender(logCtx, getLogEncoder(logCtx)));
        log.addAppender(getLogFileAppender(logCtx, getLogEncoder(logCtx)));

        return log;
    }
    public static LoggerContext loggerContext() {
        LoggerContext logCtx = (LoggerContext) LoggerFactory.getILoggerFactory();
        PatternLayoutEncoder logEncoder = getLogEncoder(logCtx);
        ConsoleAppender<ILoggingEvent> consoleAppender = getLogConsoleAppender(logCtx, logEncoder);
        RollingFileAppender<ILoggingEvent> logFileAppender = getLogFileAppender(logCtx, logEncoder);
        SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = getTriggeringPolicy(logCtx, logFileAppender);
        FixedWindowRollingPolicy rollingPolicy = getRollingPolicy(logCtx, logFileAppender);

        return logCtx;
    }

    private static PatternLayoutEncoder getLogEncoder(LoggerContext loggerContext) {
        PatternLayoutEncoder logEncoder = new PatternLayoutEncoder();
        logEncoder.setContext(loggerContext);
        logEncoder.setPattern("%d{yyyy/MM/dd HH:mm:ss.SSS} | %-5logger{100} |  %-5level | %C.%M\\(%F:%L\\) | %msg %n");
        logEncoder.start();
        return logEncoder;
    }
    private static ConsoleAppender<ILoggingEvent> getLogConsoleAppender(LoggerContext loggerContext, PatternLayoutEncoder logEncoder) {
        ConsoleAppender<ILoggingEvent> logConsoleAppender = new ConsoleAppender<>();
        logConsoleAppender.setContext(loggerContext);
        logConsoleAppender.setName("console");
        logConsoleAppender.setEncoder(logEncoder);
        logConsoleAppender.start();

        return logConsoleAppender;
    }
    private static RollingFileAppender<ILoggingEvent> getLogFileAppender(LoggerContext loggerContext, PatternLayoutEncoder logEncoder) {
        RollingFileAppender<ILoggingEvent> logFileAppender = new RollingFileAppender<ILoggingEvent>();
        logFileAppender.setContext(loggerContext);
        logFileAppender.setName("logFile");
        logFileAppender.setEncoder(logEncoder);
        logFileAppender.setAppend(true);
        logFileAppender.setFile("logs/logfile.log");
        return logFileAppender;
    }
    private static SizeBasedTriggeringPolicy<ILoggingEvent> getTriggeringPolicy(LoggerContext loggerContext, RollingFileAppender<ILoggingEvent> logFileAppender) {
        SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
        triggeringPolicy.setContext(loggerContext);
        triggeringPolicy.setMaxFileSize(FileSize.valueOf("1MB"));
        triggeringPolicy.start();
        logFileAppender.setTriggeringPolicy(triggeringPolicy);

        return triggeringPolicy;
    }

    private static FixedWindowRollingPolicy getRollingPolicy(LoggerContext loggerContext, RollingFileAppender<ILoggingEvent> logFileAppender) {
        FixedWindowRollingPolicy rollingPolicy = new FixedWindowRollingPolicy();
        rollingPolicy.setContext(loggerContext);
        rollingPolicy.setParent(logFileAppender);
        rollingPolicy.setMinIndex(1);
        rollingPolicy.setMaxIndex(3);
        String rollingName = "logs/log_%i.log";
        rollingPolicy.setFileNamePattern(rollingName);
        logFileAppender.setRollingPolicy(rollingPolicy);
        rollingPolicy.start();
        logFileAppender.start();
        return rollingPolicy;
    }
}

And i can call this class anyware for example here :

public class Main {
    public static void main(String[] args) {
        Logger log = LogbackConfig.getLogger(
                               LogbackConfig.loggerContext(), 
                               MethodHandles.lookup().lookupClass().toString());

        for(int i = 0; i < 10; i++) {
            log.warn("write in file ...");
        }
        Test test = new Test();
        test.testLog();
    }
}

my test class just log some text. My issue is that i display correctly the information on the console. I also correctly create my log file but nothing is written.


Solution

  • I finally solved this :

    public static Logger getLogger(String name) {
        LoggerContext logCtx = (LoggerContext) LoggerFactory.getILoggerFactory();
    
        PatternLayoutEncoder logEncoder = getPatternLayoutEncoder(logCtx);
        ConsoleAppender<ILoggingEvent> logConsoleAppender = getConsoleAppender(logCtx, logEncoder);
    
        // two different patterns layout
        logEncoder = new PatternLayoutEncoder();
        logEncoder.setContext(logCtx);
        logEncoder.setPattern("%d{yyyy/MM/dd HH:mm:ss.SSS} | %-5logger{100} |  %-5level | %C.%M\\(%F:%L\\) | %msg %n");
        logEncoder.start();
    
        RollingFileAppender<ILoggingEvent> logFileAppender = getRollingFileAppender(logCtx, logEncoder);
        SizeBasedTriggeringPolicy<ILoggingEvent> sizeBasedTriggeringPolicy = getSizeBasedTriggeringPolicy(logCtx);
    
        logFileAppender.setTriggeringPolicy(sizeBasedTriggeringPolicy);
    
        FixedWindowRollingPolicy logFilePolicy = getFixedWindowRollingPolicy(logCtx, logFileAppender);
        logFilePolicy.start();
        logFileAppender.start();
    
        Logger logger = logCtx.getLogger(name);
        logger.setAdditive(false);
        logger.setLevel(Level.INFO);
        logger.addAppender(logConsoleAppender);
        logger.addAppender(logFileAppender);
        return logger;
    }
    
    
    private static PatternLayoutEncoder getPatternLayoutEncoder(LoggerContext logCtx) {
        PatternLayoutEncoder logEncoder = new PatternLayoutEncoder();
        logEncoder.setContext(logCtx);
        logEncoder.setPattern("%d{yyyy/MM/dd HH:mm:ss.SSS} | %-5logger{100} |  %-5level | %C.%M\\(%F:%L\\) | %msg %n");
        logEncoder.start();
        return logEncoder;
    }
    private static ConsoleAppender<ILoggingEvent> getConsoleAppender(LoggerContext logCtx, PatternLayoutEncoder logEncoder) {
        ConsoleAppender<ILoggingEvent> logConsoleAppender = new ConsoleAppender<>();
        logConsoleAppender.setContext(logCtx);
        logConsoleAppender.setName("console");
        logConsoleAppender.setEncoder(logEncoder);
        logConsoleAppender.start();
        return logConsoleAppender;
    }
    private static RollingFileAppender<ILoggingEvent> getRollingFileAppender(LoggerContext logCtx, PatternLayoutEncoder logEncoder) {
        RollingFileAppender<ILoggingEvent> logFileAppender = new RollingFileAppender<>();
        logFileAppender.setContext(logCtx);
        logFileAppender.setName("logFile");
        logFileAppender.setEncoder(logEncoder);
        logFileAppender.setAppend(true);
        logFileAppender.setFile("logs/logfile.log");
        return logFileAppender;
    }
    private static SizeBasedTriggeringPolicy<ILoggingEvent> getSizeBasedTriggeringPolicy(LoggerContext logCtx) {
        SizeBasedTriggeringPolicy<ILoggingEvent> sizeBasedTriggeringPolicy = new SizeBasedTriggeringPolicy<>();
        sizeBasedTriggeringPolicy.setContext(logCtx);
        sizeBasedTriggeringPolicy.setMaxFileSize(FileSize.valueOf("1Mb"));
        sizeBasedTriggeringPolicy.start();
        return sizeBasedTriggeringPolicy;
    }
    
    private static FixedWindowRollingPolicy getFixedWindowRollingPolicy(LoggerContext logCtx, RollingFileAppender<ILoggingEvent> logFileAppender) {
        FixedWindowRollingPolicy logFilePolicy = new FixedWindowRollingPolicy();
        logFilePolicy.setContext(logCtx);
        logFilePolicy.setParent(logFileAppender);
        logFilePolicy.setMinIndex(1);
        logFilePolicy.setMaxIndex(3);
        String rollingName = "logs/log_%i.log";
        logFilePolicy.setFileNamePattern(rollingName);
        logFileAppender.setRollingPolicy(logFilePolicy);
        logFilePolicy.start();
        return logFilePolicy;
    }
    

    And in the main :

    public class Main {
        public static void main(String[] args) {
            Logger log = LogbackConfig.getLogger(
                            MethodHandles.lookup().lookupClass().toString());
    
            for(int i = 0; i < 10; i++) {
                log.warn("write in file ...");
            }
            Test test = new Test();
            test.testLog();
        }
    }