Usage

Static vs Non-Static Loggers

As with any variable in Java, Loggers may be declared as static variables or class member variables. However,
there are a few factors to consider when choosing to delare a logger as static vs non-static. Generally, it
is better to declare Loggers as static.

Instantiation of a new Logger is a fairly expensive operation when using the default ContextSelector,
ClassLoaderContextSelector.
When the Logger is created the ClassLoaderContextSelector will locate the ClassLoader for the Class the Logger
is associated with and add the Logger to the LoggerContext associated with that ClassLoader.

Once a Logger is created it will not be deleted until the LoggerContext it is associated with
is deleted. Typically, this will only happen when the application is shut down or un-deployed. Each call
to getLogger with the same logger name will return the same Logger instance. Thus, there is very little
difference between a static or non-static Logger.

There is no behavioral difference between a static and non-static Logger. Both will have the Logger name
assigned when they are created, which usually will be the name of the class they are associated with. See
the discussion below on logger names vs class names and the example for more information.

Logging the Logger name vs the Class name

The logger name of a Logger is specified when the Logger is created. When a log method is called the
class name value in the log event will reflect the name of the class the log method was called from, which is
not necessarily the same as the class that created the Logger. The following example illustrations this.

The base class creates a static Logger and a logger variable that is initialized as that same Logger.
It has a method that performs logging, but provides access to two Loggers, one that is static and one
that can be overridden.

This class extends the base class. It provides its own logger and has three methods, one that uses the
logger in this class,one that uses the static logger from the base class, and one that where the logger
may be set to either the parent or the child.

The application exercises all the logging methods four times. The first two times the Logger in the base
class is set to the static Logger. The second two times the Logger in the base class is set to use the
Logger in the subclass. In the first and third invocation of each method a null Marker is passed. In the
second and fourth a Marker named "CLASS" is passed.

The configuration takes advantage of Log4j's ability to select a pattern based upon attributes of the log event.
In this case %C, the class name pattern, is used when the CLASS Marker is present, and %c, the logger name
is used when the CLASS marker is not present.

The output below illustrates the difference between using the Logger name and the Class name in the pattern. All
the odd numbered items print the name of the logger (%c) while all the even numbered items print the
name of the class that called the logging method (%C). The numbers in the description of the outcomes in the
following list match the corresponding numbers shown in the output.

Logging is performed in the parent class using the static logger with the Logger name pattern. The
logger name matches the name of the parent class.

Logging is performed in the parent class using the static logger with the Class name pattern. Although
the method was called against the Child instance it is implemented in Parent so that is what
appears.

Logging is performed in Child using the logger in the parent, so the name of the
parent is printed as the logger name.

Logging is performed in Child using the logger in the parent. Since the method calling the logging
method is in Child that is the class name that appears.

Logging is performed in Child using the static logger in the parent, so the name of the
parent is printed as the logger name.

Logging is performed in Child using the static logger in the parent. Since the method calling the logging
method is in Child that is the class name that appears.

Logging is performed in the parent class using the logger of Child. The
logger name matches the name of the child and so it is printed.

Logging is performed in the parent class using the logger of the Child. Although
the method was called against the Child instance it is implemented in PArent so that is what
appears as the class name.

Logging is performed in Child using the logger in the parent which is set to the child logger,
so the name of the child is printed as the logger name.

Logging is performed in Child using the logger in the parent, which is set to the child logger. Since
the method calling the logging method is in Child that is the class name that appears.

In the example above there are two Loggers declared. One is static and one is non-static. When looking at
the results it is clear that the outcomes would be exactly the same regardless of whether how the loggers
are declared. The name of the logger will always originate from the class in which it is created and the
Class name in each log event will always reflect the Class from which the logging method was called.

It should be noted that there is a substantial performance penalty for printing the location information
(class name, method name, and line number). If the method name and line number are not important it is
usually better to make sure that each class has its own Logger so the logger name accurately reflects the
class performing the logging.