Java – Log4j2-RollingFile not writing when TimeBasedTriggeringPolicy enabled

javalog4j2maven

Log4j2 is having trouble reading the date in the filePattern of my RollingFile Appender. When I add a TimeBasedTriggeringPolicy and it re-configures my config file I get this error:

"ERROR Unable to inject fields into builder class for plugin type
class org.apache.logging.log4j.core.appender.RollingFileAppender,
element RollingFile. java.lang.IllegalStateException: Pattern does not
contain a date"

I have put a breakpoint in the log4j2 code and found that the reason is the frequency variable that is part of the PatternProcessor object is null. I don't know why this is null or how to set it to something other than null.

If I comment out the TimeBasedTriggeringPolicy, the appender begins to work and writes the logs to my file.

Here are the log4j dependencies in my POM:

<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-api</artifactId>
  <version>2.7</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.7</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j-impl</artifactId>
  <version>2.7</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-web</artifactId>
  <version>2.6.2</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>jcl-over-slf4j</artifactId>
  <version>1.7.7</version>
</dependency>
<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.7.7</version>
</dependency>

Here is my log4j2.xml file:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30" status="DEBUG">
    <Properties>
        <Property name="baseDir">/logs/oracle/domains/cim</Property>
    </Properties>
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%highlight{%d{DEFAULT} [%t] %-5p %c -%m%n}"/>
        </Console>
        <RollingFile name="RollingFile" fileName="${baseDir}/cim.log"
            filePattern="${baseDir}/cim-%d{yyyy-MM-dd}.log" append="true">
            <PatternLayout pattern="%d{DEFAULT} %-5p %c - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
            <DefaultRolloverStrategy max="31"/>
        </RollingFile>
    </Appenders>
  <Loggers>
    <Logger name="com.cim" level="debug" additivity="true">
        <Appender-Ref ref="RollingFile"/>
    </Logger>
    <Root level="debug" additivity="false">
        <Appender-Ref ref="Console"/>
    </Root>
  </Loggers>
</Configuration>

Here is the initial stack trace after the Error message above:

at org.apache.logging.log4j.core.appender.rolling.PatternProcessor.getNextTime(PatternProcessor.java:119)
    at org.apache.logging.log4j.core.appender.rolling.TimeBasedTriggeringPolicy.initialize(TimeBasedTriggeringPolicy.java:59)
    at org.apache.logging.log4j.core.appender.rolling.CompositeTriggeringPolicy.initialize(CompositeTriggeringPolicy.java:52)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.setTriggeringPolicy(RollingFileManager.java:216)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.updateData(RollingFileManager.java:439)
    at org.apache.logging.log4j.core.appender.AbstractManager.getManager(AbstractManager.java:119)
    at org.apache.logging.log4j.core.appender.OutputStreamManager.getManager(OutputStreamManager.java:114)
    at org.apache.logging.log4j.core.appender.rolling.RollingFileManager.getFileManager(RollingFileManager.java:128)
    at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:135)
    at org.apache.logging.log4j.core.appender.RollingFileAppender$Builder.build(RollingFileAppender.java:58)
    at org.apache.logging.log4j.core.config.plugins.util.PluginBuilder.build(PluginBuilder.java:122)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.createPluginObject(AbstractConfiguration.java:942)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:882)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.createConfiguration(AbstractConfiguration.java:874)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.doConfigure(AbstractConfiguration.java:498)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.initialize(AbstractConfiguration.java:227)
    at org.apache.logging.log4j.core.config.AbstractConfiguration.start(AbstractConfiguration.java:239)
    at org.apache.logging.log4j.core.LoggerContext.setConfiguration(LoggerContext.java:530)
    at org.apache.logging.log4j.core.LoggerContext.onChange(LoggerContext.java:653)
    at org.apache.logging.log4j.core.config.ConfiguratonFileWatcher$ReconfigurationRunnable.run(ConfiguratonFileWatcher.java:65)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Best Answer

The error message "Pattern does not contain a date" is clearly wrong, because your pattern is filePattern="${baseDir}/cim-%d{yyyy-MM-dd}.log", which does contain a date

However, there is a problem with the pattern. You did specify two triggering policies, a date-based and a size-based one.

The SizeBasedTriggeringPolicy also needs something in the filePattern, specifically %i, because when this policy triggers, it needs to rename the file to something.

With the size-based policy you usually end up with a bunch of rolled over log files like this:

app-1.log
app-2.log
app-3.log
...

The filePattern needs to contain a %i conversion pattern, to tell Log4j2 where to put the counter, or it won't be able to rename the file.