Logback
Clips from Logback docs with information I wanted to save for the future.
Usually I rephrase paragraphs in order to learn more and make notes concise, but in this case it’s more like a lecture rather than guide.
Appender
An Appender is a class that can be seen as an output destination.
Appenders exist for many different destinations including the console, files, Syslog, TCP Sockets, JMS and many more. Users can also easily create their own Appenders as appropriate for their specific situation.
Main classes
Logback is built upon three main classes: Logger, Appender and Layout. These three types of components work together to enable developers to log messages according to message type and level, and to control at runtime how these messages are formatted and where they are reported.
The Logger class is part of the
logback-classic
module. On the other hand, the Appender and Layout interfaces are part oflogback-core
. As a general-purpose module,logback-core
has no notion of loggers.
Loggers
Loggers are named entities. Their names are case-sensitive and they follow the hierarchical naming rule.
For example, the logger namedcom.foo
is a parent of the logger namedcom.foo.Bar
. Similarly,java
is a parent ofjava.util
and an ancestor ofjava.util.Vector
.
The root logger resides at the top of the logger hierarchy. It is exceptional in that it is part of every hierarchy at its inception. Like every logger, it can be retrieved by its name, as follows:
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
If a given logger is not assigned a level, then it inherits one from its closest ancestor with an assigned level.
To ensure that all loggers can eventually inherit a level, the root logger always has an assigned level. By default, this level isDEBUG
.
In fundamental contradiction to biological parenthood, where parents always precede their children, logback loggers can be created and configured in any order. In particular, a “parent” logger will find and link to its descendants even if it is instantiated after them.
Appenders
The ability to selectively enable or disable logging requests based on their logger is only part of the picture. Logback allows logging requests to print to multiple destinations. In logback speak, an output destination is called an appender. Currently, appenders exist for the console, files, remote socket servers, to MySQL, PostgreSQL, Oracle and other databases, JMS, and remote UNIX Syslog daemons.
More than one appender can be attached to a logger.
Each enabled logging request for a given logger will be forwarded to all the appenders in that logger as well as the appenders higher in the hierarchy.
In other words, appenders are inherited additively from the logger hierarchy. For example, if a console appender is added to the root logger, then all enabled logging requests will at least print on the console.
If in addition a file appender is added to a logger, say L, then enabled logging requests for L and L’s children will print on a file and on the console*.
*It is possible to override this default behavior so that appender accumulation is no longer additive by setting the additivity flag of a logger to false.
Layout
More often than not, users wish to customize not only the output destination but also the output format. This is accomplished by associating a layout with an appender. The layout is responsible for formatting the logging request according to the user’s wishes, whereas an appender takes care of sending the formatted output to its destination.
Configuration
The very basic structure of the configuration file can be described as,
<configuration>
element, containing zero or more<appender>
elements, followed by zero or more<logger>
elements, followed by at most one<root>
element.
At this point you should have at least some understanding of level inheritance and the basic selection rule. Otherwise, and unless you are an egyptologist, logback configuration will be no more meaningful to you than are hieroglyphics.
The
<logger>
element may contain zero or more<appender-ref>
elements; each appender thus referenced is added to the named logger.
Note that unlike log4j, logback-classic does not close nor remove any previously referenced appenders when configuring a given logger.
Similarly to the
<logger>
element, the<root>
element may contain zero or more<appender-ref>
elements; each appender thus referenced is added to the root logger. Note that unlike log4j, logback-classic does not close nor remove any previously referenced appenders when configuring the root logger.
An appender is configured with the
<appender>
element, which takes two mandatory attributes name and class. The name attribute specifies the name of the appender whereas the class attribute specifies the fully qualified name of the appender class to instantiate. The<appender>
element may contain zero or one<layout>
elements, zero or more<encoder>
elements and zero or more<filter>
elements.
The
<layout>
element takes a mandatory class attribute specifying the fully qualified name of the layout class to instantiate. As with the<appender>
element,<layout>
may contain other elements corresponding to properties of the layout instance. Since it’s such a common case, if the layout class is PatternLayout, then the class attribute can be omitted as specified by default class mapping rules.
The
<encoder>
element takes a mandatory class attribute specifying the fully qualified name of the encoder class to instantiate. Since it’s such a common case, if the encoder class is PatternLayoutEncoder, then the class attribute can be omitted as specified by default class mapping rules.
The appenders are attached to the root logger by referencing them by name within an
appender-ref
element. Note that each appender has its own encoder. Encoders are usually not designed to be shared by multiple appenders. The same is true for layouts. As such, logback configuration files do not provide any syntactical means for sharing encoders or layouts.
By default, appenders are cumulative: a logger will log to the appenders attached to itself (if any) as well as all the appenders attached to its ancestors. Thus, attaching the same appender to multiple loggers will cause logging output to be duplicated:
1
2
3
4
5
6
7
<logger name="chapters.configuration">
<appender-ref ref="STDOUT" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
Appender additivity is not intended as a trap for new users. It is quite a convenient logback feature. For instance, you can configure logging such that log messages appear on the console (for all loggers in the system) while messages only from some specific set of loggers flow into a specific appender.
1
2
3
4
5
6
7
<logger name="chapters.configuration">
<appender-ref ref="FILE" />
</logger>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
Filters
In
logback-classic
, filters can be added to Appender instances. By adding one or more filters to an appender, you can filter events by arbitrary criteria, such as the contents of the log message, the contents of the MDC, the time of day or any other part of the logging event.
The
ThresholdFilter
filters events below the specified threshold. For events of level equal or above the threshold, ThresholdFilter will respond NEUTRAL when itsdecide()
method is invoked. However, events with a level below the threshold will be denied.
TurboFilter
objects all extend theTurboFilter
abstract class. Like the regular filters, they use ternary logic to return their evaluation of the logging event. Overall, they work much like the previously mentioned filters. However, there are two main differences betweenFilter
andTurboFilter
objects.TurboFilter
objects are tied to the logging context. Hence, they are called not only when a given appender is used, but each and every time a logging request is issued. Their scope is wider than appender-attached filters. More importantly, they are called before the LoggingEvent object creation.TurboFilter
objects do not require the instantiation of a logging event to filter a logging request. As such, turbo filters are intended for high performance filtering of logging events, even before the events are created.
Source
The logback manual