Click here to Skip to main content
15,886,362 members
Articles / Programming Languages / Java / Java SE

Daily Folder Appender

Rate me:
Please Sign up or sign in to vote.
4.54/5 (7 votes)
17 Jun 2004CPOL1 min read 52.2K   751   12  
A Log4j appender class to create daily folders
/*------------------------------------------------------------------------------
 * PACKAGE: com.freeware.log4j
 * FILE   : DailyFolderApender.java
 * CREATED: Jun 16, 2004
 * AUTHOR : Prasad P. Khandekar
 *------------------------------------------------------------------------------
 * Change Log:
 *-----------------------------------------------------------------------------*/
package com.freeware.log4j;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;

/**
 * This DailyFolderAppender class extends {@link FileAppender} to facilitate creation
 * of folders on per day basis.
 * 
 * <p>The appender computes the proper filename using the format specified in  
 * <a href="http://java.sun.com/j2se/1.3/docs/api/java/text/SimpleDateFormat.html">
 * java.text.SimpleDateFormat</a>.
 * 
 * <p>Do not use the colon ":" and backslash "\" character(s) anywhere in the 
 * <b>DatePattern</b> option.
 *
 * <p><b>Parameters:</b>
 * <ol>
 * 		<li>DatePattern - The date pattern string.</li>
 * 		<li>RootFolder  - The root folder where the daily folders will be created.</li>
 * 		<li>FileName    - The name of the file. Needed only if you want to use the fixed file name.</li>
 * </ol>
 * <br>
 * @author <a HREF="mailto:KPrasadKhan@hotmail.com">Prasad P. Khandekar</a>
 * @version 1.0
 * @since 1.0
 */
public class DailyFolderAppender extends FileAppender
{
	/**
	 * The fixed date pattern to be used if one is not specified.
	 */
	private static String DATE_PATTERN = "yyyy-MM-dd";

	/**
	 * The folder under which daily folders are created. This can be a absolute path
	 * or relative path also.
	 * e.g. JavaLogs/CPRILog or F:/LogFiles/CPRILog
	 */
	private String mstrRootFolder;

	/**
	 * Used internally and contains the name of the daily folder derived from
	 * current system date. 
	 */
	private String mstrDateFolder;

	/**
	 * Holds the user specified DatePattern,
	 */
	private String mstrDatePattern = DATE_PATTERN;

	/**
	 * Holds the user specified file name. This allows fixed file names to be used
	 * as folders are created on daily basis. If not specified then file name is
	 * set to DailyFolder name.
	 */
	private String mstrFileName;

	/**
	 * The date formatter object used for parsing the user specified DatePattern.
	 */
	private SimpleDateFormat mobjSDF;

	/**
	 * Default constructor. This is required as the appender class is dynamically
	 * loaded.
	 */
	public DailyFolderAppender()
	{
	}

	public DailyFolderAppender(Layout pobjLayout, String pstrFolder, 
								String pstrPattern, String pstrFile) throws IOException
	{
		this.mstrRootFolder = createFolder(pstrFolder);
		this.mstrFileName = pstrFile;
		this.layout = pobjLayout;
		this.mstrDatePattern = checkPattern(pstrPattern);
		this.mstrDateFolder = this.mobjSDF.format(new Date(System.currentTimeMillis()));
		createFolder(pstrFolder + "\\" + this.mstrDateFolder);

		if (pstrFile != null)
			fileName = this.mstrRootFolder + "\\" + this.mstrDateFolder + 
						"\\" + pstrFile;
		else
			fileName = this.mstrRootFolder + "\\" + this.mstrDateFolder + 
						"\\" + this.mstrDateFolder + ".log";
		activateOptions();
	}

	/* (non-Javadoc)
	 * @see org.apache.log4j.FileAppender#activateOptions()
	 */
	public void activateOptions()
	{
		createFolder(this.mstrRootFolder + "\\" + this.mstrDateFolder);

		if (this.mstrFileName != null)
			fileName = this.mstrRootFolder + "\\" + this.mstrDateFolder + 
						"\\" + this.mstrDateFolder + ".log";
		else
			fileName = this.mstrRootFolder + "\\" + this.mstrDateFolder + 
							"\\" + this.mstrFileName;
		super.activateOptions();
	}

/*------------------------------------------------------------------------------
 * Getters
 *----------------------------------------------------------------------------*/
	public String getDatePattern()
	{
		return this.mstrDatePattern;
	}

