0

I know that logback.xml easily provides for rotation of my logs daily, or hourly, or weekly. How do I configure the timestamp in fileNamePattern so as to rotate my logs every half hour or 'x' minutes?

Or is there a code-level change that is required here? And if it is the case, is it threadsafe and efficient for high-performance business-level applications?

Yash Jaiswal
  • 17
  • 1
  • 7
  • just change pattern in log file [%d{yyyy-MM-dd HH:mm:ss}] - [%X{thread}] - %p %c -- %m%n you can refer https://logback.qos.ch/manual/appenders.html this link – Tejal Jun 19 '18 at 12:27
  • Can check https://stackoverflow.com/questions/48646546/configure-tomcat-log-rotation-windows/48649793#48649793 – lrathod Jun 19 '18 at 18:33

3 Answers3

2
import ch.qos.logback.core.joran.spi.NoAutoStart;
import ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy;

@NoAutoStart
public class MyTimeBasedFileNamingAndTriggeringPolicy<E> extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {
    // This is used to specify the time interval
    private Integer multiple = 1;

    @Override
    protected void computeNextCheck() {
        nextCheck = rc.getEndOfNextNthPeriod(dateInCurrentPeriod, multiple).getTime();
    }

    public Integer getMultiple() {
        return multiple;
    }

    public void setMultiple(Integer multiple) {
        if (multiple > 1) {
            this.multiple = multiple;
        }
    }
}
    <appender name="FILE-SFTP-OperationLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        
        <File>${FILE_PATH_SFTP_OperationLog}</File>
        
        <!--        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">-->
        <rollingPolicy
                class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
          
            <FileNamePattern>${FILE_PATH_SFTP_OperationLog}_%d{"yyyy-MM-dd_HH-mm", UTC}_0.zip</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="xxx.yyy.zzz.api.config.MyTimeBasedFileNamingAndTriggeringPolicy">
                <multiple>5</multiple>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--            <MaxFileSize>100MB</MaxFileSize>-->
            <!--            <totalSizeCap>1GB</totalSizeCap>-->
            <MaxHistory>90</MaxHistory>
        </rollingPolicy>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <encoder>
            <pattern>
{
    "time": "%d{yyyy-MM-dd HH:mm:ss.SSS}",
    "level": "%level",
    "thread": "%thread",
    "class": "%logger{40}",
    "message": "%message"
}%n
            </pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>
Sergey Nemchinov
  • 1,348
  • 15
  • 21
han wei
  • 41
  • 3
1

I am created TriggeringPolicy and RollingPolicy like this:

class MyTriggeringPolicy<E> extends DefaultTimeBasedFileNamingAndTriggeringPolicy<E> {
  protected int periodMinutes = 1;

  public int getPeriodMinutes() {
    return this.periodMinutes;
  }

  public void setPeriodMinutes(int minutes) {
    if (minutes > 0) {
      this.periodMinutes = minutes;
    }
  }

  private long roundTimestamp(long time) = {
    int periodTicks = periodMinutes * 60000;
    return periodTicks * (time / periodTicks);
  }

  @Override
  public void setDateInCurrentPeriod(long now) {
    dateInCurrentPeriod.setTime(roundTimestamp(now));
  }

  @Override
  public void setDateInCurrentPeriod(Date _dateInCurrentPeriod) {
    dateInCurrentPeriod = new Date(roundTimestamp(_dateInCurrentPeriod.getTime()));
  }

  @Override
  public void computeNextCheck() {
    rc.setTime(dateInCurrentPeriod);
    rc.set(Calendar.SECOND, 0);
    rc.set(Calendar.MILLISECOND, 0);
    rc.add(Calendar.MINUTE, periodMinutes);

    nextCheck = rc.getTime().getTime();
  }

  @Override
  public String toString() {
    return "MyTriggeringPolicy";
  }
}
class MyRollingPolicy<E> extends TimeBasedRollingPolicy<E> {
  private int periodMinutes;

  public int getPeriodMinutes() {
    return this.periodMinutes;
  }

  public void setPeriodMinutes(int minutes) {
    this.periodMinutes = minutes;
  }

  @Override
  public void start() {
    MyTriggeringPolicy<E> triggeringPolicy = new MyTriggeringPolicy<E>();
    triggeringPolicy.setPeriodMinutes(periodMinutes);
    setTimeBasedFileNamingAndTriggeringPolicy(triggeringPolicy);

    super.start();
  }

  @Override
  public String toString() {
    return "MyRollingPolicy";
  }
}
    <rollingPolicy class="MyRollingPolicy">
      <periodMinutes>5</periodMinutes>
      <fileNamePattern>application-%d{yyyyMMddHHmm}.log</fileNamePattern>
    </rollingPolicy>

This is rollover in 5,10,15... minutes.

e.g. 'application-201910301100.log' contains logs from 2019-10-30 11:00:00 to 2019-10-30 11:04:59.

0

You do not need to change the code. Changing the configuration file (logback.xml) is sufficient. Change the configuration of the appender to something similar to

<configuration>
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
      <!-- keep 30 days' worth of history capped at 3GB total size -->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

See https://logback.qos.ch/manual/appenders.html for more details. For example use logFile.%d{yyyy-MM-dd_HH-mm}.log
to Rollover at the beginning of every minute.

DrHopfen
  • 752
  • 3
  • 13