LogbackのFixedWindowRollingPolicyで、日時ローテートする。
Logbackの、FixedWindowRollingPolicyを使って、日時ローテートしたいときに使えるTriggeringEvent。
package com.example; import java.io.File; import java.util.Date; import ch.qos.logback.core.Context; import ch.qos.logback.core.rolling.TriggeringPolicyBase; import ch.qos.logback.core.rolling.helper.RollingCalendar; public class TimeBasedTriggeringPolicy extends TriggeringPolicyBase { public static final String TOP_OF_MONTH = "MONTH"; public static final String TOP_OF_WEEK = "WEEK"; public static final String TOP_OF_DAY = "DAY"; public static final String HALF_OF_DAY = "HALF_OF_DAY"; public static final String TOP_OF_HOUR = "HOUR"; public static final String TOP_OF_MINUTE = "MINUTE"; public static final String TOP_OF_SECOND = "SECOND"; RollingCalendar rc; long currentTime; Date lastCheck = new Date(); long nextCheck; // indicate whether the time has been forced or not boolean isTimeForced = false; private String rollingPeriod; @Override public void start() { // find out period from the filename pattern String rollingPeriodDatePattern = null; if (rollingPeriod != null) { rollingPeriodDatePattern = determinRollingPeriodPattern(this.context); } else { String msg = "The RollingPeriod option must be set before using TimeBasedTriggeringPolicy. "; addWarn(msg); throw new IllegalStateException(msg); } if (rollingPeriodDatePattern == null) { throw new IllegalStateException( "RollingPeriod [" + rollingPeriod + "] is not valid value. The valid values are " + "[MONTH, WEEK, DAY, HALF_OF_DAY, HOUR, MINUTE, SECOND]."); } rc = new RollingCalendar(); rc.init(rollingPeriodDatePattern); rc.printPeriodicity(this); // currentTime = System.currentTimeMillis(); lastCheck.setTime(getCurrentTime()); nextCheck = rc.getNextCheckMillis(lastCheck); super.start(); } private String determinRollingPeriodPattern(Context context) { String pattern = null; if (rollingPeriod.equals(TOP_OF_MONTH)) { pattern = "yyyy-MM"; } else if (rollingPeriod.equals(TOP_OF_WEEK)) { pattern = "yyyy-MM-E"; } else if (rollingPeriod.equals(TOP_OF_DAY)) { pattern = "yyyy-MM-E-dd"; } else if (rollingPeriod.equals(HALF_OF_DAY)) { pattern = "yyyy-MM-E-dd-a"; } else if (rollingPeriod.equals(TOP_OF_HOUR)) { pattern = "yyyy-MM-E-dd-a-HH"; } else if (rollingPeriod.equals(TOP_OF_MINUTE)) { pattern = "yyyy-MM-E-dd-a-HH-mm"; } else if (rollingPeriod.equals(TOP_OF_SECOND)) { pattern = "yyyy-MM-E-dd-a-HH-mm-ss"; } return pattern; } public boolean isTriggeringEvent(File activeFile, Object event) { long time = getCurrentTime(); if (time >= nextCheck) { lastCheck.setTime(time); nextCheck = rc.getNextCheckMillis(lastCheck); return true; } else { return false; } } public long getCurrentTime() { // if time is forced return the time set by user if (isTimeForced) { return currentTime; } else { return System.currentTimeMillis(); } } public void setCurrentTime(long timeInMillis) { currentTime = timeInMillis; isTimeForced = true; } public void setRollingPeriod(String rollingPeriod) { this.rollingPeriod = rollingPeriod; } }
使い方は、logback.xml内のアペンダに以下のように、triggeringPolicyを指定すればOK。
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>hoge.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <FileNamePattern>hoge.%i.log.zip</FileNamePattern> <MinIndex>1</MinIndex> <MaxIndex>3</MaxIndex> </rollingPolicy> <triggeringPolicy class="com.example.TimeBasedTriggeringPolicy"> <!-- MONTH, WEEK, DAY, HALF_OF_DAY, HOUR, MINUTE, SECOND --> <RollingPeriod>MINUTE</RollingPeriod> </triggeringPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%d{yyyy/MM/dd HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg%n</Pattern> </layout> </appender>