一、业务需求
log4j的DailyRollingFileAppender只能实现指定时间周期的log文件的备份,当指定周期结束时将现在的log文件加上指定的后缀后,重新开始写下一个周期的log文件。但是我这次的业务中,日方对log文件的要求如下:
1)、每天写一个log文件,文件的后缀为yyyyMMdd
2)、只保存七天的log文件,以前的log文件删除
二、设计
DailyRollingBackupFileAppender继承FileAppender实现了主要功能,但是备份的处理委托为BackupStrategy接口。DailyRollingFileFilter实现将指定的文件搜索出来,交给BackupStrategy处理。
三、实现
DailyRollingBackupFileAppender
log4j的DailyRollingFileAppender只能实现指定时间周期的log文件的备份,当指定周期结束时将现在的log文件加上指定的后缀后,重新开始写下一个周期的log文件。但是我这次的业务中,日方对log文件的要求如下:
1)、每天写一个log文件,文件的后缀为yyyyMMdd
2)、只保存七天的log文件,以前的log文件删除
二、设计
DailyRollingBackupFileAppender继承FileAppender实现了主要功能,但是备份的处理委托为BackupStrategy接口。DailyRollingFileFilter实现将指定的文件搜索出来,交给BackupStrategy处理。
三、实现
DailyRollingBackupFileAppender
package study.log;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent; /**
* <b>サブシステム名:</b>デジタルシネマ フレームワーク共通<br>
* <b>機能名称:</b>ログ機能<br>
* <b>処理説明:</b>週に保存Appenderを定義するクラス。<br>
* <b>変更履歴:</b>2007/07/04 NTT-AT 新規<br>
* <br>
*
* @author NTT-AT
* @since 1.0.0
* @version 1.0.0 2007/07/04 初版
* <p>
*/
public class DailyRollingBackupFileAppender extends FileAppender {
public static final int TOP_OF_TROUBLE = -1;
public static final int TOP_OF_MINUTE = 0;
public static final int TOP_OF_HOUR = 1;
public static final int HALF_DAY = 2;
public static final int TOP_OF_DAY = 3;
public static final int TOP_OF_WEEK = 4;
public static final int TOP_OF_MONTH = 5;
/** バックアップ周期 */
private int backupCheckPeriod = 7;
private BackupCalendar backupCalendar = new BackupCalendar(-backupCheckPeriod);
private BackupStrategy backupStrategy = new DeleteBackupStrategy();
private String datePattern = "'.'yyyy-MM-dd";
private String scheduledFilename;
private long nextCheck = System.currentTimeMillis() - 1;
private Date now = new Date();
private SimpleDateFormat sdf;
private BackupCalendar rollingCalendar = new BackupCalendar();
private int rollingCheckPeriod = TOP_OF_TROUBLE;
private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
private File filePath = null;
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender() {
super();
}
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param layout ライアウト
* @param filename ファイル名
* @param datePattern 日時パタン
* @throws IOException ファイル異常
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender(Layout layout, String filename, String datePattern) throws IOException {
this(layout, filename, datePattern, 7, new DeleteBackupStrategy());
}
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param layout ライアウト
* @param filename ファイル名
* @param datePattern 日時パタン
* @param backupPeriod バックアップ周期
* @param backupStrategy バックアップ策略
* @throws IOException ファイル異常
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender(Layout layout,
String filename,
String datePattern,
int backupPeriod,
BackupStrategy backupStrategy) throws IOException {
super(layout, filename, true);
this.datePattern = datePattern;
activateOptions();
}
* <b>機能概要:</b> バックアップ策略を取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を取得する
* </ul>
* @return BackupStrategy バックアップ策略
*
* @since 1.0.0
* <p>
*/
public BackupStrategy getBackupStrategy() {
return backupStrategy;
}
* <b>機能概要:</b> バックアップ策略を設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を設定する
* </ul>
* @param backupStrategy バックアップ策略
*
* @since 1.0.0
* <p>
*/
public void setBackupStrategy(BackupStrategy backupStrategy) {
this.backupStrategy = backupStrategy;
}
* <b>機能概要:</b> バックアップ周期を取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を取得する
* </ul>
* @return int バックアップ周期
*
* @since 1.0.0
* <p>
*/
public int getBackupCheckPeriod() {
return backupCheckPeriod;
}
* <b>機能概要:</b> バックアップ周期を設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ周期を設定する
* </ul>
* @param backupCheckPeriod バックアップ周期
*
* @since 1.0.0
* <p>
*/
public void setBackupCheckPeriod(int backupCheckPeriod) {
this.backupCheckPeriod = backupCheckPeriod;
backupCalendar.setPeriod(-backupCheckPeriod);
}
* <b>機能概要:</b> 日付パターンを設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>日付パターンを設定する
* </ul>
* @param pattern 日付パターン
*
* @since 1.0.0
* <p>
*/
public void setDatePattern(String pattern) {
datePattern = pattern;
}
* <b>機能概要:</b> 日付パターンを取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>日付パターンを取得する
* </ul>
* @return String 日付パターン
*
* @since 1.0.0
* <p>
*/
public String getDatePattern() {
return datePattern;
}
* <b>機能概要:</b> オプッションを設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>オプッションを設定する
* </ul>
*
* @since 1.0.0
* <p>
*/
@Override
public void activateOptions() {
super.activateOptions();
if (datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rollingCalendar.setType(type);
backupCalendar.setType(type);
File file = new File(fileName);
scheduledFilename = fileName + sdf.format(new Date(file.lastModified()));
filePath = new File(file.getAbsolutePath()).getParentFile();
} else {
LogLog.error("Either File or DatePattern options are not set for appender [" + name + "].");
}
}
* <b>機能概要:</b> バックアップ/Rolling周期タイプを記録する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling周期タイプを記録する
* </ul>
* @param type バックアップ/Rolling周期タイプ
*
* @since 1.0.0
* <p>
*/
private void printPeriodicity(int type) {
switch (type) {
case TOP_OF_MINUTE:
LogLog.debug("Appender [" + name + "] to be rolled every minute.");
break;
case TOP_OF_HOUR:
LogLog.debug("Appender [" + name + "] to be rolled on top of every hour.");
break;
case HALF_DAY:
LogLog.debug("Appender [" + name + "] to be rolled at midday and midnight.");
break;
case TOP_OF_DAY:
LogLog.debug("Appender [" + name + "] to be rolled at midnight.");
break;
case TOP_OF_WEEK:
LogLog.debug("Appender [" + name + "] to be rolled at start of week.");
break;
case TOP_OF_MONTH:
LogLog.debug("Appender [" + name + "] to be rolled at start of every month.");
break;
default:
LogLog.warn("Unknown periodicity for appender [" + name + "].");
}
}
* <b>機能概要:</b> バックアップ/Rolling周期タイプを計算する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling周期タイプを計算する
* </ul>
* @return int バックアップ/Rolling周期タイプ
*
* @since 1.0.0
* <p>
*/
protected int computeCheckPeriod() {
BackupCalendar rollingCalendar = new BackupCalendar(gmtTimeZone, Locale.ENGLISH);
Date epoch = new Date(0);
if (datePattern != null) {
for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in GMT
String r0 = simpleDateFormat.format(epoch);
rollingCalendar.setType(i);
Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
String r1 = simpleDateFormat.format(next);
// logger.debug("Type = "+i+", r0 = "+r0+", r1 = "+r1);
if (r0 != null && r1 != null && !r0.equals(r1)) {
return i;
}
}
}
return TOP_OF_TROUBLE; // Deliberately head for trouble...
}
* <b>機能概要:</b> バックアップ/Rollingの処理を行う。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rollingの処理を行う
* </ul>
* @since 1.0.0
* <p>
*/
void rollOver() {
if (datePattern == null) {
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
// It is too early to roll over because we are still within the
// bounds of the current interval. Rollover will occur once the
// next interval is reached.
if (scheduledFilename.equals(datedFilename)) {
return;
}
this.closeFile();
if (target.exists()) {
target.delete();
}
boolean result = file.renameTo(target);
if (result) {
LogLog.debug(fileName + " -> " + scheduledFilename);
} else {
LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].");
}
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
} catch (IOException e) {
errorHandler.error("setFile(" + fileName + ", false) call failed.");
}
scheduledFilename = datedFilename;
now.setTime(System.currentTimeMillis());
Collection < ? > fileList = FileUtils.listFiles(filePath,
new DailyRollingFileFilter(fileName,
datePattern,
backupCheckPeriod,
sdf.format(backupCalendar.getNextCheckDate(now))),
FalseFileFilter.INSTANCE);
for (Object obj : fileList) {
try {
backupStrategy.backup((File)obj);
} catch (Exception e) {
errorHandler.error("backup(" + obj + ") call failed.");
}
}
}
* <b>機能概要:</b> ログ内容を記録する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling処理をチェックする
* <li>ログ内容を記録する
* </ul>
* @param event ログイベント
* @since 1.0.0
* <p>
*/
@Override
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
nextCheck = rollingCalendar.getNextCheckMillis(now);
rollOver();
}
super.subAppend(event);
}
* <b>サブシステム名:</b>デジタルシネマ フレームワーク共通<br>
* <b>機能名称:</b>ログ機能<br>
* <b>処理説明:</b>バックアップ/Rolling周期カレンダーを定義するクラス。<br>
* <b>変更履歴:</b>2007/07/04 NTT-AT 新規<br>
* <br>
*
* @author NTT-AT
* @since 1.0.0
* @version 1.0.0 2007/07/04 初版
* <p>
*/
class BackupCalendar extends GregorianCalendar {
private static final long serialVersionUID = 2882906031608620390L;
/** バックアップ/Rolling周期カレンダータイプ */
private int type = DailyRollingBackupFileAppender.TOP_OF_TROUBLE;
private int period = 1;
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @since 1.0.0
* <p>
*/
BackupCalendar() {
super();
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param period バックアップ/Rolling周期
* @since 1.0.0
* <p>
*/
BackupCalendar(int period) {
super();
this.period = period;
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
* @param
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.Locale;
import java.util.TimeZone; import org.apache.commons.io.FileUtils;
import org.apache.commons.io.filefilter.FalseFileFilter;
import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent; /**
* <b>サブシステム名:</b>デジタルシネマ フレームワーク共通<br>
* <b>機能名称:</b>ログ機能<br>
* <b>処理説明:</b>週に保存Appenderを定義するクラス。<br>
* <b>変更履歴:</b>2007/07/04 NTT-AT 新規<br>
* <br>
*
* @author NTT-AT
* @since 1.0.0
* @version 1.0.0 2007/07/04 初版
* <p>
*/
public class DailyRollingBackupFileAppender extends FileAppender {
/** バックアップ周期タイプル:エラー */
public static final int TOP_OF_TROUBLE = -1;
/** バックアップ周期タイプル:分 */
public static final int TOP_OF_MINUTE = 0;
/** バックアップ周期タイプル:時 */
public static final int TOP_OF_HOUR = 1;
/** バックアップ周期タイプル:半日 */
public static final int HALF_DAY = 2;
/** バックアップ周期タイプル:日 */
public static final int TOP_OF_DAY = 3;
/** バックアップ周期タイプル:週 */
public static final int TOP_OF_WEEK = 4;
/** バックアップ周期タイプル:月 */
public static final int TOP_OF_MONTH = 5;
/** バックアップ周期 */
private int backupCheckPeriod = 7;
/** バックアップカレンダー */
private BackupCalendar backupCalendar = new BackupCalendar(-backupCheckPeriod);
/** バックアップ策略 */
private BackupStrategy backupStrategy = new DeleteBackupStrategy();
/** 日付パターン:デフォールトは'.'yyyy-MM-dd */
private String datePattern = "'.'yyyy-MM-dd";
/** 新しいログファイル名 */
private String scheduledFilename;
/** Rollingチェックタイミング */
private long nextCheck = System.currentTimeMillis() - 1;
/** 現在の日時 */
private Date now = new Date();
/** 日付フォーマット */
private SimpleDateFormat sdf;
/** Rollingカレンダー */
private BackupCalendar rollingCalendar = new BackupCalendar();
/** Rollingチェック周期 */
private int rollingCheckPeriod = TOP_OF_TROUBLE;
/** タイムゾーン */
private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT");
/** ファイルパス */
private File filePath = null;
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender() {
super();
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param layout ライアウト
* @param filename ファイル名
* @param datePattern 日時パタン
* @throws IOException ファイル異常
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender(Layout layout, String filename, String datePattern) throws IOException {
this(layout, filename, datePattern, 7, new DeleteBackupStrategy());
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param layout ライアウト
* @param filename ファイル名
* @param datePattern 日時パタン
* @param backupPeriod バックアップ周期
* @param backupStrategy バックアップ策略
* @throws IOException ファイル異常
*
* @since 1.0.0
* <p>
*/
public DailyRollingBackupFileAppender(Layout layout,
String filename,
String datePattern,
int backupPeriod,
BackupStrategy backupStrategy) throws IOException {
super(layout, filename, true);
this.datePattern = datePattern;
activateOptions();
}
/**
* <b>機能概要:</b> バックアップ策略を取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を取得する
* </ul>
* @return BackupStrategy バックアップ策略
*
* @since 1.0.0
* <p>
*/
public BackupStrategy getBackupStrategy() {
return backupStrategy;
}
/**
* <b>機能概要:</b> バックアップ策略を設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を設定する
* </ul>
* @param backupStrategy バックアップ策略
*
* @since 1.0.0
* <p>
*/
public void setBackupStrategy(BackupStrategy backupStrategy) {
this.backupStrategy = backupStrategy;
}
/**
* <b>機能概要:</b> バックアップ周期を取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ策略を取得する
* </ul>
* @return int バックアップ周期
*
* @since 1.0.0
* <p>
*/
public int getBackupCheckPeriod() {
return backupCheckPeriod;
}
/**
* <b>機能概要:</b> バックアップ周期を設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ周期を設定する
* </ul>
* @param backupCheckPeriod バックアップ周期
*
* @since 1.0.0
* <p>
*/
public void setBackupCheckPeriod(int backupCheckPeriod) {
this.backupCheckPeriod = backupCheckPeriod;
backupCalendar.setPeriod(-backupCheckPeriod);
}
/**
* <b>機能概要:</b> 日付パターンを設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>日付パターンを設定する
* </ul>
* @param pattern 日付パターン
*
* @since 1.0.0
* <p>
*/
public void setDatePattern(String pattern) {
datePattern = pattern;
}
/**
* <b>機能概要:</b> 日付パターンを取得する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>日付パターンを取得する
* </ul>
* @return String 日付パターン
*
* @since 1.0.0
* <p>
*/
public String getDatePattern() {
return datePattern;
}
/**
* <b>機能概要:</b> オプッションを設定する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>オプッションを設定する
* </ul>
*
* @since 1.0.0
* <p>
*/
@Override
public void activateOptions() {
super.activateOptions();
if (datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rollingCalendar.setType(type);
backupCalendar.setType(type);
File file = new File(fileName);
scheduledFilename = fileName + sdf.format(new Date(file.lastModified()));
filePath = new File(file.getAbsolutePath()).getParentFile();
} else {
LogLog.error("Either File or DatePattern options are not set for appender [" + name + "].");
}
}
/**
* <b>機能概要:</b> バックアップ/Rolling周期タイプを記録する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling周期タイプを記録する
* </ul>
* @param type バックアップ/Rolling周期タイプ
*
* @since 1.0.0
* <p>
*/
private void printPeriodicity(int type) {
switch (type) {
case TOP_OF_MINUTE:
LogLog.debug("Appender [" + name + "] to be rolled every minute.");
break;
case TOP_OF_HOUR:
LogLog.debug("Appender [" + name + "] to be rolled on top of every hour.");
break;
case HALF_DAY:
LogLog.debug("Appender [" + name + "] to be rolled at midday and midnight.");
break;
case TOP_OF_DAY:
LogLog.debug("Appender [" + name + "] to be rolled at midnight.");
break;
case TOP_OF_WEEK:
LogLog.debug("Appender [" + name + "] to be rolled at start of week.");
break;
case TOP_OF_MONTH:
LogLog.debug("Appender [" + name + "] to be rolled at start of every month.");
break;
default:
LogLog.warn("Unknown periodicity for appender [" + name + "].");
}
}
/**
* <b>機能概要:</b> バックアップ/Rolling周期タイプを計算する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling周期タイプを計算する
* </ul>
* @return int バックアップ/Rolling周期タイプ
*
* @since 1.0.0
* <p>
*/
protected int computeCheckPeriod() {
BackupCalendar rollingCalendar = new BackupCalendar(gmtTimeZone, Locale.ENGLISH);
Date epoch = new Date(0);
if (datePattern != null) {
for (int i = TOP_OF_MINUTE; i <= TOP_OF_MONTH; i++) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat(datePattern);
simpleDateFormat.setTimeZone(gmtTimeZone); // do all date formatting in GMT
String r0 = simpleDateFormat.format(epoch);
rollingCalendar.setType(i);
Date next = new Date(rollingCalendar.getNextCheckMillis(epoch));
String r1 = simpleDateFormat.format(next);
// logger.debug("Type = "+i+", r0 = "+r0+", r1 = "+r1);
if (r0 != null && r1 != null && !r0.equals(r1)) {
return i;
}
}
}
return TOP_OF_TROUBLE; // Deliberately head for trouble...
}
/**
* <b>機能概要:</b> バックアップ/Rollingの処理を行う。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rollingの処理を行う
* </ul>
* @since 1.0.0
* <p>
*/
void rollOver() {
/* Compute filename, but only if datePattern is specified */
if (datePattern == null) {
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
String datedFilename
= fileName + sdf.format(now);// It is too early to roll over because we are still within the
// bounds of the current interval. Rollover will occur once the
// next interval is reached.
if (scheduledFilename.equals(datedFilename)) {
return;
}
// close current file, and rename it to datedFilename
this.closeFile();
File target
= new File(scheduledFilename);if (target.exists()) {
target.delete();
}
File file
= new File(fileName);boolean result = file.renameTo(target);
if (result) {
LogLog.debug(fileName + " -> " + scheduledFilename);
} else {
LogLog.error("Failed to rename [" + fileName + "] to [" + scheduledFilename + "].");
}
try {
// This will also close the file. This is OK since multiple
// close operations are safe.
this.setFile(fileName, false, this.bufferedIO, this.bufferSize);
} catch (IOException e) {
errorHandler.error("setFile(" + fileName + ", false) call failed.");
}
scheduledFilename = datedFilename;
now.setTime(System.currentTimeMillis());
Collection < ? > fileList = FileUtils.listFiles(filePath,
new DailyRollingFileFilter(fileName,
datePattern,
backupCheckPeriod,
sdf.format(backupCalendar.getNextCheckDate(now))),
FalseFileFilter.INSTANCE);
for (Object obj : fileList) {
try {
backupStrategy.backup((File)obj);
} catch (Exception e) {
errorHandler.error("backup(" + obj + ") call failed.");
}
}
}
/**
* <b>機能概要:</b> ログ内容を記録する。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>バックアップ/Rolling処理をチェックする
* <li>ログ内容を記録する
* </ul>
* @param event ログイベント
* @since 1.0.0
* <p>
*/
@Override
protected void subAppend(LoggingEvent event) {
long n = System.currentTimeMillis();
if (n >= nextCheck) {
now.setTime(n);
nextCheck = rollingCalendar.getNextCheckMillis(now);
rollOver();
}
super.subAppend(event);
}
/**
* <b>サブシステム名:</b>デジタルシネマ フレームワーク共通<br>
* <b>機能名称:</b>ログ機能<br>
* <b>処理説明:</b>バックアップ/Rolling周期カレンダーを定義するクラス。<br>
* <b>変更履歴:</b>2007/07/04 NTT-AT 新規<br>
* <br>
*
* @author NTT-AT
* @since 1.0.0
* @version 1.0.0 2007/07/04 初版
* <p>
*/
class BackupCalendar extends GregorianCalendar {
/** バージョンID */
private static final long serialVersionUID = 2882906031608620390L;
/** バックアップ/Rolling周期カレンダータイプ */
private int type = DailyRollingBackupFileAppender.TOP_OF_TROUBLE;
/** バックアップ/Rolling周期 */
private int period = 1;
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @since 1.0.0
* <p>
*/
BackupCalendar() {
super();
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
*
* @param period バックアップ/Rolling周期
* @since 1.0.0
* <p>
*/
BackupCalendar(int period) {
super();
this.period = period;
}
/**
* <b>機能概要:</b> コンストラクタ。<br>
* <br>
* <b>処理詳細:</b> <br>
* <ul>
* <li>親のコンストラクタを呼び出す
* </ul>
* @param