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.
To write different log levels in different log files
- Create a custom Log4j appender extending FileAppender.
- 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.
- 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");
}
}



{ 45 comments… read them below or add one }
Log4j MDC.?
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/
How to receive the log files by using wowza server?
what is wowza server?
Can you tell me?please
How to create a own appender?
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.
Am creating a one application using log4j,how can i track the log statements ?
how to collect the data’s of log files ,before reaching the log files in wowza server?
its is a server used for streaming for live video
How to connect wowza with web services?
I have never worked on Wowza before. So, I may not be the right person to answer your questions.
ok, normally how to receive the log statements?
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
ya i want to receive the log message in different way.
how to receive the log message in different way?is any source code ? i want the sample code for it.
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.
ok how the output will print in the log statement? i want to display my output in different server.
i want to display the log statements in different server?is it possible?
if you want to send your log messages to a different server, try exploring the Network appenders such as SocketAppender or a JMSAppender etc.
ok thank you..!
how to run the SocketAppender?
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.
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.
How to create web sevices in java?
how to call the webservies from a server?
how to create the web service in java
]
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.
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.
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.
Hi, MDC.get(ORIG_LOG_FILE_NAME) returns null. Anyone knows why is this occours?
Did you put the data in MDC at first?
Veera..Thanks for sharing your wonderful log4j guide and code examples..
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.
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.
Nice tutorial. Thanks for the time and effort in putting this together. Very helpful.
Hey, mate.
Thanks a lot!
Hi veera,
just share the things from basic level.so it will be useful for startes like me..
Hi Veera
Thanks for sharing the information. It works like a gem.
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.
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
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.
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
Thanks a lot Veera, very helpful article!
But after doing this, won’t you get an empty logs.log file?
Hi Veera, thanks very much for this helpful website
Best wishes
Charles
{ 1 trackback }