Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I configure logback to rollover based on time or size, with an absolute max on total number of files?

Tags:

java

logback

Apologies if this is seen as a duplicate. This question is very similar but not the same. I'm interested in controlling the overall number of files (really I want to control the total size used for all logs).

I want the following from log back:

  • For the current file, roll over every 12 hours or the file hits 100MB.
  • No matter what, don't use more than 600MB of space total (I could also say this like: don't have more than 5 backup files).

The first point seems easy. I'm aware of TimeBasedRollingPolicy, and I know I can limit the per file size, but that's not enough. I need a way of limiting the total number of log files, not just the total number of time periods.

like image 797
kbyrd Avatar asked Oct 21 '22 12:10

kbyrd


1 Answers

It's been a long time and someone asked for the code so I thought I would post it as an answer. I haven't tested it but it should serve as a reasonable example.

/**
 * Extends SizeBasedTriggeringPolicy to trigger based on size or time in minutes
 *
 * Example:
 *   <triggeringPolicy class="com.foo.bar.TimeSizeBasedTriggeringPolicy">
 *       <MaxFileSize>10MB</MaxFileSize>
 *       <RolloverInMinutes>35</RolloverInMinutes>
 *   </triggeringPolicy>
 *
 * This would rollover every 35min or 10MB, whichever comes first. Because isTriggeringEvent()
 * is only called when a log line comes in, these limits will not be obeyed perfectly.
 */
public class TimeSizeBasedTriggeringPolicy<E> extends SizeBasedTriggeringPolicy<E> {
     private long MILLIS_IN_A_MINUTE = 60 * 1000;

     private long rolloverPeriod;
     private long nextRolloverTime;

     @Override
     public void start() {
         nextRolloverTime = System.currentTimeMillis() + rolloverPeriod;
         super.start();
     }

     @Override
     public boolean isTriggeringEvent(File activeFile, final E event) {
         long currentTime = System.currentTimeMillis();
         boolean isRolloverTime = super.isTriggeringEvent(activeFile, event) ||
                 currentTime >= nextRolloverTime;

         // Reset the rollover period regardless of why we're rolling over.
         if (isRolloverTime) {
             nextRolloverTime = currentTime + rolloverPeriod;
         }

         return isRolloverTime;
     }

     public long getRolloverInMinutes() {
         return rolloverPeriod / MILLIS_IN_A_MINUTE;
     }

     public void setRolloverInMinutes(long rolloverPeriodInMinutes) {
         this.rolloverPeriod = rolloverPeriodInMinutes * MILLIS_IN_A_MINUTE;
     }
 }
like image 171
kbyrd Avatar answered Oct 23 '22 02:10

kbyrd