1
votes

Logging in my application works fine with log4j library 1.1.4 and slf4j-api 1.7.25.

But after updating log4j library from version 1.1.4 to 1.1.5 (or higher), log files simply stop being created with no exception or warning produced. Even version 1.1.5 is fairly old, so I'd rather use an even more recent version. Something must have changed in how configuration works, but I can't find out what.

This simple code will create rolling log files in log4j 1.1.4, but produces no log files with more recent versions. What is missing?

Maven dependencies are:

    <dependencies>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.25</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.4</version>
        </dependency>
    </dependencies>

Code:

package com.scratch.mylogtest;

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.rolling.*;
import static java.nio.charset.StandardCharsets.UTF_8;

/**
 * A test of log file configuration and roll-over. It should simply create a log file then write enough data to it to cause the
 * file to roll-over to a new log file.
 */
public class LogbackTest1 {

  public static void main(String[] args) {
    final String LOG_LAYOUT = "%-5level \\(%logger{0}\\) [%date]: %m%n";

    final org.slf4j.Logger rootLogger = org.slf4j.LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
    rootLogger.info("Test of root logger prior to initialization");

    ((ch.qos.logback.classic.Logger) rootLogger).setLevel(ch.qos.logback.classic.Level.DEBUG);

    //set up the logging
    SLF4JBridgeHandler.removeHandlersForRootLogger(); //remove normal JUL logging...
    SLF4JBridgeHandler.install(); //...and route JUL logging to SLF4J

    LoggerContext loggerContext = ((ch.qos.logback.classic.Logger) rootLogger).getLoggerContext();

    //appender
    RollingFileAppender rollingFileAppender = new RollingFileAppender();
    rollingFileAppender.setContext(loggerContext);
    rollingFileAppender.setFile("C:\\ProgramData\\LogTest\\log-test.log");

    //encoder
    PatternLayoutEncoder patternLayoutEncoder = new PatternLayoutEncoder();
    patternLayoutEncoder.setContext(loggerContext);
    patternLayoutEncoder.setCharset(UTF_8);
    patternLayoutEncoder.setPattern(LOG_LAYOUT);
    patternLayoutEncoder.start();

    //rolling policy
    FixedWindowRollingPolicy fixedWindowRollingPolicy = new FixedWindowRollingPolicy();
    fixedWindowRollingPolicy.setContext(loggerContext);
    fixedWindowRollingPolicy.setParent(rollingFileAppender);
    fixedWindowRollingPolicy.setFileNamePattern("C:\\ProgramData\\LogTest\\log-test.log.%i");
    fixedWindowRollingPolicy.setMaxIndex(3);
    fixedWindowRollingPolicy.start();

    //triggering policy
    SizeBasedTriggeringPolicy triggeringPolicy = new SizeBasedTriggeringPolicy();
    triggeringPolicy.setMaxFileSize("100KB");

    //start appender
    rollingFileAppender.setEncoder(patternLayoutEncoder);
    rollingFileAppender.setRollingPolicy(fixedWindowRollingPolicy);
    rollingFileAppender.setTriggeringPolicy(triggeringPolicy);

    rollingFileAppender.start();

    //add appender
    ((ch.qos.logback.classic.Logger) rootLogger).addAppender(rollingFileAppender);

    final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(LogbackTest1.class);


    // Write some data into the logs.  Write enough data that it should cause the log file to roll-over to a new file
    logger.info("Starting");
    int logTestLines = 5000;
    for (int i = logTestLines; i > 0; i--) {
      logger.info("Log test line: " + i);
    }
    logger.info("Exiting");
  }

}
1

1 Answers

0
votes

Found the solution!

Starting in logback version 1.1.5 it is necessary to call SizeBasedTriggeringPolicy.start(). In version 1.1.3 that was not necessary.

Starting in version 1.1.9, the method to set the maximum file size also changes, so code should look like this:

SizeBasedTriggeringPolicy<ILoggingEvent> triggeringPolicy = new SizeBasedTriggeringPolicy<>();
triggeringPolicy.setMaxFileSize(FileSize.valueOf("100KB"));
triggeringPolicy.start();

I found the problem by using the debugging method

StatusPrinter.print(loggerContext);

That prints this information:

15:47:22,788 |-WARN in ch.qos.logback.core.rolling.RollingFileAppender[null] - TriggeringPolicy has not started. RollingFileAppender will not start

But if you do not use StatusPrinter, no warning will be printed.