Welcome to TheGillis.net

Consider this site a collection of random notes about a variety of topics. I hope this information helps you in some way.

21 August 2004 - 15:23Java Application Logging With Log4J

One problem that I have always faced with creating robust Java Applications has been logging the state of the program. In some cases it’s important to know about debug information, while other times it can get in the way. Even solutions that initially appear simple, can turn out to cause problems. One example is using System.out.println statements. This can cause problems when the application is no longer attached to a console such as in a Servlet. Other times having a console open with a Swing application can be difficult. Then to remove the output, it is necessary to comment out all of the print lines in a final release, taking even more time. One very good solution I’ve run across is using the Jakarta Log4J project.

Intro

The Jakarta Log4J project solves most of these problems. It not only allows you to specify logging levels, but it also allows you to specify the logging output type. It allows you to specify a configuration file that specifies what to log and where to log it to. It is also has a very light footprint, not only in the code, but during runtime with performance. It is very easy to start to use and is very expandable, allowing you to change the output format, the types of data that you can output, or even where to output the data.

Ideas

There are several concepts behind the Log4J project. Logging is broken down into Loggers. A Logger is essentially a category of logs and it usually broken down by package and class name. Loggers are hierarchical and inherit traits from the parent. Logging to the logger is specified with one of the logger levels DEBUG, INFO, WARN, ERROR, and FATAL. Simple examples of logging to a logger are:

// Usually means class foo, package com
Logger  logger = Logger.getLogger("com.foo");
logger.debug("Test debug message.");
logger.warn("Test warn message.");

This will get the logger with the specified name, usually the full name of the class, and then two messages are printed. This logger will inherit the settings from the parent (covered later). If DEBUG level output is selected, both messages will be printed, if IFNO level output is selected, only the warning will be displayed. To load the default Log4J output options, use the following line:

// Import log4j classes.
import org.apache.log4j.BasicConfigurator;
// Later in the method of a class...
// Set up a simple configuration that logs DEBUG
// or higher on the console.
BasicConfigurator.configure();

Using a property file to specify what is logged and where it’s logged to is just as easy. Here’s an example property file:

# Set root logger level to DEBUG and its only appender to A1.
log4j.rootLogger=DEBUG, A1
# A1 is set to be a ConsoleAppender.
log4j.appender.A1=org.apache.log4j.ConsoleAppender
# A1 uses PatternLayout.
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=%-4r [%t] %-5p %c %x - %m%n

… and can be loaded using…

PropertyConfigurator.configure("config.txt");

This allows for the exact logging to be specified by configuration files at runtime, and no sources need to be recompiled.

Summary

As you can see, the Log4J project allows you to get the benefit of complex logs without needing to write the complex code for each project. It keeps performance as one of it’s major architecture goals, and is still very easy to use. What I find best of all, it has been ported to C, C++, C#, Perl, Python, Ruby, and Eiffel so you can take advantage of this project for anything you happen to be writing.

Links:

No Comments | Tags: Programming

Add a Comment