How to create a new log file for each time the application runs?

by Veera on August 19, 2009

in How To,Java

Recently I got a question from my blog reader Kuruba, regarding log4j logging. Kuruba is having a batch program with Log4j logging and he wants to send the log messages to a new log file each time his batch runs. This can be achieved by extending Log4j’s FileAppender, which is used for logging to a file, and adding our own customization to the file appender. Below I’m explaining how to do it.

Extending FileAppender to create a new log file for each application run:

Here’s the pseudo code for the logic we are going to implement.

  1. Create a new Class NewLogForEachRunFileAppender (or any name as you wish), and extend it from the class org.apache.log4j.FileAppender.
  2. Override the activateOptions() function for setting the new log file name every time the logger is instantiated.
  3. For simplicity, we will append the current timestamp to each log file name. So, each time when you run the application, you will get a fresh log file.

Customized FileAppender: NewLogForEachRunFileAppender:

Here is the code for the customize FileAppender, which will create a new log file, appender with the current timestamp, for each run of the application. Please note that this code is tested in Windows environment. So, please be cautious and do a testing when running this code in Unix or other environment.

package com.veerasundar.dynamiclogger;

import java.io.File;
import java.io.IOException;

import org.apache.log4j.FileAppender;
import org.apache.log4j.Layout;
import org.apache.log4j.spi.ErrorCode;

/**
* This is a customized log4j appender, which will create a new file for every
* run of the application.
*
* @author veera | http://veerasundar.com
*
*/
public class NewLogForEachRunFileAppender extends FileAppender {

public NewLogForEachRunFileAppender() {
}

public NewLogForEachRunFileAppender(Layout layout, String filename,
		boolean append, boolean bufferedIO, int bufferSize)
		throws IOException {
	super(layout, filename, append, bufferedIO, bufferSize);
}

public NewLogForEachRunFileAppender(Layout layout, String filename,
		boolean append) throws IOException {
	super(layout, filename, append);
}

public NewLogForEachRunFileAppender(Layout layout, String filename)
		throws IOException {
	super(layout, filename);
}

public void activateOptions() {
if (fileName != null) {
	try {
		fileName = getNewLogFileName();
		setFile(fileName, fileAppend, bufferedIO, bufferSize);
	} catch (Exception e) {
		errorHandler.error("Error while activating log options", e,
				ErrorCode.FILE_OPEN_FAILURE);
	}
}
}

private String getNewLogFileName() {
if (fileName != null) {
	final String DOT = ".";
	final String HIPHEN = "-";
	final File logFile = new File(fileName);
	final String fileName = logFile.getName();
	String newFileName = "";

	final int dotIndex = fileName.indexOf(DOT);
	if (dotIndex != -1) {
		// the file name has an extension. so, insert the time stamp
		// between the file name and the extension
		newFileName = fileName.substring(0, dotIndex) + HIPHEN
				+ +System.currentTimeMillis() + DOT
				+ fileName.substring(dotIndex + 1);
	} else {
		// the file name has no extension. So, just append the timestamp
		// at the end.
		newFileName = fileName + HIPHEN + System.currentTimeMillis();
	}
	return logFile.getParent() + File.separator + newFileName;
}
return null;
}
}

log4j.properties file

Since we created a custom file appender, we need to tell the Log4j to use our custom file appender. For demo purpose, I configured this custom FileAppender as a rootLogger. So, all log messages will go to our file appender. Below is the sample log4j.properties file.

log4j.rootLogger = DEBUG, fileout
log4j.appender.fileout = com.veerasundar.dynamiclogger.NewLogForEachRunFileAppender
log4j.appender.fileout.layout.ConversionPattern = %d{ABSOLUTE} %5p %c - %m%n
log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
log4j.appender.fileout.File = D:/temp/dynamiclogger/logs.log

If you look at the property log4j.appender.fileout, our customized file appender is associated with this appender. We have also given a log file name “log.log” in the above configuration file. So, with the above configuration, when you run your application, the log files will be generated in this fashion: logs-1250696128437.log, logs-1250696142828.log.

{ 8 comments… read them below or add one }

govind August 20, 2009 at 10:49 AM

Thanks Veer,

Reply

Veera August 20, 2009 at 5:40 PM

@Govind

Welcome. I hope that I answered your question.:)

Reply

Tanzy September 10, 2009 at 10:35 AM

Hi Veera,

This is really a very useful content.
Thanks for posting it.

Well i have a query regarding this.
How about if i want to use MaxBackupIndex properties. Can we do it? if yes then how?

Thanks,
Tanzy.

Reply

Veera September 10, 2009 at 4:38 PM

@Tanzy

Yes. It’s possible but with a small code change in the above solution. We just need delete the old log files if the total number of log files reached the maxBackupIndex threshold. This is doable. Will try to post the solution for this later. :)

Reply

Robin February 2, 2010 at 3:26 PM

Thanks for making this code publicly available. It`s very useful and works straight ‘out of the box’ for me on Ubuntu.

Regards

Reply

Veera February 2, 2010 at 4:45 PM

you are welcome.

Reply

KiranB August 30, 2010 at 8:59 AM

Hi Veera,
The code works to create multiple log files each time it is called. But am using a Thread java class which calls this log fiel genrate everytime a thread starts, say for example my code is used to run 5 threads parallely and inside my process i tried calling this NewLogForEachRunFileAppender class it generates 5 different log files but writes all the logger.info into single log file inside of writing each process logger.info into its specific log files. Please let me what needs to be done?

Reply

Veera September 1, 2010 at 9:41 AM

Hi Kiran,

The above example code was made for different runs of the application, without having threads in mind. That’s why it didn’t work properly to you.

Anyway, I’ll work out a solution and will inform u soon.

Reply

Leave a Comment

Previous post:

Next post: