Home > Articles > Programming > Java

Java Reference Guide

Hosted by

Toggle Open Guide Table of ContentsGuide Contents

Close Table of ContentsGuide Contents

Close Table of Contents

Hierarchical Logging

Last updated Mar 14, 2003.

An important distinction between manual logging and adopting a logging system is that a logging system can enable or disable logging statements external to the application itself. A powerful feature of Log4j specifically is that logging can be enabled and disabled in a hierarchical manner. Log4j defines a named hierarchy of loggers as follows (extracted from the Log4j manual):

“A logger is said to be an ancestor of another logger if its name followed by a dot is a prefix of the descendant logger name. A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.”

In other words, there is a parent/child relationship defined for loggers by their names. Traditionally we name loggers based upon the class name that is generating log messages. For example, the class com.geekcap.app1.MyApplication would have a logger defined with the name “com.geekcap.app1.MyApplication” and the class com.geekcap.app2.MyOtherApplication would have a logger defined with the name “com.geekcap.app2.MyOtherApplication.” Log4j allows the configuration of logging levels based upon a dot-based named hierarchy. This means that you can configure debug statements to be logged for the following loggers:

com.geekcap=DEBUG

The com.geekcap.app1.MyApplication and com.geekcap.app2.MyOtherApplication loggers would both inherit the “DEBUG” level because they are children of the com.geekcap logger. Furthermore, if you were to define a different configuration for app1, such as:

com.geekcap.app1=TRACE

Then all classes in the com.geekcap.app1 package, and its sub packages, would instead log trace messages. The point is that you can control what is logged and where it is logged to at a very fine granularity.

Additionally there is a root logger, named rootLogger, from which all other loggers inherit. The rootLogger defines the logging granularity and the various appenders (see the next section) for the application as a whole. So you can configure your root logger with a default configuration and then add additional logging as needed. For example, if your application is logging errors in the com.geekcap.app1.ComplicatedStuff logger, then instead of logging at an information level, you can log trace messages for just that logger. The following log4j snippet illustrates this:

log4j.rootLogger=INFO, A1
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout

log4j.appender.A1.layout.ConversionPattern=%d [%t] %-5p %c - %m%n

log4j.logger.com.geekcap.app1.ComplicatedStuff=TRACE

I discuss appenders and layouts below, but the important thing to notice here is that the root logger, from which all loggers inherit, is defined to log INFO messages, but the ComplicatedStuff logger is defined to log TRACE messages. This enables you to diagnose problematic code without negatively affecting the performance of the entire application.