Search code examples
javalogginglog4jlogbackslf4j

MaxBackupIndex in logback


I have a java project I am using Logback as a logging framework instead of the log4j project. Logback's architecture is sufficiently generic so as to apply under different circumstances. I have this logback.xml file expecting no more than 10 log files at the same time, but Its not the case

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

    <property name="DEV_HOME" value="" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
            </Pattern>
        </layout>
    </appender>

    <appender name="FILE-AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>Calzada.log</file>
        <encoder>
            <pattern>%d{"yyyy-MM-dd HH:mm"} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover daily -->
            <fileNamePattern>ATrackAT1Handler.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <minIndex>1</minIndex>
            <maxIndex>10</maxIndex>
            <maxHistory>10</maxHistory>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10KB</maxFileSize>

            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>     
    </appender>

    <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>CalzadaError.log</file>
        <encoder>
            <pattern>%d{"yyyy-MM-dd HH:mm"} [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover daily -->
            <fileNamePattern>ATrackAT1HandlerError.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10KB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>     
    </appender>



    <logger name="com.calzada" level="debug"
        additivity="false">
        <appender-ref ref="FILE-AUDIT" />
        <appender-ref ref="STDOUT" />
    </logger>

   <root level="error">
        <appender-ref ref="FILE-ERROR" />
    </root>

</configuration> 

Solution

  • I think your configuration is mixing up Logback policies.

    In your configuration you use: TimeBasedRollingPolicy and then attempt to set minIndex and maxIndex but those configuration properties are not available on a TimeBasedRollingPolicy, instead they are properties of a FixedWindowRollingPolicy.

    See the docs for TimeBasedRollingPolicy and FixedWindowRollingPolicy.

    Here are some examples:

    • The following appender definition will cause Calzada.log to be rolled over to ATrackAT1Handler.%i.log everytime Calzada.log reaches 10KB and Logback will retain a maximum of 10 historic files i.e. ATrackAT1Handler.1.log to ATrackAT1Handler.10.log

      <appender name="FILE-AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <file>Calzada.log</file>
          <encoder>
              <pattern>%d{"yyyy-MM-dd HH:mm"} [%thread] %-5level %logger{35} - %msg%n</pattern>
          </encoder>
          <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
              <fileNamePattern>ATrackAT1Handler.%i.log</fileNamePattern>
              <minIndex>1</minIndex>
              <maxIndex>10</maxIndex>
          </rollingPolicy>
          <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
              <maxFileSize>10KB</maxFileSize>
          </triggeringPolicy>
      </appender>
      
    • The following appender definition will cause Calzada.log to be rolled over to ATrackAT1Handler.<yyy-MM-dd>.%i.log everytime Calzada.log reaches 10KB and Logback will retain a maximum of 10 days of historic log files but (and this is an important distinction) there is no cap on the number of files Logback will rollover within each day. So, you could have ATrackAT1Handler.2017-09-06.0.log to ATrackAT1Handler.2017-09-06.20.log and then the next day you could have ATrackAT1Handler.2017-09-07.0.log to ATrackAT1Handler.2017-09-07.12.log etc.

      <appender name="FILE-AUDIT" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <file>Calzada.log</file>
          <encoder>
              <pattern>%d{"yyyy-MM-dd HH:mm"} [%thread] %-5level %logger{35} - %msg%n</pattern>
          </encoder>
          <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
              <fileNamePattern>ATrackAT1Handler.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
              <maxFileSize>10KB</maxFileSize>
              <maxHistory>10</maxHistory>
          </rollingPolicy>
      </appender> 
      

    So, FixedWindowRollingPolicy allows you to control the number and size of historic files whereas TimeBasedRollingPolicy allows you to control the number of days of historic files and the size of each file. There seems to be a piece missing with TimeBasedRollingPolicy, namely, how can we limit the total size of all files across all days? To fill this gap the TimeBasedRollingPolicy provides the configuration property: totalSizeCap. From the docs:

    totalSizeCap int

    The optional totalSizeCap property controls the total size of all archive files. Oldest archives are deleted asynchronously when the total size cap is exceeded. The totalSizeCap property requires maxHistory property to be set as well. Moreover, the "max history" restriction is always applied first and the "total size cap" restriction applied second.

    So, you can either go with FixedWindowRollingPolicy and you'll limit the number of files but you won't have daily rollovers or use TimeBasedRollingPolicy to get daily rollovers and retain some control over historic log file footprint by ising totalSizeCap.