Automating log4j Logger Names

By Mitch Stuart
Copyright © 2005 FullSpan Software  -  Usage subject to license
Document Version: $Revision: 1.3 $, $Date: 2005/02/11 06:07:58 $

Introduction

The log4j logging package is a popular library for logging from Java code. This article explains how to automatically follow a standardized naming convention for log4j Logger instances.

Background

With log4j, logging is done through instances of the Logger class. Each logger has a name, and the namespace is hierarchical, allowing logging to be controlled at a coarse or fine level.

A common naming convention for loggers is to use the (fully qualified) Java class name as the logger name. This is typically done by creating a static instance of a Logger in each Java file where logging is required. For example, imagine the class com.fullspan.util.MyClass. To create the Logger in MyClass.java, the MyClass class object is passed to the Logger factory as follows:

   private static final Logger LOGGER = Logger.getLogger(MyClass.class);
This creates a logger with the name "com.fullspan.util.MyClass".

This works fine. But imagine the case when you copy MyClass.java to MyOtherClass.java. You need to remember to change the getLogger invocation to use MyOtherClass.class. It would be nice to have a common logger creation pattern that is identical across all classes where it is used, so it can be copied and pasted freely into any Java file.

Automatic Naming

The following line of code can be pasted into any Java file to create a logger whose name is the name of the class that contains the line:
   private static final Logger LOGGER = Logger.getLogger(LangUtil.getInvokingClassName());
This allows you to simply replicate this line in all of your Java files, without having to change the argument to getLogger.

Invoking Class Name

Getting the invoking class name is simple in recent versions of Java. The LangUtil class, part of the FSJUtil package, defines the getInvokingClassName method. You can download or view LangUtil, but it is simple enough to just show the entire code for for the getInvokingClassName method:
   public static String getInvokingClassName()
   {
      return new Throwable().getStackTrace()[1].getClassName();
   }
I would not recommend calling getInvokingClassName in performance-sensitive code, unless you do some testing to determine its performance impact. But for creating Logger instances at class load time, performance should not be a concern.