Click here to Skip to main content
Click here to Skip to main content

DailyRollingFileAppender with maxBackupIndex

By , 15 May 2010
Rate this:
Please Sign up or sign in to vote.

Introduction

If you are trying to use the Apache Log4J DailyRollingFileAppender for a daily log file, you may need to want to specify the maximum number of files which should be kept. Just like rolling RollingFileAppender supports maxBackupIndex. But the current version of Log4j (Apache log4j 1.2.16) does not provide any mechanism to delete old log files if you are using DailyRollingFileAppender. I tried to make small modifications in the original version of DailyRollingFileAppender to add maxBackupIndex property. So, it would be possible to clean up old log files which may not be required for future usage.

Changes Made in the DailyRollingFileAppender

Step 1: Renamed the Java file DailyRollingFileAppender to CustomDailyRollingFileAppender and put it into a different package, which is custom.log4j.appender.

Step 2: Added a new field variable protected int maxBackupIndex = 1; and set the default value as one. This is required because based on the value of maxBackupIndex our appender determines the number of files needed to keep backup.

Step 3: Created a mutator (setter method) and an accessor (getter method) for the filed maxBackupIndex.

public int getMaxBackupIndex() {
	return maxBackupIndex;
}

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

Step 4: Created a class within the same Java source file ModifiedTimeSortableFile. This class extends java.io.File class and implements java.lang.Comparable<T> to sort files list based upon their modified date. The main purpose behind creating this class is to override public int compareTo(File anotherPathName) method which is used later to call Collections.sort() method to sort the files in the oldest modified date order.

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));
	}
}

Step 5: Once the class ModifiedTimeSortableFile has been created, now we can move on to add new method private List<ModifiedTimeSortableFile> getAllFiles() to our modified class CustomDailyRollingFileAppender. The purpose of this method is to fetch a list of log files based on the pattern given in the log4j configuration file and return as a list.

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;
   } 

Step 6: The void rollOver() throws IOException is responsible to rollover the current file to a new file. We just need to put additional logic before anything it does to rollover. Our logic simply gets the list of files, sorts those according to modified date, checks the maxBackupIndex and deletes additional old log files.

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++;
   }
} 

How To Use

We have created our CustomDailyRollingFileAppender. Now, it's time to test our appender. There are only two steps involved to create a sample application as described below:

Step 1: Create a log4J configuration file to set the datePattern, maxBackupSize, etc.

<?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>

Here you can see the class name mentioned is the one which we have just created (i.e. CustomDailyRollingFileAppender). And we set the maxBackupIndex as 4. Hence, there should be only four log files that shall be kept on your system.

Step 2: Create a class with public static void main(String[] args) method and add latest log4J jar file at your 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");
   } 

Now we are ready to test whether our appender is working fine or not. Just change your system date to observe files are backed up as per maxBackupIndex or not.

Conclusion

This is a modified version of DailyRollingFileAppender and all the comments and license in the source file have been kept untouched. I added my comment though. It is only tested on Windows Operating System. Please make your necessary adjustments in the code if required. The purpose of this article is to demonstrate how to create your own custom appenders.

History

  • 16th May, 2010: Initial post

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Bikash Shaw
Software Developer (Senior) Société Générale
India India
Summary:
 
1. Extensive working experience in web and windows application development, database programming using Java and .Net technologies.
 
2. Good knowledge in SDLC and Processes like project planning, requirement gathering, development, test planning, release management and production support.
 
3. Good knowledge and working experience in following methodologies:
a. Agile Development Approach
b. Test Driven Development
c. Behavior Driven Development
d. Continuous Integration & Delivery Model.
 
4. Excellent communication & analytical skills, good team player, great mentoring capability.
 
5. Interaction with customer and team spread over different geographical area.
 
Technologies / Languages: J2SE 5/6, J2EE, .Net 2.0/3.5, C#, ASP.NET, AJAX, XHTML, CSS, JavaScript, jQuery, PL/SQL, Web Services (SOAP based), Winforms, Hibernate, Spring, GWT, XML, XSD, XPath, SAX, JAXB, JUnit, JBehave, Mockito, Selenium, StringTemplate, Log4J, Apache Commons API
 
Database: Oracle, SQL Server, MySQL, Sybase
 
Application Server: Tomcat, Sun Application Server, JBoss, GlassFish, Jetty, IIS
 
Development Environments: Eclipse, NetBeans, Visual Studio.
 
Designing Tools: Enterprise Architect, Microsoft Visio
 
Version Control: SVN, Perforce
 
Build Management: Hudson & JCruisemonitor, TeamCity
 
Bug Tracking Tools: HP Quality Center, Bugzilla, JIRA
 
Specialties:
1. Agile Test and Behavior Driven Development
2. Continuous Delivery Approach
2. Spring IOC and MVC
3. Web Services
Follow on   Twitter

Comments and Discussions

 
Questionsynchronization issues Pinmemberborta_galen6-Jun-12 23:24 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.140415.2 | Last Updated 16 May 2010
Article Copyright 2010 by Bikash Shaw
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid