Monday, June 25, 2012

Logging to different log files based on condition using Log4j

There are times when you need to log the entire flow to some specific file or maybe based on some condition you need to log something specific in a specific log file.

You can achieve this using NDC or MDC. I will be using MDC

Let's get started.

Step 1: You need to write a Custom appender in which you will put the condition logic.

 public class MyRollingFileAppender extends RollingFileAppender {  
  @Override  
  public void append(LoggingEvent event) {  
  String condition = (String)event.getMDC("keyForConditionVariable");  
  fileName = fileName.substring(0, fileName.lastIndexOf('/'));  
  if(condition == null) {  
   fileName += "/default.log";  
  } else if("condition1".equals(condition)) {  
   fileName += "/condition_1.log";  
  } else if("condition2".equals(condition)) {  
   fileName += "/condition_2.log";  
  }  
  try {  
   setFile(fileName, fileAppend, bufferedIO, bufferSize);  
  } catch (IOException ioe) {  
             System.err.println("Exception while setting service log file ")  
  }  
  super.append(event);  
  }  
 }  

The fileName is the name of the log file. What we are doing is getting a value from MDC, I will explain how to put that in MDC later, which we are using for the condition, and decides on the log file based on that.

Step 2: Configuring our custom appender. Sample configuration
 <appender class="com.my.MyRollingFileAppender" name="rollingfile">  
     <param name="maxFileSize" value="10MB" />  
     <param name="maxBackupIndex" value="5" />  
     <param name="File" value="C:/mdc/default.log" />  
     <layout class="org.apache.log4j.PatternLayout">  
       <param name="ConversionPattern" value="%d %p [%c] - %m%n %X{keyForConditionVariable}" />  
     </layout>  
 </appender>  
If you want to log the value from the MDC you need to use %X option as configured above.

Step 3: The last piece. Putting the value in MDC. You need to put the value at the very start of the flow and also need to remove it at the end of the flow.
To put the value in the MDC
MDC.put("keyForConditionVariable", "condition1")

To remove the value from MDC
MDC.remove("keyForConditionVariable")
So here we are having "keyForConditionVariable" key the value of which we are using for the condition check in our custom appender. That's it to use MDC in log4j

No comments:

Post a Comment