Friday, May 18, 2007

Reduce logger initialization code in your Java applications

You might have logger initialization code in most of the classes in an application (e.g. Action, Service and DAO classes). This is actually unnecessary if these types of classes extend from your own base classes.

An application using log4j logging framework will initialize the logger in a class as

private static final Logger logger = Logger.getInstance(TestAction.getClass());

This is done in each and every class which needs to use a logger. Now if we use a base class for lets say all Struts Actions called BaseAction, it can contain the logger initialization code as below.

package com.test.web;

import org.apache.log4j.Logger;
import org.apache.struts.action.Action;

public abstract class BaseAction extends Action{
//initializes the logger object
protected final Logger logger = Logger.getInstance(this.getClass());
}


Now all sub classes that extends from BaseAction (implementation action classes) will have the logger object created on initialization with the proper class name. Even though in theory this creates a new logger object per instance of TestAction class, it wont be an issue since Struts will maintain only a single instance of TestAction to serve all requests mapped to it.

This could be applied to all Service, DAO classes as well if you are using a framework like Spring to manage them, where only one instance per implementation class will be created.

P.S. This post was modified as per comments by fabien...

Don' forget to click the +1 button below if this post was helpful.

4 comments:

Jay said...

rather than a per instance Logger, why not use one per class?

ie: private static final Logger logger = Logger.getInstance(TestAction.class);

Fabien said...

Looks like bad coding practice to me:
- you use inheritance for fields, this is most of the time a mistake. Your field should be at least final.
- you create one freaking Logger instance per object! This is very inefficient.

What's missing in Java to make Logger declaration nice is class fields like they have in Python.

More info on ways to declare your Logger at http://chasethedevil.blogspot.com/2006/12/declaring-your-logger-no-problem.html

Master of Nothing said...

Hi fabien,

I totally agree with your comments.

- Yes I should have declared the field as final.

- You are right about the inefficiency of creating an instance of logger per object, but Struts will maintain a single instance of a given Action class (only one object of type TestAction will be created). Therefore there is no performance hit on having a logger instance per object. The same applies to Service and DAO classes as I'm using Spring to manage them which I forgot to mention (my bad). Again Spring will maintain a single instance for each Service and DAO class during the life cycle of the app.

I guess the above point answers Jay's question too.

Anonymous said...

Doesn't log4j guarantee only one logger per class? That is, as long as one always specifies the same class for a logger, log4j always returns the same one.

The javadocs for Logger.getLogger(class) says
If the named logger already exists, then the existing instance will be returned. Otherwise, a new instance is created.