July 13, 2010

Logback or Log4j Additivity Explained

If you have come across the notion of additivity, while trying to figure out how to stop Logback or Log4j from dumping too much or too little data to the console or a file, but don't quite understand how it works, here is a quick explanation.

First, the very basics

Logback and Log4j have 3 main items that you should understand:

  1. Loggers - objects that log something
  2. Appenders - each logger has one or more. An appender is an output destination (eg. the console or a file)
  3. Layouts - each appender has a layout. A layout is the format of the stuff being logged.

Also

  • A logger can have a parent based on what name you give it (using the . notation). For example, a logger called bob is a parent of a logger called bob.stuff or bob.stuff.foo
  • The root logger is always the parent of every other logger.

So what is aditivity

When a method like log.debug() or log.info() is called on a logger X.Y.Z, it is forwarded to all appenders associated with logger X.Y.Z, as well as all appenders associated with X's parents (such as logger X.Y and logger X). The message is also forwarded to all appenders of the root logger.

For example, if the root logger has an appender for a standard console output, and you have another logger X which has a file appender, calling x.debug() on logger x, will log both to the console (the root logger's appender) and to the file (the X logger's file appender).

If the aditivity flag of logger X however is set to false, or disabled, then calling x.debug() will only log to the file. In other words disabling additivity for a logger, prevents parents of that logger from using their appenders to display the message.

Hope that makes sense.

If you are just starting out with Logback

If you're just starting out with Logback or Log4j, and don't quite understand the naming convention used by these logging frameworks for naming the loggers, keep in mind the following quote from Logback's official documentation:

"Logback makes it easy to name loggers by software component. This can be accomplished by instantiating a logger in each class, with the logger name equal to the fully qualified name of the class. This is a useful and straightforward method of defining loggers. As the log output bears the name of the generating logger, this naming strategy makes it easy to identify the origin of a log message. However, this is only one possible, albeit common, strategy for naming loggers. Logback does not restrict the possible set of loggers. As a developer, you are free to name loggers as you wish."

So hopefully now when you see the following line of code, which defines a logger in a class, you understand what it does:

//get the logger called "com.foo.SomeClassName"
private static Logger log = LoggerFactory.getLogger(SomeClassName.class);