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)

_______________________________________________
logback-dev mailing list
logback-dev@qos.ch
http://mailman.qos.ch/mailman/listinfo/logback-dev

Reply via email to