65.9K
CodeProject 正在变化。 阅读更多。
Home

带有 maxBackupIndex 的 DailyRollingFileAppender

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (4投票s)

2010年5月16日

Apache

3分钟阅读

viewsIcon

133236

downloadIcon

1486

这是 Log4J DailyRollingFileAppender 的修改版本,带有 maxBackupIndex,如果超出给定的 maxBackupIndex 大小,则会删除旧的日志文件。

引言

如果您尝试使用 Apache Log4J 的 DailyRollingFileAppender 来记录每日日志文件,您可能需要指定应保留的最大文件数。就像 RollingFileAppender 支持 maxBackupIndex 一样。但是,当前版本的 Log4j(Apache log4j 1.2.16)没有提供任何机制来删除使用 DailyRollingFileAppender 时的旧日志文件。 我尝试在原始版本的 DailyRollingFileAppender 中进行小修改,以添加 maxBackupIndex 属性。 这样,就可以清理可能不需要用于将来使用的旧日志文件。

DailyRollingFileAppender 中所做的更改

第 1 步: 将 Java 文件 DailyRollingFileAppender 重命名为 CustomDailyRollingFileAppender,并将其放入不同的包中,即 custom.log4j.appender

第 2 步: 添加一个新的字段变量 protected int maxBackupIndex = 1;,并将默认值设置为 1。这是必需的,因为我们的 appender 基于 maxBackupIndex 的值来确定需要保留备份的文件数。

第 3 步: 为字段 maxBackupIndex 创建一个 mutator(setter 方法)和一个 accessor(getter 方法)。

public int getMaxBackupIndex() {
	return maxBackupIndex;
}

public void setMaxBackupIndex(int maxBackups) {
	this.maxBackupIndex = maxBackups;
}

第 4 步: 在同一个 Java 源文件中创建一个类 ModifiedTimeSortableFile。 该类扩展了 java.io.File 类并实现了 java.lang.Comparable<T>,以根据文件的修改日期对文件列表进行排序。 创建此类的主要目的是覆盖 public int compareTo(File anotherPathName) 方法,该方法稍后用于调用 Collections.sort() 方法以按最旧的修改日期顺序对文件进行排序。

class ModifiedTimeSortableFile extends File implements Serializable, Comparable<File>
{
	private static final long serialVersionUID = 1373373728209668895L;
	
	public ModifiedTimeSortableFile(String parent, String child) {
		super(parent, child);
	}

	public ModifiedTimeSortableFile(URI uri) {
		super(uri);
	}

	public ModifiedTimeSortableFile(File parent, String child) {
		super(parent, child);
	}	
	
	public ModifiedTimeSortableFile(String string) {
		super(string);
	}
	
	public int compareTo(File anotherPathName) {
		long thisVal = this.lastModified();
		long anotherVal = anotherPathName.lastModified();
		return (thisVal<anotherVal ? -1 : (thisVal==anotherVal ? 0 : 1));
	}
}

第 5 步: 创建了类 ModifiedTimeSortableFile 之后,现在我们可以继续向修改后的类 CustomDailyRollingFileAppender 添加新方法 private List<ModifiedTimeSortableFile> getAllFiles()。 此方法的目的是根据 log4j 配置文件中给定的模式获取日志文件列表并将其作为列表返回。

private List<ModifiedTimeSortableFile> getAllFiles()
   {
      List<ModifiedTimeSortableFile> files = new ArrayList<ModifiedTimeSortableFile>(); 
      FilenameFilter filter = new FilenameFilter() {
         public boolean accept(File dir, String name) {
            String directoryName = dir.getPath();
            LogLog.debug("directory name: " + directoryName);
            File file = new File(fileName);
            String perentDirectory = file.getParent();
            if(perentDirectory !=null)
            {
               String localFile = fileName.substring(directoryName.length());
               return name.startsWith(localFile);
            }
            return name.startsWith(fileName);
         }
      };
      File file = new File(fileName);
      String perentDirectory = file.getParent();
      if(file.exists())
      {
         if(file.getParent() == null){
            String absolutePath = file.getAbsolutePath();
            perentDirectory = absolutePath.substring(0,
				absolutePath.lastIndexOf(fileName));            
         }
      }
      File dir = new File(perentDirectory); 
      String[] names = dir.list(filter);
      
      for (int i = 0 ; i < names.length ; i++) {
         files.add(new ModifiedTimeSortableFile
		(dir + System.getProperty("file.separator") + names[i]));
         }
      return files;
   } 

第 6 步: void rollOver() throws IOException 负责将当前文件滚动到新文件。 我们只需要在滚动之前添加额外的逻辑。 我们的逻辑只是获取文件列表,根据修改日期对它们进行排序,检查 maxBackupIndex 并删除其他旧日志文件。

List<ModifiedTimeSortableFile> files = getAllFiles();
Collections.sort(files)
if(files.size() >= maxBackupIndex)
{
   int index = 0;
   int diff = files.size() - (maxBackupIndex - 1);
   for(ModifiedTimeSortableFile file : files)
   {
     if(index >= diff)
       break;
            
     file.delete();
    index++;
   }
} 

如何使用

我们已经创建了 CustomDailyRollingFileAppender。 现在,是时候测试我们的 appender 了。 创建示例应用程序只需两个步骤,如下所述

第 1 步: 创建一个 log4J 配置文件来设置 datePatternmaxBackupSize 等。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd" >
<log4j:configuration>
   <appender name="FILE" class="custom.log4j.appender.CustomDailyRollingFileAppender">
      <param name="file" value="test-agent.log" />
      <param name="datePattern" value="'_'dd-yyyy-MM'.log'" />
      <param name="maxBackupIndex" value="4" />
      <param name="append" value="true" />
      <layout class="org.apache.log4j.PatternLayout">
         <param name="ConversionPattern" value="%d [%t] %p - %m%n" />
      </layout>
   </appender>
   <root>
      <priority value="info" />
      <appender-ref ref="FILE" />
   </root>
</log4j:configuration>

在这里,您可以看到提到的类名是我们刚刚创建的类(即 CustomDailyRollingFileAppender)。 我们将 maxBackupIndex 设置为 4。 因此,您的系统上应该只保留四个日志文件。

第 2 步: 创建一个包含 public static void main(String[] args) 方法的类,并将最新的 log4J jar 文件添加到您的 classpath 中。

 public class Main {

   private static org.apache.log4j.Logger log = Logger.getLogger(Main.class);

   public static void main(String[] args) {
      String configFile;

      final File file = new File("log4j.xml");

       if (file.exists()) {
           final URL url = Main.class.getClassLoader().getResource("log4j.xml");
           configFile = url.getPath();
           PropertyConfigurator.configure("log4j.xml");
       }

      log.trace("Trace");
      log.debug("Debug");
      log.info("Info");
      log.warn("Warn");
      log.error("Error");
      log.fatal("Fatal");
   } 

现在我们准备好测试我们的 appender 是否工作正常。 只需更改您的系统日期即可观察文件是否按照 maxBackupIndex 进行备份。

结论

这是 DailyRollingFileAppender 的修改版本,源文件中的所有注释和许可证都保持不变。 我添加了我的评论。 它仅在 Windows 操作系统上进行了测试。 如果需要,请对代码进行必要的调整。 本文的目的是演示如何创建您自己的自定义 appender。

历史

  • 2010 年 5 月 16 日:初始发布
© . All rights reserved.