Wednesday, May 4th, 2011

Log4j Tutorial – Writing different log levels in different log files

Hi there! I have created a small eBook explaining about Log4j. Its completely free! But if you feel this blog/eBook helped you in someway, you could consider donating a small amount.Download the Log4j PDF (200 KB)

Recently one of my blog reader Surisetty send me a question, asking me if it is possible to write log messages of different levels (info, debug, etc) into different log files? To answer his question, yes, it is possible. We can do this by extending the FileAppender class and writing our own logic.

Below is the proof of concept code written to demonstrate this. Before that, you can download the Eclipse project file to run this code in your environment.

Download the Source code

To write different log levels in different log files

  1. Create a custom Log4j appender extending FileAppender.
  2. In that, override the append() method and check for the log level before writing a log message. Based on the level, call the setFile() method to switch between corresponding log file.
  3. Also, use MDC to store the original log file name mentioned in the log4j.properties. This is needed because setFile() changes the log file name every time you call it. So, we need to keep a track of the original file name somehow. And, we can use Log4j MDC for this.

Custom Appender: LogLevelFilterFileAppender

package com.veerasundar.log4j;
 

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

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

/**
 * This customized Log4j appender will seperate the log messages based on their
 * LEVELS and will write them' into separate files. For example, all DEBUG
 * messages will go to a file and all INFO messages will go to a different file.
 *
 * @author Veera Sundar | http://veerasundar.com
 *
 */
public class LogLevelFilterFileAppender extends FileAppender {

	private final static String DOT = ".";
	private final static String HIPHEN = "-";
	private static final String ORIG_LOG_FILE_NAME = "OrginalLogFileName";

	public LogLevelFilterFileAppender() {

	}

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

	public LogLevelFilterFileAppender(Layout layout, String fileName,
			boolean append) throws IOException {
		super(layout, fileName, append);
	}

	public LogLevelFilterFileAppender(Layout layout, String fileName)
			throws IOException {
		super(layout, fileName);
	}

	@Override
	public void activateOptions() {
		MDC.put(ORIG_LOG_FILE_NAME, fileName);
		super.activateOptions();
	}

	@Override
	public void append(LoggingEvent event) {
		try {
			setFile(appendLevelToFileName((String) MDC.get(ORIG_LOG_FILE_NAME),
					event.getLevel().toString()), fileAppend, bufferedIO,
					bufferSize);
		} catch (IOException ie) {
			errorHandler
					.error(
							"Error occured while setting file for the log level "
									+ event.getLevel(), ie,
							ErrorCode.FILE_OPEN_FAILURE);
		}
		super.append(event);
	}

	private String appendLevelToFileName(String oldLogFileName, String level) {
		if (oldLogFileName != null) {
			final File logFile = new File(oldLogFileName);
			String newFileName = "";
			final String fn = logFile.getName();
			final int dotIndex = fn.indexOf(DOT);
			if (dotIndex != -1) {
				// the file name has an extension. so, insert the level
				// between the file name and the extension
				newFileName = fn.substring(0, dotIndex) + HIPHEN + level + DOT
						+ fn.substring(dotIndex + 1);
			} else {
				// the file name has no extension. So, just append the level
				// at the end.
				newFileName = fn + HIPHEN + level;
			}
			return logFile.getParent() + File.separator + newFileName;
		}
		return null;
	}
}

log4j.properties file

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

Lets test our code

package com.veerasundar.log4j;

import org.apache.log4j.Logger;

public class Log4jDemo {

	private static final Logger logger = Logger.getLogger(Log4jDemo.class);

	public static void main(String args[]) {
		logger.debug("This is a debug message");
		logger.info("This is a information message");
		logger.warn("This is a warning message");
		logger.error("This is an error message");
		logger.fatal("This is a fatal message");
		logger.debug("This is another debug message");
		logger.info("This is another information message");
		logger.warn("This is another warning message");
		logger.error("This is another error message");
		logger.fatal("This is another fatal message");
	}
}

Download the Source code

{ 45 comments… read them below or add one }

karthick r May 5, 2011 at 2:38 pm

Log4j MDC.?

Reply

Veera May 5, 2011 at 2:59 pm

It stands for Mapped Diagnostic Context, where you can store a value which would be available for the entire thread.

More here: http://veerasundar.com/blog/2009/10/log4j-mdc-mapped-diagnostic-context-what-and-why/

Reply

elakkiya May 5, 2011 at 3:07 pm

How to receive the log files by using wowza server?

Reply

Veera May 5, 2011 at 3:11 pm

what is wowza server?

Reply

elakkiya May 5, 2011 at 3:24 pm

Can you tell me?please

Reply

elakkiya May 5, 2011 at 3:42 pm

How to create a own appender?

Reply

Veera May 5, 2011 at 3:45 pm

Just create a Java class and extend the log4j appender. And then override the functions according to your need.

You can look at the LogLevelFilterFileAppender class file given in this code as your reference. This is a custom appender extending the FileAppender.

Reply

elakkiya May 5, 2011 at 4:20 pm

Am creating a one application using log4j,how can i track the log statements ?

Reply

elakkiya May 5, 2011 at 3:10 pm

how to collect the data’s of log files ,before reaching the log files in wowza server?

Reply

elakkiya May 5, 2011 at 3:14 pm

its is a server used for streaming for live video

Reply

elakkiya May 5, 2011 at 3:20 pm

How to connect wowza with web services?

Reply

Veera May 5, 2011 at 3:26 pm

I have never worked on Wowza before. So, I may not be the right person to answer your questions. :)

Reply

elakkiya May 5, 2011 at 3:36 pm

ok, normally how to receive the log statements?

Reply