	public String getRootFolder()
	{
		return this.mstrRootFolder;
	}

	public String getFileName()
	{
		return this.mstrFileName;
	}

/*------------------------------------------------------------------------------
 * Setters
 *----------------------------------------------------------------------------*/
	public void setDatePattern(String pstrPattern)
	{
		this.mstrDatePattern = checkPattern(pstrPattern);
		// derive the DateFolder name.
		this.mstrDateFolder = this.mobjSDF.format(new Date(System.currentTimeMillis()));
	}

	public void setRootFolder(String pstrFolder)
	{
		this.mstrRootFolder = createFolder(pstrFolder);
	}

	public void setFileName(String pstrFile)
	{
		this.mstrFileName = pstrFile;
	}

/*------------------------------------------------------------------------------
 * Methods
 *----------------------------------------------------------------------------*/
	/* (non-Javadoc)
	 * @see org.apache.log4j.WriterAppender#subAppend(org.apache.log4j.spi.LoggingEvent)
	 */
	protected void subAppend(LoggingEvent pobjEvent)
	{
		Date   dtNow;
		String strFolder;

		dtNow = new Date(System.currentTimeMillis());
		strFolder = this.mobjSDF.format(dtNow);
		if (!strFolder.equals(this.mstrDateFolder))
		{
			try
			{
				rollOver(strFolder);
				this.mstrDateFolder = strFolder;
			}
			catch (IOException IOEx)
			{
				LogLog.error("rollOver() failed!", IOEx);
			}
		}
		super.subAppend(pobjEvent);
	}

/*------------------------------------------------------------------------------
 * Helpers
 *----------------------------------------------------------------------------*/
	/**
	 * The helper function to vaildate the DatePattern.
	 * @param pstrPattern The DatePattern to be validated.
	 * @return The validated date pattern or defautlt DATE_PATTERN
	 */
	private String checkPattern(String pstrPattern)
	{
		String strRet = null;
		SimpleDateFormat objFmt = new SimpleDateFormat(DATE_PATTERN);

		try
		{
			this.mobjSDF = new SimpleDateFormat(pstrPattern);
			strRet = pstrPattern;
		}
		catch (NullPointerException NPExIgnore)
		{
			LogLog.error("Invalid DatePattern " + pstrPattern, NPExIgnore);
			this.mobjSDF = objFmt;
			strRet = DATE_PATTERN;
		}
		catch (IllegalArgumentException IlArgExIgnore)
		{
			LogLog.error("Invalid DatePattern " + pstrPattern, IlArgExIgnore);
			this.mobjSDF = objFmt;
			strRet = DATE_PATTERN;
		}
		finally
		{
			objFmt = null;
		}
		return strRet;
	}

	/**
	 * Helper function to create the folder(s) in a given path. 
	 * @param pstrPath The path to be used for folder creation.
	 * @return The folder path with last "\" or "/" removed.
	 */
	private String createFolder(String pstrPath)
	{
		char chrEnd;
		File objFile;

		pstrPath.trim();
		chrEnd = pstrPath.charAt(pstrPath.length() - 1);
		if (chrEnd == '\\' || chrEnd == '/')
			pstrPath = pstrPath.substring(0, (pstrPath.length() - 1));
	
		objFile = new File(pstrPath);
		// Ask file object to create all missing folders.
		objFile.mkdirs();
		objFile = null;
		return pstrPath;
	}

	/**
	 * This function is responsible for performing the actual file rollover.
	 * @param pstrName The name of the new folder based on current system date.
	 * @throws IOException
	 */
	private void rollOver(String pstrName) throws IOException
	{
		String strTemp;

		if (pstrName.equals(this.mstrDateFolder)) return;
		this.closeFile();

		createFolder(this.mstrRootFolder + "\\" + pstrName);
		if (this.mstrFileName != null)
			strTemp = this.mstrRootFolder + "\\" + pstrName + "\\" + pstrName + ".log";
		else
			strTemp = this.mstrRootFolder + "\\" + pstrName + "\\" + this.mstrFileName;
		this.setFile(strTemp, false, this.bufferedIO, this.bufferSize);
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior) Freelancer
India India
I am a software professional with over 20 years of commercial business applications design and development experience.

My programming experience includes Java, Spring, .NET, Classic VB & ASP, Scripting, Power Builder, PHP, Magic & far far ago FoxPro, C, Assembly and COBOL.

From last 11 years I am mostly working with Java Technology. I am currently available to take up new assignments.

Comments and Discussions