log4j使用DailyRollingFileAppender对日志文件按天进行归档时,可以使用datePattern指定归档文件名格式. 如日志文件名为error.log,设置datePattern=yyyyMMdd,则归档文件名为error.logyyyyMMdd.
这样的归档文件名没有统一的后缀名,看起来不是很美观.于是我想,要是能将归档文件名设置为error_yyyyMMdd.log就好了.
分析DailyRollingFileAppender的源代码,我们重点关注两个函数
public void activateOptions() {
super.activateOptions();
if(datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rc.setType(type);
File file = new File(fileName);
scheduledFilename = fileName+sdf.format(new Date(file.lastModified()));
} else {
LogLog.error("Either File or DatePattern options are not set for appender ["
+name+"].");
}
}activeOptions函数,在初始化Appender时会被调用一次,设置scheduleFilename为当前日志文件名+datePattern.
void rollOver() throws IOException {
/* 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;
}rollOver函数每隔一段时间执行,首先使用日志文件名+datePattern表示的当天时间赋值给dateFilename,再将dateFilename与scheduledFilename进行比较.如果两者相等,则表示不需要进行文件归档. 当一天结束进入下一天时,dateFilename发生变化,此时与scheduledFilename不相等,此时将当前日志文件名重置成scheduledFilename,进行归档
从上面的分析可以看出,首先设置的datePattern只能添加到原文件名的后面.如果我们想实现将error.log文件归档为error_yyyyMMdd.log需要对log4j做一下修改.
首先,修改datePattern,设置为
log4j.appender.error.datePattern='_'yyyyMMdd'.log'接下来,创建我们自己的Appender,继承DailyRollingFileAppender,重载上面两个函数
public void activateOptions() {
super.activateOptions();
if(datePattern != null && fileName != null) {
now.setTime(System.currentTimeMillis());
sdf = new SimpleDateFormat(datePattern);
int type = computeCheckPeriod();
printPeriodicity(type);
rc.setType(type);
File file = new File(fileName);
String tempFileName = fileName.substring(0, fileName.lastIndexOf("."));
scheduledFilename = tempFileName+sdf.format(new Date(file.lastModified()));
} else {
LogLog.error("Either File or DatePattern options are not set for appender ["
+name+"].");
}
}scheduledFilename会将当前文件后缀名去掉,再拼接上datePattern,当然也可以按需要自定义.
void rollOver() throws IOException {
/* Compute filename, but only if datePattern is specified */
if (datePattern == null) {
errorHandler.error("Missing DatePattern option in rollOver().");
return;
}
String tempFileName = fileName.substring(0, fileName.lastIndexOf("."));
String datedFilename = tempFileName+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;
}rollOver函数中,同样对datedFilename,也需要做同样的处理,当发生归档时,会将归档文件名设置为scheduledFilename,再将datedFilename复制给scheduledFilename,准备下一次的归档.
通过重载,我们可以完全按照我们的自定义DailyRollingFileAppender的归档文件名了
本文介绍了如何在log4j中使用DailyRollingFileAppender进行日志按天归档,并详细说明了如何通过修改datePattern属性以及重载相关方法,来实现将归档文件名格式化为`error_yyyyMMdd.log`,以提高归档文件的可读性和美观性。
272

被折叠的 条评论
为什么被折叠?



