Tutorial :Logging wrapper - log4j



Question:

I have a requirement to do a wrapper interface so that you can switch between different kind of logging mechanisms without changing the code. So I have my own info(String message) method inside a Wrapper class, like:

public void info( Object message ) { if ( isInfoEnabled() ) { logger.info( message ); } }

It works as expected except that when logging it does not show the class and line of the from where I am logging, but those from the Wrapper class. Can you please help...


Solution:1

My suggestion would be to use Simple Logging Facade for Java (SLF4J) instead of your own wrapper. From its website:

The Simple Logging Facade for Java or (SLF4J) serves as a simple facade or abstraction for various logging frameworks, e.g. java.util.logging, log4j and logback, allowing the end user to plug in the desired logging framework at deployment time.

This is a moderner and preferred1 alternative to Jakarta Commons Logging (JCL). I recommend to read this article for a detailed analysis but the short version is that SLF4J doesn't suffer from the class loader problems or memory leaks observed with JCL. The author of Commons Logging himself admits it.

In case you wonder, SLF4J has been written by Ceki Gülcü which is the author of Log4J (and now works on Logback, the successor of Log4J). So this guy know a thing or two about logging and there are some chances "his" wrapper is better than mine.

In other words, there is IMHO just no point at creating a wrapper in 2010 when a nice and good one already exists.

1 Please, don't use Spring as counter example, Spring is a bad counter example (see SPR-5327).


Solution:2

There's already a wrapper interface around various logging implementations: Apache Commons Logging. Have you tried using that instead?


Solution:3

So, to solve my specific requirement, here is it what should be done...

public class Log4jWrapper implements ILogger  

{ private Logger logger;

/**   * The name of this wrapper class   */  static final String FQCN = Log4jWrapper.class.getName();    /**   * Constructor which returns the root content   */  public Log4jWrapper()  {      logger = Logger.getRootLogger();  }    /**   * Creates a {@link Logger} object   *    * @param clazz name reference for this category to create   */  public Log4jWrapper( Class<?> clazz )  {      logger = Logger.getLogger( clazz );  }    /**   * Log an debug message   *    * @param msg the message   */  public void debug( Object msg )  {      if ( isDebugEnabled() )      {          logger.log( FQCN, Level.DEBUG, msg, null );      }  }  


Solution:4

This is how you wrap log4j. You pass log() the name of your wrapper class.

class YourLog4jWrapper {      Logger _base = Logger.getLogger(/*....*/);      private void log(Object msg) {      _base.log(YourLog4jWrapper.class.getName(), Priority.INFO, msg, null);    }    }  

Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »