How to combine log4j daily log rotation with filesize based rotation and maxbackup?

913 Views Asked by At

I want to configure the following things for log4j:

  • rotate logfile daily
  • max logfile size 100MB (rotate when the log reaches the limit).
  • compress daily rotated logfiles
  • only keep compressed logfiles for 7 days.
  • log should be written with a certain pattern
  • log level info

preconditions: OS is windows, log4j version 1.1.x, xml configuration format

This is what I have:

    <?xml version="1.0"?>
    <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
        <appender name="RollingAppender" class="org.apache.log4j.rolling.RollingFileAppender">
            <rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
                    <param name="ActiveFileName" value="logs/app.log"/>
            </rollingPolicy>
            
            <layout class="org.apache.log4j.EnhancedPatternLayout">
                    <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t][%c{1}:%L] %m%n" />
            </layout>
        </appender>
        
        <root>
            <priority value="INFO" />
            <appender-ref ref="RollingAppender" />
        </root>
    </log4j:configuration>
1

There are 1 best solutions below

0
On

Even if you use apache-log4j-extras (as it seems), it is not possible to obtain such a configuration out-of-the-box. What you lack is a TriggeringPolicy that causes a rollover every day: the TimeBasedRollingPolicy works correctly only if it is used as both the RollingPolicy and TriggeringPolicy. Otherwise it triggers a rollover every message.

Therefore you need to create a class like this:

public class DailyTrigerringPolicy implements TriggeringPolicy {

   private LocalDate lastDate;

   @Override
   public void activateOptions() {
      lastDate = LocalDate.now();
   }

   @Override
   public boolean isTriggeringEvent(Appender appender, LoggingEvent event, String filename, long fileLength) {
      boolean result = !lastDate.equals(LocalDate.now());
      lastDate = LocalDate.now();
      return result;
   }
}

and transform your configuration to look like this:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "https://raw.githubusercontent.com/apache/log4j/trunk/src/main/resources/org/apache/log4j/xml/log4j.dtd" >
<log4j:configuration>
  <appender name="RollingAppender" class="org.apache.log4j.rolling.RollingFileAppender">
    <param name="file" value="${catalina.base}/logs/app.log" />
    <!-- Rolls logs over and compresses the old ones -->
    <rollingPolicy class="org.apache.log4j.rolling.FixedWindowRollingPolicy">
      <param name="fileNamePattern" value="${catalina.base}/logs/app.%i.log.gz" />
      <!-- These are default values: keeps up to 7 old logs
      <param name="minIndex" value="1" />
      <param name="maxIndex" value="7" />
       -->
    </rollingPolicy>
    <!-- Triggers a rollover whenever one of its child policies does. -->
    <triggeringPolicy class="org.apache.log4j.rolling.CompositeTriggeringPolicy">
      <!-- Triggers a rollover when the file size exceeds 100 MiB -->
      <triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
        <param name="maxFileSize" value="104857600" />
      </triggeringPolicy>
      <!-- This is the class above: triggers a rollover once a day-->
      <triggeringPolicy class="com.example.DailyTrigerringPolicy" />
    </triggeringPolicy>
    <layout class="org.apache.log4j.EnhancedPatternLayout">
      <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %-5p [%t][%c{1}:%L] %m%n" />
    </layout>
  </appender>
  <root>
    <priority value="INFO" />
    <appender-ref ref="RollingAppender" />
  </root>
</log4j:configuration>

Remark: As you probably know, Log4j 1.x reached its end-of-life 6 years ago. Its successor Log4j 2.x has all the triggering policies you need (cf. documentation), if you are willing to upgrade.