[logback-dev] [JIRA] Updates for LOGBACK-1579: Hourly rolling policy not working

QOS.CH (JIRA) noreply-jira at qos.ch
Thu Sep 30 22:43:00 CEST 2021


logback / LOGBACK-1579 [Open]
Hourly rolling policy not working

==============================

Here's what changed in this issue in the last few minutes.
This issue has been created
This issue is now assigned to you.

View or comment on issue using this link
https://jira.qos.ch/browse/LOGBACK-1579

==============================
 Issue created
------------------------------

BATICLE created this issue on 30/Sep/21 10:28 PM
Summary:              Hourly rolling policy not working
Issue Type:           Bug
Affects Versions:     1.2.3
Assignee:             Logback dev list
Components:           logback-core
Created:              30/Sep/21 10:28 PM
Environment:
  Intellij / JDK 11 / Spring Boot 2.2.4 using logback 1.2.3
  
   
  
  <appender name="TechFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
              <fileNamePattern>${LOG_DIR}/test-app.%d{yyyy-MM-dd_HH}.log</fileNamePattern>
              <maxHistory>10</maxHistory>
              <cleanHistoryOnStart>true</cleanHistoryOnStart>
          </rollingPolicy>
          <encoder>
              <pattern>%d{yyyyMMdd.HHmmss}.%p.%t.%logger{35} %-5level - %msg %n</pattern>
          </encoder>
      </appender>
Labels:               TimeBasedRollingPolicy rollingPolicy
Priority:             Major
Reporter:             BATICLE
Description:
  Hello,
  
  Figured out a bug inside class RollingCalendar in method "periodBarriersCrossed" when applying periodicityType = TOP_OF_HOUR.
  
  The "int cast" is applied to "diff" value making the resulting long value negative and not properly applying period calculation for the kind of periodicity.
  
  Fix is to delete the int cast.
  
  Workaround is creating all set of classes allowing us to override the default implementation of this RollingCalendar.
  
  <appender name="TechFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
          <rollingPolicy class="CustomTimeBasedRollingPolicy">
              <fileNamePattern>${LOG_DIR}/test-app.%d{yyyy-MM-dd_HH}.log</fileNamePattern>
              <maxHistory>10</maxHistory>
              <cleanHistoryOnStart>true</cleanHistoryOnStart>
          </rollingPolicy>
          <encoder>
              <pattern>%d{yyyyMMdd.HHmmss}.%p.%t.%logger{35} %-5level - %msg %n</pattern>
          </encoder>
      </appender>
   
  
   
  public class CustomTimeBasedRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
  
      @Override
      public void start() {
          setTimeBasedFileNamingAndTriggeringPolicy(new CustomTimeBasedFileNamingAndTriggeringPolicy<>());
          super.start();
      }
  
  }
  
  class CustomTimeBasedFileNamingAndTriggeringPolicy<E> extends TimeBasedFileNamingAndTriggeringPolicyBase<E> {
  
      private static final String COLLIDING_DATE_FORMAT_URL = CODES_URL + "#rfa_collision_in_dateFormat";
  
      private FileNamePattern fileNamePatternWithoutCompSuffix;
  
      @Override
      public void start() {
          super.start();
          if (!super.isErrorFree())
              return;
  
          final var fileNamePatternStr = tbrp.getFileNamePattern();
          final var fileNamePattern = new FileNamePattern(fileNamePatternStr, this.context);
          fileNamePatternWithoutCompSuffix = new FileNamePattern(Compressor.computeFileNameStrWithoutCompSuffix(fileNamePatternStr, tbrp.getCompressionMode()), this.context);
          DateTokenConverter<Object> dtc = fileNamePattern.getPrimaryDateTokenConverter();
          if (dtc == null) {
              throw new IllegalStateException("FileNamePattern [" + fileNamePattern.getPattern() + "] does not contain a valid DateToken");
          }
  
          if (dtc.getTimeZone() != null) {
              rc = new CustomTopOfHourRollingCalendar(dtc.getDatePattern(), dtc.getTimeZone(), Locale.getDefault());
          } else {
              rc = new CustomTopOfHourRollingCalendar(dtc.getDatePattern());
          }
          addInfo("The date pattern is '" + dtc.getDatePattern() + "' from file name pattern '" + fileNamePattern.getPattern() + "'.");
          rc.printPeriodicity(this);
  
          if (!rc.isCollisionFree()) {
              addError("The date format in FileNamePattern will result in collisions in the names of archived log files.");
              addError(CoreConstants.MORE_INFO_PREFIX + COLLIDING_DATE_FORMAT_URL);
              withErrors();
              return;
          }
          if(fileNamePattern.hasIntegerTokenCOnverter()) {
              addError("Filename pattern ["+fileNamePattern+"] contains an integer token converter, i.e. %i, INCOMPATIBLE with this configuration. Remove it.");
              return;
          }
          archiveRemover = new TimeBasedArchiveRemover(fileNamePattern, rc);
          archiveRemover.setContext(context);
          started = true;
      }
  
      @Override
      public boolean isTriggeringEvent(File activeFile, final E event) {
          long time = getCurrentTime();
          if (time >= nextCheck) {
              Date dateOfElapsedPeriod = dateInCurrentPeriod;
              addInfo("Elapsed period: " + dateOfElapsedPeriod);
              elapsedPeriodsFileName = fileNamePatternWithoutCompSuffix.convert(dateOfElapsedPeriod);
              setDateInCurrentPeriod(time);
              computeNextCheck();
              return true;
          } else {
              return false;
          }
      }
  }
  
  class CustomTopOfHourRollingCalendar extends RollingCalendar {
  
      private final PeriodicityType calculatedPeriodicityType;
  
      CustomTopOfHourRollingCalendar(String datePattern) {
          super(datePattern);
          this.calculatedPeriodicityType = computePeriodicityType();
      }
  
      CustomTopOfHourRollingCalendar(String datePattern, TimeZone tz, Locale locale) {
          super(datePattern, tz, locale);
          this.calculatedPeriodicityType = computePeriodicityType();
      }
  
      @Override
      public long periodBarriersCrossed(long start, long end) {
          if(TOP_OF_HOUR == calculatedPeriodicityType) {
              if (start > end)
                  throw new IllegalArgumentException("Start cannot come before end");
  
              long startFloored = getStartOfCurrentPeriodWithGMTOffsetCorrection(start, getTimeZone());
              long endFloored = getStartOfCurrentPeriodWithGMTOffsetCorrection(end, getTimeZone());
  
              long diff = endFloored - startFloored;
  
              return diff / MILLIS_IN_ONE_HOUR;
          }
          return super.periodBarriersCrossed(start, end);
      }
  }
   
  
   


==============================
 This message was sent by Atlassian Jira (v8.8.0#808000-sha1:e2c7e59)



More information about the logback-dev mailing list