Veera May 5, 2011 at 3:46 pm

U want to send log messages to different servers? :|

May be u can have a look at this page which lists all Log4J appenders. You can use one according to your need.

http://www.allapplabs.com/log4j/log4j_appenders.htm

Reply

elakkiya May 5, 2011 at 4:22 pm

ya i want to receive the log message in different way.

Reply

elakkiya May 5, 2011 at 4:43 pm

how to receive the log message in different way?is any source code ? i want the sample code for it.

Reply

Veera May 5, 2011 at 4:53 pm

I don’t get your question! what do you mean by ‘different way’? Is it you want to change the format in which log messages are written? If so, you need to tweak the “ConversionPattern” option in your log4j.properties file according to your specific need.

Reply

elakkiya May 5, 2011 at 5:03 pm

ok how the output will print in the log statement? i want to display my output in different server.

Reply

elakkiya May 5, 2011 at 5:06 pm

i want to display the log statements in different server?is it possible?

Reply

Veera May 5, 2011 at 5:14 pm

if you want to send your log messages to a different server, try exploring the Network appenders such as SocketAppender or a JMSAppender etc.

Reply

elakkiya May 5, 2011 at 5:15 pm

ok thank you..!

Reply

elakkiya May 5, 2011 at 7:07 pm

how to run the SocketAppender?

Reply

Geoffrey May 5, 2011 at 3:24 pm

There has been no real development on Log4j in the last 4-5 years. Slf4J (created by the same guy as Log4J) is effectively Log4J 2.

Reply

Veera May 5, 2011 at 3:28 pm

yes. I have came across slf4j sometimes before.

Even though the Log4j isn’t developed further, people are still using the framework a lot. From the traffic that I get for this website, I can tell that still the Log4j usage is much high.

Reply

elakkiya May 9, 2011 at 4:34 pm

How to create web sevices in java?

Reply

elakkiya May 6, 2011 at 11:38 am

how to call the webservies from a server?

Reply

elakkiya May 7, 2011 at 10:11 am

how to create the web service in java
]

Reply

elakkiya May 17, 2011 at 11:13 am

I created a proxy classes for my web service by using
wsimport command.My web service application is in .NET,now i want to
call the web service . How can i cal the web service from my web
sever? please help me.

Reply

elakkiya May 17, 2011 at 11:13 am

I created a proxy classes for my web service by using
wsimport command.My web service application is in .NET,now i want to
call the web service . How can i cal the web service from my web
sever? please help me.

Reply

elakkiya May 17, 2011 at 11:13 am

I created a proxy classes for my web service by using
wsimport command.My web service application is in .NET,now i want to
call the web service . How can i cal the web service from my web
sever? please help me.

Reply

samatra June 30, 2011 at 4:57 pm

Hi, MDC.get(ORIG_LOG_FILE_NAME) returns null. Anyone knows why is this occours?

Reply

Veera July 1, 2011 at 10:58 am

Did you put the data in MDC at first?

Reply

Subhasis September 9, 2011 at 2:28 am

Veera..Thanks for sharing your wonderful log4j guide and code examples..

Reply

Vinay Maheshwari October 12, 2011 at 12:14 pm

Veera ! I stuck in coding to write own custom appender which will generate a XML that have all the logs details from the Jboss server logs.

Reply

Mohana priya October 18, 2011 at 3:55 pm

How to send log details by using udp appender . i have uncomment the udp appender in log4j.properties and added serverAccessUDP to root. but i Cant view the result.Where i Can Get the Result?Help Me Thanks in Advance.

Reply

Kurt October 30, 2011 at 8:29 am

Nice tutorial. Thanks for the time and effort in putting this together. Very helpful.

Reply

Adil Berikuly December 12, 2011 at 2:19 pm

Hey, mate.
Thanks a lot!

Reply

sravan kumar December 21, 2011 at 3:14 pm

Hi veera,
just share the things from basic level.so it will be useful for startes like me..

Reply

Sriram February 2, 2012 at 2:51 am

Hi Veera

Thanks for sharing the information. It works like a gem.

Reply

sunny gupta February 3, 2012 at 1:51 pm

I tried to run this appender in the JBoss web application, But it is not showing messages in the log file. Please let me know do i need to do some modification in that.

Reply

srikkanth February 7, 2012 at 6:27 pm

Hi Veera,
I am having one requirement where i need to write a particular detail for eg: while trying to download a file from a server we may download that successfully or it may fail, so if it is success then i need to write that into a file as the particular operations is success and if it is failure then i need to write it as failed. Now i need to write the usual logger operation in console and in parallel i need to write the above mentioned operation in a separate file where i need only that success and failure messages alone that should not contain any other log which were written in the console. Can u please help me out in this problem. thanks in advance please reply me ASAP.

thanks
Sri

Reply

Veera February 8, 2012 at 3:58 pm

I guess you must be having a Java class that does the downloading. You can create a new file appender , set its category to the package name of your downloader class and set the additivity option to false for that category.

This will send all the log messages generated from that package to a single log file.

Reply

srikkanth February 8, 2012 at 5:57 pm

Hi Veera,
Thank u very much for your help will try that out if it dosen’t work,because above mentioned scenario is not the exact one so i may face some issues in the future, ill be back again, .Once again thank u so much for ur time.
sri

Reply

Mark February 22, 2012 at 9:22 pm

Thanks a lot Veera, very helpful article!

But after doing this, won’t you get an empty logs.log file?

Reply

Charles Howard March 24, 2012 at 11:50 am

Hi Veera, thanks very much for this helpful website
Best wishes
Charles

Reply

Leave a Comment

{ 1 trackback }

Previous post:

Next post: