sobota 11. února 2012

Log4j - logging into N files based on custom filter

Why ?
I was dealing with log4j and logging into N files. The main idea was to append for each thread Its own logger with different file. I realized that there are not enough information about that so I decided to write my current experience with log4j and custom filtering.

Solution
First, we start with log4j configuration file ( I prefer xml ).

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  <appender name="A"  class="org.apache.log4j.FileAppender">
          .......
          <param name="FILE" value="log/A.log" />
          <layout class="org.apache.log4j.PatternLayout">
                  <param name="ConversionPattern" value="...." />
          </layout>
          <filter class="com.log4j.example.CustomFilter">
                  <param name="appender" value="A" />
          </filter>
  </appender>
  <appender name="B"  class="org.apache.log4j.FileAppender">
          .......
          <param name="FILE" value="log/B.log" />
          <layout class="org.apache.log4j.PatternLayout">
                  <param name="ConversionPattern" value="...." />
          </layout>
          <filter class="com.log4j.example.CustomFilter">
                  <param name="appender" value="B" />
          </filter>
  </appender>
<root>
    <appender-ref ref="A"/>
    <appender-ref ref="B"/>
</root>
</log4j:configuration>
At this example there are two appenders with the same filter. If we now run our application the logger will save logs in both log files. However, we want to log some informations into a different files. We came to our CustomFilter.java to see how to deal with.
package com.log4j.example;

import org.apache.log4j.spi.Filter;
import org.apache.log4j.spi.LoggingEvent;

public class CustomFilter extends Filter {
 
 private String appender;

 public void setAppender(String appender) {
  this.appender = appender;
 }

 @Override
 public int decide(LoggingEvent event) {
  if (appender.equals(event.getThreadName())) {
   return Filter.ACCEPT;
  } else if (appender.equals(event.getThreadName())) {
   return Filter.ACCEPT;
  } else {
   return Filter.DENY;
  }
 }
}
As an indetifier I used thread name. There are more possible options It depends on your situation but this was the most suitable for me. I just need to created named thread such as "new Thread(new Runnable(),"A")".

Summarize
I hope this article was helpfull at least for a one person. Thank you for your comments...

Žádné komentáře:

Okomentovat