Apache Log4j 2 Users Guide

log4j-users-guide

log4j-users-guide

User Manual:

Open the PDF directly: View PDF PDF.
Page Count: 285

DownloadApache Log4j 2 Log4j-users-guide
Open PDF In BrowserView PDF
......................................................................................................................................

Apache Log4j 2
v. 2.11.0
User's Guide

......................................................................................................................................
The Apache Software Foundation

2018-03-17

Table of Contents

Table of Contents

i

.......................................................................................................................................
1. Table of Contents . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . i
2. Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
1
3. Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
4. Log4j 1.x Migration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 10
5. API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17
6. Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
7. Web Applications and JSPs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
8. Plugins . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
9. Lookups . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72
10. Appenders . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
11. Layouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
12. Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
13. Async Loggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225
14. Garbage-free Logging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
15. JMX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
16. Logging Separation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
17. Extending Log4j . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
257
18. Programmatic Log4j Configuration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
19. Custom Log Levels . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

Table of Contents

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

ii

1 Introduction

1

1 Introduction

.......................................................................................................................................
1.1 Welcome to Log4j 2!
1.1.1 Introduction

Almost every large application includes its own logging or tracing API. In conformance with this
rule, the E.U. SEMPER project decided to write its own tracing API. This was in early 1996. After
countless enhancements, several incarnations and much work that API has evolved to become log4j,
a popular logging package for Java. The package is distributed under the Apache Software License,
a fully-fledged open source license certified by the open source initiative. The latest log4j version,
including full-source code, class files and documentation can be found at http://logging.apache.org/
log4j/2.x/index.html.
Inserting log statements into code is a low-tech method for debugging it. It may also be the only way
because debuggers are not always available or applicable. This is usually the case for multithreaded
applications and distributed applications at large.
Experience indicates that logging was an important component of the development cycle. It offers
several advantages. It provides precise context about a run of the application. Once inserted into the
code, the generation of logging output requires no human intervention. Moreover, log output can
be saved in persistent medium to be studied at a later time. In addition to its use in the development
cycle, a sufficiently rich logging package can also be viewed as an auditing tool.
As Brian W. Kernighan and Rob Pike put it in their truly excellent book "The Practice of
Programming":
As personal choice, we tend not to use debuggers beyond getting a stack trace or the value of a
variable or two. One reason is that it is easy to get lost in details of complicated data structures and
control flow; we find stepping through a program less productive than thinking harder and adding
output statements and self-checking code at critical places. Clicking over statements takes longer
than scanning the output of judiciously-placed displays. It takes less time to decide where to put print
statements than to single-step to the critical section of code, even assuming we know where that is.
More important, debugging statements stay with the program; debugging sessions are transient.
Logging does have its drawbacks. It can slow down an application. If too verbose, it can cause
scrolling blindness. To alleviate these concerns, log4j is designed to be reliable, fast and extensible.
Since logging is rarely the main focus of an application, the log4j API strives to be simple to
understand and to use.
1.1.2 Log4j 2

Log4j 1.x has been widely adopted and used in many applications. However, through the years
development on it has slowed down. It has become more difficult to maintain due to its need to be
compliant with very old versions of Java and became End of Life in August 2015. Its alternative,
SLF4J/Logback made many needed improvements to the framework. So why bother with Log4j 2?
Here are a few of the reasons.
1. Log4j 2 is designed to be usable as an audit logging framework. Both Log4j 1.x and Logback
will lose events while reconfiguring. Log4j 2 will not. In Logback, exceptions in Appenders are
never visible to the application. In Log4j 2 Appenders can be configured to allow the exception
to percolate to the application.
2. Log4j 2 contains next-generation Asynchronous Loggers based on the LMAX Disruptor library.
In multi-threaded scenarios Asynchronous Loggers have 10 times higher throughput and orders
of magnitude lower latency than Log4j 1.x and Logback.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

1 Introduction

2

3. Log4j 2 is garbage free for stand-alone applications, and low garbage for web applications
during steady state logging. This reduces pressure on the garbage collector and can give better
response time performance.
4. Log4j 2 uses a Plugin system that makes it extremely easy to extend the framework by adding
new Appenders, Filters, Layouts, Lookups, and Pattern Converters without requiring any
changes to Log4j.
5. Due to the Plugin system configuration is simpler. Entries in the configuration do not require a
class name to be specified.
6. Support for custom log levels. Custom log levels can be defined in code or in configuration.
7. Support for lambda expressions. Client code running on Java 8 can use lambda expressions to
lazily construct a log message only if the requested log level is enabled. Explicit level checks are
not needed, resulting in cleaner code.
8. Support for Message objects. Messages allow support for interesting and complex constructs
to be passed through the logging system and be efficiently manipulated. Users are free to create
their own Message types and write custom Layouts, Filters and Lookups to manipulate
them.
9. Log4j 1.x supports Filters on Appenders. Logback added TurboFilters to allow filtering of
events before they are processed by a Logger. Log4j 2 supports Filters that can be configured to
process events before they are handled by a Logger, as they are processed by a Logger or on an
Appender.
10.Many Logback Appenders do not accept a Layout and will only send data in a fixed format.
Most Log4j 2 Appenders accept a Layout, allowing the data to be transported in any format
desired.
11.Layouts in Log4j 1.x and Logback return a String. This resulted in the problems discussed at
Logback Encoders. Log4j 2 takes the simpler approach that Layouts always return a byte array.
This has the advantage that it means they can be used in virtually any Appender, not just the ones
that write to an OutputStream.
12.The Syslog Appender supports both TCP and UDP as well as support for the BSD syslog and
the RFC 5424 formats.
13.Log4j 2 takes advantage of Java 5 concurrency support and performs locking at the lowest level
possible. Log4j 1.x has known deadlock issues. Many of these are fixed in Logback but many
Logback classes still require synchronization at a fairly high level.
14.It is an Apache Software Foundation project following the community and support model used
by all ASF projects. If you want to contribute or gain the right to commit changes just follow the
path outlined at Contributing.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

3

2 Architecture

.......................................................................................................................................
2.1 Architecture
2.1.1 Main Components

Log4j uses the classes shown in the diagram below.

Applications using the Log4j 2 API will request a Logger with a specific name from the LogManager.
The LogManager will locate the appropriate LoggerContext and then obtain the Logger from it. If the
Logger must be created it will be associated with the LoggerConfig that contains either a) the same
name as the Logger, b) the name of a parent package, or c) the root LoggerConfig. LoggerConfig
objects are created from Logger declarations in the configuration. The LoggerConfig is associated
with the Appenders that actually deliver the LogEvents.
2.1.1.1 Logger Hierarchy

The first and foremost advantage of any logging API over plain System.out.println resides in
its ability to disable certain log statements while allowing others to print unhindered. This capability
assumes that the logging space, that is, the space of all possible logging statements, is categorized
according to some developer-chosen criteria.
In Log4j 1.x the Logger Hierarchy was maintained through a relationship between Loggers. In Log4j
2 this relationship no longer exists. Instead, the hierarchy is maintained in the relationship between
LoggerConfig objects.
Loggers and LoggerConfigs are named entities. Logger names are case-sensitive and they follow the
hierarchical naming rule:
Named Hierarchy

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

4

A LoggerConfig is said to be an ancestor of another LoggerConfig if its name followed
by a dot is a prefix of the descendant logger name. A LoggerConfig is said to be a parent
of a child LoggerConfig if there are no ancestors between itself and the descendant
LoggerConfig.
For example, the LoggerConfig named "com.foo" is a parent of the LoggerConfig named
"com.foo.Bar". Similarly, "java" is a parent of "java.util" and an ancestor of
"java.util.Vector". This naming scheme should be familiar to most developers.
The root LoggerConfig resides at the top of the LoggerConfig hierarchy. It is exceptional in
that it always exists and it is part of every hierarchy. A Logger that is directly linked to the root
LoggerConfig can be obtained as follows:
Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

Alternatively, and more simply:
Logger logger = LogManager.getRootLogger();

All other Loggers can be retrieved using the LogManager.getLogger static method by passing the
name of the desired Logger. Further information on the Logging API can be found in the Log4j 2
API.
2.1.1.2 LoggerContext

The LoggerContext acts as the anchor point for the Logging system. However, it is possible to have
multiple active LoggerContexts in an application depending on the circumstances. More details on the
LoggerContext are in the Log Separation section.
2.1.1.3 Configuration

Every LoggerContext has an active Configuration. The Configuration contains all the Appenders,
context-wide Filters, LoggerConfigs and contains the reference to the StrSubstitutor. During
reconfiguration two Configuration objects will exist. Once all Loggers have been redirected to the
new Configuration, the old Configuration will be stopped and discarded.
2.1.1.4 Logger

As stated previously, Loggers are created by calling LogManager.getLogger. The Logger itself
performs no direct actions. It simply has a name and is associated with a LoggerConfig. It extends
AbstractLogger and implements the required methods. As the configuration is modified Loggers may
become associated with a different LoggerConfig, thus causing their behavior to be modified.
2.Retrieving Loggers

Calling the LogManager.getLogger method with the same name will always return a reference to
the exact same Logger object.
For example, in
Logger x = LogManager.getLogger("wombat");
Logger y = LogManager.getLogger("wombat");

x and y refer to exactly the same Logger object.

Configuration of the log4j environment is typically done at application initialization. The preferred
way is by reading a configuration file. This is discussed in Configuration.
Log4j 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

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

5

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. Log4j does
not restrict the possible set of loggers. The developer is free to name the loggers as desired.
Since naming Loggers after their owning class is such a common idiom, the convenience method
LogManager.getLogger() is provided to automatically use the calling class's fully qualified class
name as the Logger name.
Nevertheless, naming loggers after the class where they are located seems to be the best strategy
known so far.
2.1.1.5 LoggerConfig

LoggerConfig objects are created when Loggers are declared in the logging configuration. The
LoggerConfig contains a set of Filters that must allow the LogEvent to pass before it will be passed to
any Appenders. It contains references to the set of Appenders that should be used to process the event.
2.Log Levels

LoggerConfigs will be assigned a Log Level. The set of built-in levels includes TRACE, DEBUG,
INFO, WARN, ERROR, and FATAL. Log4j 2 also supports custom log levels. Another mechanism
for getting more granularity is to use Markers instead.
Log4j 1.x and Logback both have the concept of "Level Inheritance". In Log4j 2, Loggers and
LoggerConfigs are two different objects so this concept is implemented differently. Each Logger
references the appropriate LoggerConfig which in turn can reference its parent, thus achieving the
same effect.
Below are five tables with various assigned level values and the resulting levels that will be associated
with each Logger. Note that in all these cases if the root LoggerConfig is not configured a default
Level will be assigned to it.

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

Logger Level

root

root

DEBUG

DEBUG

X

root

DEBUG

DEBUG

X.Y

root

DEBUG

DEBUG

X.Y.Z

root

DEBUG

DEBUG

Example 1
In example 1 above, only the root logger is configured and has a Log Level. All the other Loggers
reference the root LoggerConfig and use its Level.

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

Level

root

root

DEBUG

DEBUG

X

X

ERROR

ERROR

X.Y

X.Y

INFO

INFO

X.Y.Z

X.Y.Z

WARN

WARN

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

6

Example 2
In example 2, all loggers have a configured LoggerConfig and obtain their Level from it.

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

Level

root

root

DEBUG

DEBUG

X

X

ERROR

ERROR

X.Y

X

ERROR

ERROR

X.Y.Z

X.Y.Z

WARN

WARN

Example 3
In example 3, the loggers root, X and X.Y.Z each have a configured LoggerConfig with the same
name. The Logger X.Y does not have a configured LoggerConfig with a matching name so uses the
configuration of LoggerConfig X since that is the LoggerConfig whose name has the longest match to
the start of the Logger's name.

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

level

root

root

DEBUG

DEBUG

X

X

ERROR

ERROR

X.Y

X

ERROR

ERROR

X.Y.Z

X

ERROR

ERROR

Example 4
In example 4, the loggers root and X each have a Configured LoggerConfig with the same name.
The loggers X.Y and X.Y.Z do not have configured LoggerConfigs and so get their Level from the
LoggerConfig assigned to them, X, since it is the LoggerConfig whose name has the longest match to
the start of the Logger's name.

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

level

root

root

DEBUG

DEBUG

X

X

ERROR

ERROR

X.Y

X.Y

INFO

INFO

X.YZ

X

ERROR

ERROR

Example 5
In example 5, the loggers root. X, and X.Y each have a Configured LoggerConfig with the same
name. The logger X.YZ does not have configured LoggerConfig and so gets its Level from the
LoggerConfig assigned to it, X, since it is the LoggerConfig whose name has the longest match to the
start of the Logger's name. It is not associated with LoggerConfig X.Y since tokens after periods must
match exactly.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

7

Logger Name

Assigned
LoggerConfig

LoggerConfig Level

Level

root

root

DEBUG

DEBUG

X

X

ERROR

ERROR

X.Y

X.Y

ERROR

X.Y.Z

X.Y

ERROR

Example 6
In example 6, LoggerConfig X.Y it has no configured level so it inherits its level from LoggerConfig
X. Logger X.Y.Z uses LoggerConfig X.Y since it doesn't have a LoggerConfig with a name that
exactly matches. It too inherits its logging level from LoggerConfig X.
The table below illustrates how Level filtering works. In the table, the vertical header shows the
Level of the LogEvent, while the horizontal header shows the Level associated with the appropriate
LoggerConfig. The intersection identifies whether the LogEvent would be allowed to pass for further
processing (Yes) or discarded (No).
Event
Level

LoggerConfig
Level
TRACE

DEBUG

INFO

WARN

ERROR

FATAL

OFF

ALL

YES

YES

YES

YES

YES

YES

NO

TRACE

YES

NO

NO

NO

NO

NO

NO

DEBUG

YES

YES

NO

NO

NO

NO

NO

INFO

YES

YES

YES

NO

NO

NO

NO

WARN

YES

YES

YES

YES

NO

NO

NO

ERROR

YES

YES

YES

YES

YES

NO

NO

FATAL

YES

YES

YES

YES

YES

YES

NO

OFF

NO

NO

NO

NO

NO

NO

NO

2.1.1.6 Filter

In addition to the automatic log Level filtering that takes place as described in the previous section,
Log4j provides Filters that can be applied before control is passed to any LoggerConfig, after
control is passed to a LoggerConfig but before calling any Appenders, after control is passed to a
LoggerConfig but before calling a specific Appender, and on each Appender. In a manner very similar
to firewall filters, each Filter can return one of three results, Accept, Deny or Neutral. A response
of Accept means that no other Filters should be called and the event should progress. A response of
Deny means the event should be immediately ignored and control should be returned to the caller. A
response of Neutral indicates the event should be passed to other Filters. If there are no other Filters
the event will be processed.
Although an event may be accepted by a Filter the event still might not be logged. This can happen
when the event is accepted by the pre-LoggerConfig Filter but is then denied by a LoggerConfig filter
or is denied by all Appenders.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

8

2.1.1.7 Appender

The ability to selectively enable or disable logging requests based on their logger is only part of the
picture. Log4j allows logging requests to print to multiple destinations. In log4j speak, an output
destination is called an Appender. Currently, appenders exist for the console, files, remote socket
servers, Apache Flume, JMS, remote UNIX Syslog daemons, and various database APIs. See the
section on Appenders for more details on the various types available. More than one Appender can be
attached to a Logger.
An Appender can be added to a Logger by calling the addLoggerAppender method of the current
Configuration. If a LoggerConfig matching the name of the Logger does not exist, one will be created,
the Appender will be attached to it and then all Loggers will be notified to update their LoggerConfig
references.
Each enabled logging request for a given logger will be forwarded to all the appenders in
that Logger's LoggerConfig as well as the Appenders of the LoggerConfig's parents. In other
words, Appenders are inherited additively from the LoggerConfig 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 LoggerConfig, say C, then enabled
logging requests for C and C's children will print in a file and on the console. It is possible to
override this default behavior so that Appender accumulation is no longer additive by setting
additivity="false" on the Logger declaration in the configuration file.
The rules governing appender additivity are summarized below.
Appender Additivity
The output of a log statement of Logger L will go to all the Appenders in the LoggerConfig
associated with L and the ancestors of that LoggerConfig. This is the meaning of the term
"appender additivity".
However, if an ancestor of the LoggerConfig associated with Logger L, say P, has the
additivity flag set to false, then L's output will be directed to all the appenders in L's
LoggerConfig and it's ancestors up to and including P but not the Appenders in any of the
ancestors of P.
Loggers have their additivity flag set to true by default.
The table below shows an example:
Logger
Name

Added
Appenders

Additivity
Flag

Output Targets

Comment

root

A1

not applicable

A1

The root logger
has no parent so
additivity does not
apply to it.

x

A-x1, A-x2

true

A1, A-x1, A-x2

Appenders of "x"
and root.

x.y

none

true

A1, A-x1, A-x2

Appenders of "x"
and root. It would
not be typical to
configure a Logger
with no Appenders.

x.y.z

A-xyz1

true

A1, A-x1, A-x2, Axyz1

Appenders in
"x.y.z", "x" and root.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

2 Architecture

9

security

A-sec

false

A-sec

No appender
accumulation since
the additivity flag is
set to false.

security.access

none

true

A-sec

Only appenders of
"security" because
the additivity flag in
"security" is set to
false.

2.1.1.8 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 LogEvent according to the user's wishes, whereas an appender takes care of sending
the formatted output to its destination. The PatternLayout, part of the standard log4j distribution, lets
the user specify the output format according to conversion patterns similar to the C language printf
function.
For example, the PatternLayout with the conversion pattern "%r [%t] %-5p %c - %m%n" will output
something akin to:
176 [main] INFO

org.foo.Bar - Located nearest gas station.

The first field is the number of milliseconds elapsed since the start of the program. The second field
is the thread making the log request. The third field is the level of the log statement. The fourth field
is the name of the logger associated with the log request. The text after the '-' is the message of the
statement.
Log4j comes with many different Layouts for various use cases such as JSON, XML, HTML, and
Syslog (including the new RFC 5424 version). Other appenders such as the database connectors fill in
specified fields instead of a particular textual layout.
Just as importantly, log4j will render the content of the log message according to user specified
criteria. For example, if you frequently need to log Oranges, an object type used in your current
project, then you can create an OrangeMessage that accepts an Orange instance and pass that to Log4j
so that the Orange object can be formatted into an appropriate byte array when required.
2.1.1.9 StrSubstitutor and StrLookup

The StrSubstitutor class and StrLookup interface were borrowed from Apache Commons Lang
and then modified to support evaluating LogEvents. In addition the Interpolator class was borrowed
from Apache Commons Configuration to allow the StrSubstitutor to evaluate variables that from
multiple StrLookups. It too was modified to support evaluating LogEvents. Together these provide
a mechanism to allow the configuration to reference variables coming from System Properties, the
configuration file, the ThreadContext Map, StructuredData in the LogEvent. The variables can either
be resolved when the configuration is processed or as each event is processed, if the component is
capable of handling it. See Lookups for more information.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

3 Log4j 1.x Migration

10

3 Log4j 1.x Migration

.......................................................................................................................................
3.1 Migrating from Log4j 1.x

3.1.1 Using the Log4j 1.x bridge

Perhaps the simplest way to convert to using Log4j 2 is to replace the log4j 1.x jar file with Log4j
2's log4j-1.2-api.jar. However, to use this successfully applications must meet the following
requirements:
1. They must not access methods and classes internal to the Log4j 1.x implementation such as
Appenders, LoggerRepository or Category's callAppenders method.
2. They must not programmatically configure Log4j.
3. They must not configure by calling the classes DOMConfigurator or
PropertyConfigurator.
3.1.2 Converting to the Log4j 2 API

For the most part, converting from the Log4j 1.x API to Log4j 2 should be fairly simple. Many of the
log statements will require no modification. However, where necessary the following changes must be
made.
1. The main package in version 1 is org.apache.log4j, in version 2 it is
org.apache.logging.log4j
2. Calls to org.apache.log4j.Logger.getLogger() must be modified to
org.apache.logging.log4j.LogManager.getLogger().
3. Calls to org.apache.log4j.Logger.getRootLogger() or
org.apache.log4j.LogManager.getRootLogger() must be replaced with
org.apache.logging.log4j.LogManager.getRootLogger().
4. Calls to org.apache.log4j.Logger.getLogger that accept a LoggerFactory must
remove the org.apache.log4j.spi.LoggerFactory and use one of Log4j 2's other

extension mechanisms.
5. Replace calls to org.apache.log4j.Logger.getEffectiveLevel() with
org.apache.logging.log4j.Logger.getLevel().
6. Remove calls to org.apache.log4j.LogManager.shutdown(), they are not needed in
version 2 because the Log4j Core now automatically adds a JVM shutdown hook on start up to
perform any Core clean ups.
1. Starting in Log4j 2.1, you can specify a custom ShutdownCallbackRegistry to override the
default JVM shutdown hook strategy.
2. Starting in Log4j 2.6, you can now use
org.apache.logging.log4j.LogManager.shutdown() to initiate shutdown
manually.
7. Calls to org.apache.log4j.Logger.setLevel() or similar methods
are not supported in the API. Applications should remove these. Equivalent
functionality is provided in the Log4j 2 implementation classes, see
org.apache.logging.log4j.core.config.Configurator.setLevel(), but may leave
the application susceptible to changes in Log4j 2 internals.
8. Where appropriate, applications should convert to use parameterized messages instead of String
concatenation.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

3 Log4j 1.x Migration

11

9. org.apache.log4j.MDC and org.apache.log4j.NDC have been replaced by the Thread
Context.
3.1.3 Configuring Log4j 2

Although the Log4j 2 configuration syntax is different than that of Log4j 1.x, most, if not all, of the
same functionality is available.
Note that system property interpolation via the ${foo} syntax has been extended to allow property
lookups from many different sources. See the Lookups documentation for more details. For example,
using a lookup for the system property named catalina.base, in Log4j 1.x, the syntax would be
${catalina.base}. In Log4j 2, the syntax would be ${sys:catalina.base}.
Log4j 1.x has a XMLLayout which is different from the XmlLayout in Log4j 2, the log4j-1.2-api
module contains a Log4j1XmlLayout which produce output in the format as in Log4j 1.x. The
Log4j 1.x SimpleLayout can be emulated with PatternLayout "%level - %m%n". The Log4j 1.x
TTCCLayout can be emulated with PatternLayout "%r [%t] %p %c %notEmpty{%ndc }- %m%n".
Both PatternLayout and EnhancedPatternLayout in Log4j 1.x can be replaced with
PatternLayout in Log4j 2. The log4j-1.2-api module contains two pattern conversions "%ndc" and
"%properties" which can be used to emulate "%x" and "%X" in Log4j 1.x PatternLayout ("%x" and
%X" in Log4j 2 have a slightly different format).
Below are the example configurations for Log4j 1.x and their counterparts in Log4j 2.
3.1.3.1 Sample 1 - Simple configuration using a Console Appender

Log4j 1.x XML configuration

















Log4j 2 XML configuration

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

3 Log4j 1.x Migration
















3.1.3.2 Sample 2 - Simple configuration using a File Appender, XMLLayout and SimpleLayout

Log4j 1.x XML configuration





















Log4j 2 XML configuration

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12

3 Log4j 1.x Migration

13





















3.1.3.3 Sample 3 - SocketAppender

Log4j 1.x XML configuration. This example from Log4j 1.x is misleading. The SocketAppender does
not actually use a Layout. Configuring one will have no effect.


























Log4j 2 XML configuration

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

3 Log4j 1.x Migration





















3.1.3.4 Sample 4 - AsyncAppender and TTCCLayout

Log4j 1.x XML configuration using the AsyncAppender.




















Log4j 2 XML configuration.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14

3 Log4j 1.x Migration

15


















3.1.3.5 Sample 5 - AsyncAppender with Console and File

Log4j 1.x XML configuration using the AsyncAppender.
























Log4j 2 XML configuration. Note that the Async Appender should be configured after the appenders
it references. This will allow it to shutdown properly.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

3 Log4j 1.x Migration






















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16

4 API

17

4 API

.......................................................................................................................................
4.1 Log4j 2 API

4.1.1 Overview

The Log4j 2 API provides the interface that applications should code to and provides the adapter
components required for implementers to create a logging implementation. Although Log4j 2 is
broken up between an API and an implementation, the primary purpose of doing so was not to allow
multiple implementations, although that is certainly possible, but to clearly define what classes and
methods are safe to use in "normal" application code.
4.1.1.1 Hello World!

No introduction would be complete without the customary Hello, World example. Here is ours. First,
a Logger with the name "HelloWorld" is obtained from the LogManager. Next, the logger is used
to write the "Hello, World!" message, however the message will be written only if the Logger is
configured to allow informational messages.
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class HelloWorld {
private static final Logger logger = LogManager.getLogger("HelloWorld");
public static void main(String[] args) {
logger.info("Hello, World!");
}
}

The output from the call to logger.info() will vary significantly depending on the configuration used.
See the Configuration section for more details.
4.1.1.2 Substituting Parameters

Frequently the purpose of logging is to provide information about what is happening in the system,
which requires including information about the objects being manipulated. In Log4j 1.x this could be
accomplished by doing:
if (logger.isDebugEnabled()) {
logger.debug("Logging in user " + user.getName() + " with birthday " + user.getBirthdayCalendar());
}

Doing this repeatedly has the effect of making the code feel like it is more about logging than the
actual task at hand. In addition, it results in the logging level being checked twice; once on the call to
isDebugEnabled and once on the debug method. A better alternative would be:
logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());

With the code above the logging level will only be checked once and the String construction will only
occur when debug logging is enabled.
4.1.1.3 Formatting Parameters

Formatter Loggers leave formatting up to you if toString() is not what you want. To facilitate
formatting, you can use the same format strings as Java's Formatter. For example:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

4 API

18

public static Logger logger = LogManager.getFormatterLogger("Foo");

logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
logger.debug("Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar
logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);

To use a formatter Logger, you must call one of the LogManager getFormatterLogger methods. The
output for this example shows that Calendar toString() is verbose compared to custom formatting:

2012-12-12 11:56:19,633 [main] DEBUG: User John Smith with birthday java.util.GregorianCalendar[time=?,areFie
2012-12-12 11:56:19,643 [main] DEBUG: User John Smith with birthday 05 23, 1995
2012-12-12 11:56:19,643 [main] DEBUG: Integer.MAX_VALUE = 2,147,483,647
2012-12-12 11:56:19,643 [main] DEBUG: Long.MAX_VALUE = 9,223,372,036,854,775,807

4.1.1.4 Mixing Loggers with Formatter Loggers

Formatter loggers give fine-grained control over the output format, but have the drawback that the
correct type must be specified (for example, passing anything other than a decimal integer for a %d
format parameter gives an exception).
If your main usage is to use {}-style parameters, but occasionally you need fine-grained control over
the output format, you can use the printf method:
public static Logger logger = LogManager.getLogger("Foo");

logger.debug("Opening connection to {}...", someDataSource);
logger.printf(Level.INFO, "Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBir

4.1.1.5 Java 8 lambda support for lazy logging

In release 2.4, the Logger interface added support for lambda expressions. This allows client code
to lazily log messages without explicitly checking if the requested log level is enabled. For example,
previously you would write:
// pre-Java 8 style optimization: explicitly check the log level
// to make sure the expensiveOperation() method is only called if necessary
if (logger.isTraceEnabled()) {
logger.trace("Some long-running operation returned {}", expensiveOperation());
}

With Java 8 you can achieve the same effect with a lambda expression. You no longer need to
explicitly check the log level:
// Java-8 style optimization: no need to explicitly check the log level:
// the lambda expression is not evaluated if the TRACE level is not enabled
logger.trace("Some long-running operation returned {}", () -> expensiveOperation());

4.1.1.6 Logger Names

Most logging implementations use a hierarchical scheme for matching logger names with logging
configuration. In this scheme, the logger name hierarchy is represented by '.' characters in
the logger name, in a fashion very similar to the hierarchy used for Java package names. For
example, org.apache.logging.appender and org.apache.logging.filter both have
org.apache.logging as their parent. In most cases, applications name their loggers by passing the

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

4 API

19

current class's name to LogManager.getLogger(...). Because this usage is so common, Log4j 2
provides that as the default when the logger name parameter is either omitted or is null. For example,
in all examples below the Logger will have a name of "org.apache.test.MyTest".
package org.apache.test;
public class MyTest {
private static final Logger logger = LogManager.getLogger(MyTest.class);
}
package org.apache.test;
public class MyTest {
private static final Logger logger = LogManager.getLogger(MyTest.class.getName());
}
package org.apache.test;
public class MyTest {
private static final Logger logger = LogManager.getLogger();
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

20

5 Configuration

.......................................................................................................................................
5.1 Configuration
Inserting log requests into the application code requires a fair amount of planning and effort.
Observation shows that approximately 4 percent of code is dedicated to logging. Consequently, even
moderately sized applications will have thousands of logging statements embedded within their code.
Given their number, it becomes imperative to manage these log statements without the need to modify
them manually.
Configuration of Log4j 2 can be accomplished in 1 of 4 ways:
1. Through a configuration file written in XML, JSON, YAML, or properties format.
2. Programmatically, by creating a ConfigurationFactory and Configuration implementation.
3. Programmatically, by calling the APIs exposed in the Configuration interface to add components
to the default configuration.
4. Programmatically, by calling methods on the internal Logger class.
This page focuses primarily on configuring Log4j through a configuration file. Information on
programmatically configuring Log4j can be found at Extending Log4j 2 and Programmatic Log4j
Configuration.
Note that unlike Log4j 1.x, the public Log4j 2 API does not expose methods to add, modify or remove
appenders and filters or manipulate the configuration in any way.

5.1.1 Automatic Configuration

Log4j has the ability to automatically configure itself during initialization. When Log4j starts it
will locate all the ConfigurationFactory plugins and arrange them in weighted order from highest to
lowest. As delivered, Log4j contains four ConfigurationFactory implementations: one for JSON, one
for YAML, one for properties, and one for XML.
1. Log4j will inspect the "log4j.configurationFile" system property and, if set, will attempt
to load the configuration using the ConfigurationFactory that matches the file extension.
2. If no system property is set the properties ConfigurationFactory will look for log4j2test.properties in the classpath.
3. If no such file is found the YAML ConfigurationFactory will look for log4j2-test.yaml or
log4j2-test.yml in the classpath.
4. If no such file is found the JSON ConfigurationFactory will look for log4j2-test.json or
log4j2-test.jsn in the classpath.
5. If no such file is found the XML ConfigurationFactory will look for log4j2-test.xml in the
classpath.
6. If a test file cannot be located the properties ConfigurationFactory will look for
log4j2.properties on the classpath.
7. If a properties file cannot be located the YAML ConfigurationFactory will look for
log4j2.yaml or log4j2.yml on the classpath.
8. If a YAML file cannot be located the JSON ConfigurationFactory will look for log4j2.json or
log4j2.jsn on the classpath.
9. If a JSON file cannot be located the XML ConfigurationFactory will try to locate log4j2.xml
on the classpath.
10.If no configuration file could be located the DefaultConfiguration will be used. This will
cause logging output to go to the console.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

21

An example application named MyApp that uses log4j can be used to illustrate how this is done.
import com.foo.Bar;
// Import log4j classes.
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class MyApp {
// Define a static logger variable so that it references the
// Logger instance named "MyApp".
private static final Logger logger = LogManager.getLogger(MyApp.class);
public static void main(final String... args) {
// Set up a simple configuration that logs on the console.
logger.trace("Entering application.");
Bar bar = new Bar();
if (!bar.doIt()) {
logger.error("Didn't do it.");
}
logger.trace("Exiting application.");
}
}

MyApp begins by importing log4j related classes. It then defines a static logger variable with the name
MyApp which happens to be the fully qualified name of the class.
MyApp uses the Bar class defined in the package com.foo.
package com.foo;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;
public class Bar {
static final Logger logger = LogManager.getLogger(Bar.class.getName());
public boolean doIt() {
logger.entry();
logger.error("Did it again!");
return logger.exit(false);
}
}

Log4j will provide a default configuration if it cannot locate a configuration file. The default
configuration, provided in the DefaultConfiguration class, will set up:
• A ConsoleAppender attached to the root logger.
• A PatternLayout set to the pattern "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg
%n" attached to the ConsoleAppender
Note that by default Log4j assigns the root logger to Level.ERROR.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

22

The output of MyApp would be similar to:
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] ERROR MyApp - Didn't do it.

As was described previously, Log4j will first attempt to configure itself from configuration files. A
configuration equivalent to the default would look like:














Once the file above is placed into the classpath as log4j2.xml you will get results identical to those
listed above. Changing the root level to trace will result in results similar to:
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540

[main]
[main]
[main]
[main]
[main]
[main]

TRACE
TRACE
ERROR
TRACE
ERROR
TRACE

MyApp - Entering application.
com.foo.Bar - entry
com.foo.Bar - Did it again!
com.foo.Bar - exit with (false)
MyApp - Didn't do it.
MyApp - Exiting application.

Note that status logging is disabled when the default configuration is used.

5.1.2 Additivity

Perhaps it is desired to eliminate all the TRACE output from everything except com.foo.Bar.
Simply changing the log level would not accomplish the task. Instead, the solution is to add a new
logger definition to the configuration:





With this configuration all log events from com.foo.Bar will be recorded while only error events
will be recorded from all other components.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

23

In the previous example all the events from com.foo.Bar were still written to the Console. This is
because the logger for com.foo.Bar did not have any appenders configured while its parent did. In
fact, the following configuration

















would result in
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540
17:13:01.540

[main]
[main]
[main]
[main]
[main]
[main]

TRACE
TRACE
ERROR
TRACE
TRACE
ERROR

com.foo.Bar - entry
com.foo.Bar - entry
com.foo.Bar - Did it again!
com.foo.Bar - exit (false)
com.foo.Bar - exit (false)
MyApp - Didn't do it.

Notice that the trace messages from com.foo.Bar appear twice. This is because the appender
associated with logger com.foo.Bar is first used, which writes the first instance to the Console.
Next, the parent of com.foo.Bar, which in this case is the root logger, is referenced. The event is
then passed to its appender, which is also writes to the Console, resulting in the second instance. This
is known as additivity. While additivity can be quite a convenient feature (as in the first previous
example where no appender reference needed to be configured), in many cases this behavior is
considered undesirable and so it is possible to disable it by setting the additivity attribute on the logger
to false:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

24


















Once an event reaches a logger with its additivity set to false the event will not be passed to any of its
parent loggers, regardless of their additivity setting.

5.1.3 Automatic Reconfiguration

When configured from a File, Log4j has the ability to automatically detect changes to the
configuration file and reconfigure itself. If the monitorInterval attribute is specified on the
configuration element and is set to a non-zero value then the file will be checked the next time a
log event is evaluated and/or logged and the monitorInterval has elapsed since the last check. The
example below shows how to configure the attribute so that the configuration file will be checked for
changes only after at least 30 seconds have elapsed. The minimum interval is 5 seconds.


...


5.1.4 Chainsaw can automatically process your log files (Advertising appender configurations)

Log4j provides the ability to 'advertise' appender configuration details for all file-based appenders
as well as socket-based appenders. For example, for file-based appenders, the file location and the
pattern layout in the file are included in the advertisement. Chainsaw and other external systems can
discover these advertisements and use that information to intelligently process the log file.
The mechanism by which an advertisement is exposed, as well as the advertisement format, is specific
to each Advertiser implementation. An external system which would like to work with a specific
Advertiser implementation must understand how to locate the advertised configuration as well as the
format of the advertisement. For example, a 'database' Advertiser may store configuration details in
a database table. An external system can read that database table in order to discover the file location
and the file format.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

25

Log4j provides one Advertiser implementation, a 'multicastdns' Advertiser, which advertises appender
configuration details via IP multicast using the http://jmdns.sourceforge.net library.
Chainsaw automatically discovers log4j's multicastdns-generated advertisements and displays
those discovered advertisements in Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's
classpath). To begin parsing and tailing a log file provided in an advertisement, just double-click
the advertised entry in Chainsaw's Zeroconf tab. Currently, Chainsaw only supports FileAppender
advertisements.
To advertise an appender configuration:
•
•
•
•

Add the JmDns library from http://jmdns.sourceforge.net to the application classpath
Set the 'advertiser' attribute of the configuration element to 'multicastdns'
Set the 'advertise' attribute on the appender element to 'true'
If advertising a FileAppender-based configuration, set the 'advertiseURI' attribute on the
appender element to an appropriate URI
FileAppender-based configurations require an additional 'advertiseURI' attribute to be specified on
the appender. The 'advertiseURI' attribute provides Chainsaw with information on how the file can be
accessed. For example, the file may be remotely accessible to Chainsaw via ssh/sftp by specifying a
Commons VFS ( http://commons.apache.org/proper/commons-vfs/) sftp:// URI, an http:// URI may
be used if the file is accessible through a web server, or a file:// URI can be specified if accessing the
file from a locally-running instance of Chainsaw.
Here is an example advertisement-enabled appender configuration which can be used by a locallyrunning Chainsaw to automatically tail the log file (notice the file:// advertiseURI):
Please note, you must add the JmDns library from http://jmdns.sourceforge.net to your
application classpath in order to advertise with the 'multicastdns' advertiser.



...





5.1.5 Configuration Syntax

As of version 2.9, for security reasons, Log4j does not process DTD in XML files. If you want to split
the configuration in multiple files, use XInclude or Composite Configuration.
As the previous examples have shown as well as those to follow, Log4j allows you to easily redefine
logging behavior without needing to modify your application. It is possible to disable logging for
certain parts of the application, log only when specific criteria are met such as the action being
performed for a specific user, route output to Flume or a log reporting system, etc. Being able to do
this requires understanding the syntax of the configuration files.
The configuration element in the XML file accepts several attributes:
Attribute Name

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

26

advertiser

(Optional) The Advertiser plugin name which will
be used to advertise individual FileAppender or
SocketAppender configurations. The only Advertiser
plugin provided is 'multicastdns".

dest

Either "err", which will send output to stderr, or a file
path or URL.

monitorInterval

The minimum amount of time, in seconds, that must
elapse before the file configuration is checked for
changes.

name

The name of the configuration.

packages

A comma separated list of package names to
search for plugins. Plugins are only loaded once per
classloader so changing this value may not have any
effect upon reconfiguration.

schema

Identifies the location for the classloader to located the
XML Schema to use to validate the configuration. Only
valid when strict is set to true. If not set no schema
validation will take place.

shutdownHook

Specifies whether or not Log4j should automatically
shutdown when the JVM shuts down. The shutdown
hook is enabled by default but may be disabled by
setting this attribute to "disable"

shutdownTimeout

Specifies how many milliseconds appenders and
background tasks will get to shutdown when the
JVM shuts down. Default is zero which mean
that each appender uses its default timeout, and
don't wait for background tasks. Not all appenders
will honor this, it is a hint and not an absolute
guarantee that the shutdown procedure will not
take longer. Setting this too low increase the risk
of losing outstanding log events not yet written to
the final destination. See LoggerContext.stop(long,
java.util.concurrent.TimeUnit). (Not used if
shutdownHook is set to "disable".)

status

The level of internal Log4j events that should
be logged to the console. Valid values for this
attribute are "trace", "debug", "info", "warn",
"error" and "fatal". Log4j will log details about
initialization, rollover and other internal actions
to the status logger. Setting status="trace" is
one of the first tools available to you if you need
to troubleshoot log4j.
(Alternatively, setting system property
log4j2.debug will also print internal Log4j2
logging to the console, including internal logging
that took place before the configuration file was
found.)

strict

Enables the use of the strict XML format. Not
supported in JSON configurations.

verbose

Enables diagnostic information while loading plugins.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

27

Log4j can be configured using two XML flavors; concise and strict. The concise format makes
configuration very easy as the element names match the components they represent however it cannot
be validated with an XML schema. For example, the ConsoleAppender is configured by declaring an
XML element named Console under its parent appenders element. However, element and attribute
names are are not case sensitive. In addition, attributes can either be specified as an XML attribute or
as an XML element that has no attributes and has a text value. So


and

%m%n


are equivalent.
The file below represents the structure of an XML configuration, but note that the elements in italics
below represent the concise element names that would appear in their place.
;


value


<
filter ... />

<
appender ... >
<
filter ... />

...



<
filter ... />

...






See the many examples on this page for sample appender, filter and logger declarations.
5.Strict XML

In addition to the concise XML format above, Log4j allows configurations to be specified in a
more "normal" XML manner that can be validated using an XML Schema. This is accomplished by
replacing the friendly element names above with their object type as shown below. For example,

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

instead of the ConsoleAppender being configuerd using an element named Console it is instead
configured as an appender element with a type attribute containing "Console".
;


value







...





...






Below is a sample configuration using the strict format.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

28

5 Configuration

29




target/test.log



















%d %p %C{1.} [%t] %m%n



















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

30

5.1.5.2 Configuration with JSON

In addition to XML, Log4j can be configured using JSON. The JSON format is very similar to the
concise XML format. Each key represents the name of a plugin and the key/value pairs associated
with it are its attributes. Where a key contains more than a simple value it itself will be a subordinate
plugin. In the example below, ThresholdFilter, Console, and PatternLayout are all plugins while the
Console plugin will be assigned a value of STDOUT for its name attribute and the ThresholdFilter
will be assigned a level of debug.
{ "configuration": { "status": "error", "name": "RoutingTest",
"packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename",
"value" : "target/rolling1/rollingtest-$${sd:type}.log" }
},
"ThresholdFilter": { "level": "debug" },
"appenders": {
"Console": { "name": "STDOUT",
"PatternLayout": { "pattern": "%m%n" },
"ThresholdFilter": { "level": "debug" }
},
"Routing": { "name": "Routing",
"Routes": { "pattern": "$${sd:type}",
"Route": [
{
"RollingFile": {
"name": "Rolling-${sd:type}", "fileName": "${filename}",
"filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
"PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
"SizeBasedTriggeringPolicy": { "size": "500" }
}
},
{ "AppenderRef": "STDOUT", "key": "Audit"}
]
}
}
},
"loggers": {
"logger": { "name": "EventLogger", "level": "info", "additivity": "false",
"AppenderRef": { "ref": "Routing" }},
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
}
}

Note that in the RoutingAppender the Route element has been declared as an array. This is valid
because each array element will be a Route component. This won't work for elements such as
appenders and filters, where each element has a different name in the concise format. Appenders and
filters can be defined as array elements if each appender or filter declares an attribute named "type"
that contains the type of the appender. The following example illustrates this as well as how to declare
multiple loggers as an array.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

31

{ "configuration": { "status": "debug", "name": "RoutingTest",
"packages": "org.apache.logging.log4j.test",
"properties": {
"property": { "name": "filename",
"value" : "target/rolling1/rollingtest-$${sd:type}.log" }
},
"ThresholdFilter": { "level": "debug" },
"appenders": {
"appender": [
{ "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": {
{ "type": "Routing", "name": "Routing",
"Routes": { "pattern": "$${sd:type}",
"Route": [
{
"RollingFile": {
"name": "Rolling-${sd:type}", "fileName": "${filename}",
"filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
"PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
"SizeBasedTriggeringPolicy": { "size": "500" }
}
},
{ "AppenderRef": "STDOUT", "key": "Audit"}
]
}
}
]
},
"loggers": {
"logger": [
{ "name": "EventLogger", "level": "info", "additivity": "false",
"AppenderRef": { "ref": "Routing" }},
{ "name": "com.foo.bar", "level": "error", "additivity": "false",
"AppenderRef": { "ref": "STDOUT" }}
],
"root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
}
}
}

Additional runtime dependencies are required for using JSON configuration files.

5.1.5.3 Configuration with YAML

Log4j also supports using YAML for configuration files. The structure follows the same pattern as
both the XML and YAML configuration formats. For example:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

Configuration:
status: warn
name: YAMLConfigTest
properties:
property:
name: filename
value: target/test-yaml.log
thresholdFilter:
level: debug
appenders:
Console:
name: STDOUT
PatternLayout:
Pattern: "%m%n"
File:
name: File
fileName: ${filename}
PatternLayout:
Pattern: "%d %p %C{1.} [%t] %m%n"
Filters:
ThresholdFilter:
level: error
Loggers:
logger:
name: org.apache.logging.log4j.test1
level: debug
additivity: false
ThreadContextMapFilter:
KeyValuePair:
key: test
value: 123
AppenderRef:
ref: STDOUT
name: org.apache.logging.log4j.test2
level: debug
additivity: false
AppenderRef:
ref: File
Root:
level: error
AppenderRef:
ref: STDOUT

Additional runtime dependencies are required for using YAML configuration files.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

32

5 Configuration

33

5.1.5.4 Configuring loggers

An understanding of how loggers work in Log4j is critical before trying to configure them. Please
reference the Log4j architecture if more information is required. Trying to configure Log4j without
understanding those concepts will lead to frustration.
A LoggerConfig is configured using the logger element. The logger element must have a name
attribute specified, will usually have a level attribute specified and may also have an additivity
attribute specified. The level may be configured with one of TRACE, DEBUG, INFO, WARN,
ERROR, ALL or OFF. If no level is specified it will default to ERROR. The additivity attribute may
be assigned a value of true or false. If the attribute is omitted the default value of true will be used.
A LoggerConfig (including the root LoggerConfig) can be configured with properties that will be
added to the properties copied from the ThreadContextMap. These properties can be referenced from
Appenders, Filters, Layouts, etc just as if they were part of the ThreadContext Map. The properties
can contain variables that will be resolved either when the configuration is parsed or dynamically
when each event is logged. See Property Substitution for more information on using variables.
The LoggerConfig may also be configured with one or more AppenderRef elements. Each appender
referenced will become associated with the specified LoggerConfig. If multiple appenders are
configured on the LoggerConfig each of them be called when processing logging events.
Every configuration must have a root logger. If one is not configured the default root LoggerConfig,
which has a level of ERROR and has a Console appender attached, will be used. The main differences
between the root logger and other loggers are
1. The root logger does not have a name attribute.
2. The root logger does not support the additivity attribute since it has no parent.

5.1.5.5 Configuring Appenders

An appender is configured either using the specific appender plugin's name or with an appender
element and the type attibute containing the appender plugin's name. In addition each appender must
have a name attribute specified with a value that is unique within the set of appenders. The name will
be used by loggers to reference the appender as described in the previous section.
Most appenders also support a layout to be configured (which again may be specified either using the
specific Layout plugin's name as the element or with "layout" as the element name along with a type
attribute that contains the layout plugin's name. The various appenders will contain other attributes or
elements that are required for them to function properly.

5.1.5.6 Configuring Filters

Log4j allows a filter to be specified in any of 4 places:
1. At the same level as the appenders, loggers and properties elements. These filters can accept or
reject events before they have been passed to a LoggerConfig.
2. In a logger element. These filters can accept or reject events for specific loggers.
3. In an appender element. These filters can prevent or cause events to be processed by the
appender.
4. In an appender reference element. These filters are used to determine if a Logger should route the
event to an appender.
Although only a single filter element can be configured, that element may be the filters element
which represents the CompositeFilter. The filters element allows any number of filter elements
to be configured within it. The following example shows how multiple filters can be configured on the
ConsoleAppender.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

34




target/test.log
















%d %p %C{1.} [%t] %m%n











${sys:user.name}













©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

35

5.1.5.7 Configuration with Properties

As of version 2.4, Log4j now supports configuration via properties files. Note that the property syntax
is NOT the same as the syntax used in Log4j 1. Like the XML and JSON configurations, properties
configurations define the configuration in terms of plugins and attributes to the plugins.
Prior to version 2.6, the properties configuration requires that you list the identifiers of the
appenders, filters and loggers, in a comma separated list in properties with those names. Each
of those components will then be expected to be defined in sets of properties that begin with
component.<.identifier>.. The identifier does not have to match the name of the component
being defined but must uniquely identify all the attributes and subcomponents that are part of the
component. If the list of identifiers is not present the identier must not contain a '.'. Each individual
component MUST have a "type" attribute specified that identifies the component's Plugin type.
As of version 2.6, this list of identifiers is no longer required as names are inferred upon first usage,
however if you wish to use more complex identifies you must still use the list. If the list is present it
will be used.
Unlike the base components, when creating subcomponents you cannot specify an element containing
a list of identifiers. Instead, you must define the wrapper element with its type as is shown in the
policies definition in the rolling file appender below. You then define each of the subcomponents
below that wrapper element, as the TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are
defined below.
Properties configuration files support the advertiser, monitorInterval, name, packages,
shutdownHook, shutdownTimeout, status, verbose, and dest attrbutes. See Configuration Syntax for
the definitions of these attributes.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

36

status = error
dest = err
name = PropertiesConfig
property.filename = target/rolling/rollingtest.log
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appender.console.type = Console
appender.console.name = STDOUT
appender.console.layout.type = PatternLayout
appender.console.layout.pattern = %m%n
appender.console.filter.threshold.type = ThresholdFilter
appender.console.filter.threshold.level = error
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 2
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=100MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 5
logger.rolling.name = com.example.my.app
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
rootLogger.level = info
rootLogger.appenderRef.stdout.ref = STDOUT

5.1.6 Property Substitution

Log4j 2 supports the ability to specify tokens in the configuration as references to properties defined
elsewhere. Some of these properties will be resolved when the configuration file is interpreted while
others may be passed to components where they will be evaluated at runtime. To accomplish this,
Log4j uses variations of Apache Commons Lang's StrSubstitutor and StrLookup classes. In a
manner similar to Ant or Maven, this allows variables declared as ${name} to be resolved using
properties declared in the configuration itself. For example, the following example shows the filename
for the rolling file appender being declared as a property.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

37




target/rolling1/rollingtest-$${sd:type}.log












%d %p %c{1.} [%t] %m%n


















While this is useful, there are many more places properties can originate from. To accommodate this,
Log4j also supports the syntax ${prefix:name} where the prefix identifies tells Log4j that variable
name should be evaluated in a specific context. See the Lookups manual page for more details. The
contexts that are built in to Logj4 are:
Prefix

Context

bundle

Resource bundle. The format is

${bundle:BundleName:BundleKey}.
The bundle name follows package
naming conventions, for example:

${bundle:com.domain.Messages:MyKey}.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

38

ctx

Thread Context Map (MDC)

date

Inserts the current date and/or time using the specified
format

env

System environment variables. The formats are
${env:ENV_NAME} and ${env:ENV_NAME:default_value}.

jndi

A value set in the default JNDI Context.

jvmrunargs

A JVM input argument accessed through
JMX, but not a main argument; see
RuntimeMXBean.getInputArguments(). Not available
on Android.

log4j

Log4j configuration properties. The expressions
${log4j:configLocation} and

${log4j:configParentLocation}
respectively provide the absolute path to the log4j
configuration file and its parent folder.
main

A value set with
MapLookup.setMainArguments(String[])

map

A value from a MapMessage

sd

A value from a StructuredDataMessage. The key "id"
will return the name of the StructuredDataId without
the enterprise number. The key "type" will return the
message type. Other keys will retrieve individual
elements from the Map.

sys

System properties. The formats are
${sys:some.property} and

${sys:some.property:-default_value}.

A default property map can be declared in the configuration file. If the value cannot be located in
the specified lookup the value in the default property map will be used. The default map is prepopulated with a value for "hostName" that is the current system's host name or IP address and the
"contextName" with is the value of the current logging context.

5.1.7 Lookup Variables with Multiple Leading '$' Characters

An interesting feature of StrLookup processing is that when a variable reference is declared with
multiple leading '$' characters each time the variable is resolved the leading '$' is simply removed. In
the previous example the "Routes" element is capable of resolving the variable at runtime. To allow
this the prefix value is specified as a variable with two leading '$' characters. When the configuration
file is first processed the first '$' character is simply removed. Thus, when the Routes element is
evaluated at runtime it is the variable declaration "${sd:type}" which causes the event to be inspected
for a StructuredDataMessage and if one is present the value of its type attribute to be used as the
routing key. Not all elements support resolving variables at runtime. Components that do will
specifically call that out in their documentation.
If no value is found for the key in the Lookup associated with the prefix then the value associated
with the key in the properties declaration in the configuration file will be used. If no value is found the
variable declaration will be returned as the value. Default values may be declared in the configuration
by doing:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

39




Audit

...


As a footnote, it is worth pointing out that the variables in the RollingFile appender declaration will
also not be evaluated when the configuration is processed. This is simply because the resolution
of the whole RollingFile element is deferred until a match occurs. See RoutingAppender for more
information.

5.1.8 Scripts

Log4j provides support for JSR 223 scripting languages to be used in some of its components.
Any language that provides support for the JSR 223 scripting engine may be used. A list of the
languages and bindings for them can be found at the Scripting Engine web site. However, some of
the languages listed there, such as JavaScript, Groovy and Beanshell, directly support the JSR 223
scripting framework and only require that the jars for that language be installed.
The components that support using scripts do so by allowing a 




























©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

41

If the status attribute on the Configuration element is set to DEBUG the list of script engines currently
installed and their attributes will be listed. Although some engines may say they are not thread safe,
Log4j takes steps to insure that the scripts will run in a thread-safe manner if the engine advertises
that it is not thread safe.

2015-09-27 16:13:22,925 main DEBUG Installed script engines
2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thre
Compile: false, Names: {AppleScriptEngine, AppleScript, OSA}
2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITH
Compile: true, Names: {groovy, Groovy}

2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREAD
Compile: true, Names: {beanshell, bsh, java}
2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Thr
Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript}

When the scripts are executed they will be provided with a set of variables that should allow them
to accomplish whatever task they are expected to perform. See the documentation for the individual
components for the list of variables that are available to the script.
The components that support scripting expect a return value to be passed back to the calling Java
code. This is not a problem for several of the scripting languages, but Javascript does not allow a
return statement unless it is within a function. However, Javascript will return the value of the last
statement executed in the script. As a consequence, code such as that shown below will result in the
desired behavior.
var result;
if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
result = "NoLocation";
} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
result = "Flow";
}
result;

5.1.8.1 A special note on Beanshell

JSR 223 scripting engines are supposed to identify that they support the Compilable interface if they
support compiling their scripts. Beanshell does this. However, whenever the compile method is called
it throws an Error (not an Exception). Log4j catches this but will log the warning shown below for
each Beanshell script when it tries to compile them. All Beanshell scripts will then be interpreted on
each execution.

2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable
2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented
at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175)
at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154)
at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.(ScriptManager.java:
at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94)

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

5.1.9 XInclude

XML configuration files can include other files with XInclude. Here is an example log4j2.xml file
that includes two other files:



xinclude-demo.log






log4j-xinclude-appenders.xml:







%d %p %C{1.} [%t] %m%n




log4j-xinclude-loggers.xml:
















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

42

5 Configuration

43

5.1.10 Composite Configuration

Log4j allows multiple configuration files to be used by specifying them as a list of comma separated
file paths on log4j.configurationFile. The merge logic can be controlled by specifying a class that
implements the MergeStrategy interface on the log4j.mergeStrategy property. The default merge
strategy will merge the files using the following rules:
1. The global configuration attributes are aggregated with those in later configurations replacing
those in previous configurations, with the exception that the highest status level and the lowest
monitorInterval greater than 0 will be used.
2. Properties from all configurations are aggregated. Duplicate properties replace those in previous
configurations.
3. Filters are aggregated under a CompositeFilter if more than one Filter is defined. Since Filters
are not named duplicates may be present.
4. Scripts and ScriptFile references are aggregated. Duplicate definiations replace those in previous
configurations.
5. Appenders are aggregated. Appenders with the same name are replaced by those in later
configurations, including all of the Appender's subcomponents.
6. Loggers are all aggregated. Logger attributes are individually merged with duplicates being
replaced by those in later configurations. Appender references on a Logger are aggregated with
duplicates being replaced by those in later configurations. Filters on a Logger are aggregated
under a CompositeFilter if more than one Filter is defined. Since Filters are not named duplicates
may be present. Filters under Appender references included or discarded depending on whether
their parent Appender reference is kept or discarded.

5.1.11 Status Messages
Troubleshooting tip for the impatient:

From log4j-2.9 onward, log4j2 will print all internal logging to the console if system property
log4j2.debug is defined (with any or no value).
Prior to log4j-2.9, there are two places where internal logging can be controlled:
• Before a configuration is found, status logger level can be controlled with system property
org.apache.logging.log4j.simplelog.StatusLogger.level.
• After a configuration is found, status logger level can be controlled in the configuration file with the "status"
attribute, for example: .

Just as it is desirable to be able to diagnose problems in applications, it is frequently necessary to
be able to diagnose problems in the logging configuration or in the configured components. Since
logging has not been configured, "normal" logging cannot be used during initialization. In addition,
normal logging within appenders could create infinite recursion which Log4j will detect and cause the
recursive events to be ignored. To accomodate this need, the Log4j 2 API includes a StatusLogger.
Components declare an instance of the StatusLogger similar to:
protected final static Logger logger = StatusLogger.getLogger();

Since StatusLogger implements the Log4j 2 API's Logger interface, all the normal Logger methods
may be used.
When configuring Log4j it is sometimes necessary to view the generated status events. This can
be accomplished by adding the status attribute to the configuration element or a default value can
be provided by setting the "Log4jDefaultStatusLevel" system property. Valid values of the status

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

44

attribute are "trace", "debug", "info", "warn", "error" and "fatal". The following configuration has the
status attribute set to debug.



target/rolling1/rollingtest-$${sd:type}.log












%d %p %c{1.} [%t] %m%n


















During startup this configuration produces:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

45

2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds
2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.
config.Property for element property with params(name="filename",
value="target/rolling1/rollingtest-${sd:type}.log")
2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.
core.config.plugins.PropertiesPlugin for element properties with
params(properties={filename=target/rolling1/rollingtest-${sd:type}.log})
2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds
2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.
filter.ThresholdFilter for element ThresholdFilter with params(level="debug",
onMatch="null", onMismatch="null")
2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.
layout.PatternLayout for element PatternLayout with params(pattern="%m%n",
Configuration(RoutingTest), null, charset="null")
2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds
2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.
appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null,
target="null", name="STDOUT", ignoreExceptions="null")
2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.
filter.ThresholdFilter for element ThresholdFilter with params(level="debug",
onMatch="null", onMismatch="null")
2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.
routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route)
2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.
routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route)
2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.
routing.Routes for element Routes with params(pattern="${sd:type}",
routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit'))})
2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.
routing.RoutingAppender for element Routing with params(name="Routing",
ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static
Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null)
2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.
plugins.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing})
2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.
config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing")
2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.
LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger",
AppenderRef={Routing}, null)
2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.
config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT")

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

46

2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.
LoggerConfig$RootLogger for element root with params(additivity="null", level="error",
AppenderRef={STDOUT}, null)
2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.
config.plugins.LoggersPlugin for element loggers with params(loggers={EventLogger, root})
2011-11-23 17:08:00,834 DEBUG Reconfiguration completed
2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.
layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n",
Configuration(RoutingTest), null, charset="null")
2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.
appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with
params(size="500")
2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.
appender.RollingFileAppender for element RollingFile with
params(fileName="target/rolling1/rollingtest-Unknown.log",
filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown",
bufferedIO="null", immediateFlush="null",
SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null,
PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null")
2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds
2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.
Launcher$AppClassLoader@37b90b39
2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds
2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds
2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds
2011-11-23 17:08:00,965 WARN No Loggers were configured, using default
2011-11-23 17:08:00,976 DEBUG Reconfiguration completed

If the status attribute is set to error than only error messages will be written to the console. This makes
troubleshooting configuration errors possible. As an example, if the configuration above is changed to
have the status set to error and the logger declaration is:




the following error message will be produced.
2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger

Applications may wish to direct the status output to some other destination. This can be accomplished
by setting the dest attribute to either "err" to send the output to stderr or to a file location or URL. This
can also be done by insuring the configured status is set to OFF and then configuring the application
programmatically such as:
StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
StatusLogger.getLogger().registerListener(listener);

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

47

5.1.12 Testing in Maven

Maven can run unit and functional tests during the build cycle. By default, any files placed in src/
test/resources are automatically copied to target/test-classes and are included in the classpath
during execution of any tests. As such, placing a log4j2-test.xml into this directory will cause it to be
used instead of a log4j2.xml or log4j2.json that might be present. Thus a different log configuration
can be used during testing than what is used in production.
A second approach, which is extensively used by Log4j 2, is to set the log4j.configurationFile
property in the method annotated with @BeforeClass in the junit test class. This will allow an
arbitrarily named file to be used during the test.
A third approach, also used extensively by Log4j 2, is to use the LoggerContextRule JUnit test
rule which provides additional convenience methods for testing. This requires adding the log4jcore test-jar dependency to your test scope dependencies. For example:
public class AwesomeTest {
@Rule
public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml");
@Test
public void testSomeAwesomeFeature() {
final LoggerContext ctx = init.getContext();
final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger");
final Configuration cfg = init.getConfiguration();
final ListAppender app = init.getListAppender("List");
logger.warn("Test message");
final List events = app.getEvents();
// etc.
}
}

5.1.13 System Properties

The Log4j documentation references a number of System Properties that can be used to control
various aspects of Log4j 2 behavior. The table below lists these properties along with their default
value and a description of what they control. Any spaces present in the property name are for visual
flow and should be removed.
Note that beginning in Log4j 2.10, all system property names have been normalized to follow
a consistent naming scheme. While the old property names are still supported for backwards
compatibility, it is recommended to update configurations to use the new style. This system is
extensible and is enabled through the PropertySource interface. Additional property source classes
can be added through the standard ServiceLoader mechanism in Java SE.
Properties can be overridden by sources with a lower number priority (e.g.., -100 comes before 100).
The following sources are all available by default:
Source

Priority

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

Environment Variables

48

-100

Environment variables are all
prefixed with LOG4J_, are in all
caps, and words are all separated
by underscores. Only this naming
scheme is support for environment
variables as there were no old
naming schemes to maintain
compatibility with.

log4j2.component.properties
0

Including this file on the classpath
can be used as an alternative to
providing properties as system
properties. This has priority over
system properties, but they can
be overridden by environment
variables as described above.

file

System Properties

100

All properties can be set using
normal system property patterns.
These have the lowest priority and
can be overridden by included
properties files or environment
variables.

PropertySource priorities and descriptions
The following is a list of available global configuration properties. Note that these can only be set
once per JVM process unlike configuration settings available in configuration files. The Property
Name column contains the name used in properties files and system properties; Environemt Variable
for the equivalent environment variable; and Legacy Property Name for the pre-2.10 name.
* { // this works for all but td word-wrap:break-word; } table { // this somehow makes it work for td
table-layout:fixed; width:100%; }
Property Name
(Legacy Property
Name)

Environment Variable

Default Value

Description

log4j2.configurationFile
( log4j.configurationFile)

LOG4J_CONFIGURATION_FILE

Path to an Log4j 2
configuration file.
May also contain a
comma separated list of
configuration file names.

log4j2.debug
( log4j2.debug)

LOG4J_DEBUG

Log4j2 will print all
internal logging to the
console if system property
log4j2.debug is
defined (with any or no
value).

log4j2.mergeFactory
( log4j.mergeFactory)

LOG4J_MERGE_FACTORY

The name of the
class that implements
the MergeStrategy
interface. If not specified

DefaultMergeStrategy
will be used
when creating a
CompositeConfiguration..

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

log4j2.contextSelector
( Log4jContextSelector)

49

LOG4J_CONTEXT_SELECTOR
ClassLoaderContextSelectorCreates the

LoggerContexts.
An application can
have one or more
active LoggerContexts
depending on the
circumstances. See
Log Separation for more
details. Available context
selector implementation
classes:

org.apache.logging.log4j.core.a
- makes all loggers
asynchronous.

org.apache.logging.log4j.core.s
- creates a single shared
LoggerContext.

org.apache.logging.log4j.core.s
- separate
LoggerContexts for each
web application.

org.apache.logging.log4j.core.s
- use JNDI to locate
each web application's
LoggerContext.

org.apache.logging.log4j.core.o
- separate
LoggerContexts for each
OSGi bundle.
log4j2.logEventFactory
( Log4jLogEventFactory)

LOG4J_LOG_EVENT_FACTORY
org.apache.logging.log4j.core.impl
Factory.DefaultLogEventFactory
class used by
LoggerConfig to create
LogEvent instances.
(Ignored when the

AsyncLoggerContextSelector
is used.)
log4j2.loggerContextFactory LOG4J_LOGGER_CONTEXT_FACTORY
org.apache.logging.log4j.simple
Factory
.SimpleLoggerContextFactory
class used
(
by LogManager to
log4j2.loggerContextFactory)
bootstrap the logging
implementation. The
core jar provides

org.apache.logging.log4j.core .
log4j2.configurationFactory LOG4J_CONFIGURATION_FACTORY
(
log4j.configurationFactory)

Fully specified class
name of a class extending

org.apache.logging.log4j.core .
If specified, an instance
of this class is added to
the list of configuration
factories.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

50

log4j2.shutdownHookEnabled
LOG4J_SHUTDOWN_HOOK_ENABLED
true
(
log4j.shutdownHookEnabled)

Overrides the global
flag for whether or
not a shutdown hook
should be used to stop a
LoggerContext. By
default, this is enabled
and can be disabled on a
per-configuration basis.
When running with the
log4j-web module, this
is automatically disabled.

log4j2.shutdownCallbackRegistry
LOG4J_SHUTDOWN_CALLBACK_REGISTRY
org.apache.logging.log4j.core.util
Fully specified
.DefaultShutdownCallbackRegistry
class name
(
of a class implementing
log4j.shutdownCallbackRegistry)
ShutdownCallbackRegistry.
If specified, an
instance of this class
is used instead of

DefaultShutdownCallbackRegistry
The specified class
must have a default
constructor.
log4j2.clock
( log4j.Clock)

LOG4J_CLOCK

SystemClock

Implementation of the

org.apache.logging.log4j .core.
interface that is used
for timestamping the log
events.
By default,

System.currentTimeMillis
is called on every log
event.
You can also specify a
fully qualified class name
of a custom class that
implements the Clock
interface.
log4j2.level
LOG4J_LEVEL
(
org.apache.logging.log4j.level)

ERROR

Log level of the default
configuration. The default
configuration is used if
the ConfigurationFactory
could not successfully
create a configuration
(e.g. no log4j2.xml file
was found).

log4j2.disableThreadContextLOG4J_DISABLE_THREAD_CONTEXT
false
(disableThreadContext)

If true, the
ThreadContext stack and
map are disabled. (May
be ignored if a custom
ThreadContext map is
specified.)

log4j2.disableThreadContextStack
LOG4J_DISABLE_THREAD_CONTEXT_STACK
false
(disableThreadContextStack)

If true, the
ThreadContext stack is
disabled.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

51

log4j2.disableThreadContextMap
LOG4J_DISABLE_THREAD_CONTEXT_MAP
false
(disableThreadContextMap)

If true, the
ThreadContext map
is disabled. (May be
ignored if a custom
ThreadContext map is
specified.)

log4j2.threadContextMap LOG4J_THREAD_CONTEXT_MAP
(log4j2.threadContextMap)

Fully specified class
name of a custom

ThreadContextMap
implementation class.
log4j2.isThreadContextMapInheritable
LOG4J_IS_THREAD_CONTEXT_MAP_INHERITABLE
false
If true use a
(isThreadContextMapInheritable)
InheritableThreadLocal
to implement the
ThreadContext map.
Otherwise, use a plain
ThreadLocal. (May
be ignored if a custom
ThreadContext map is
specified.)
log4j2.contextDataInjector LOG4J_CONTEXT_DATA_INJECTOR
(
log4j2.ContextDataInjector)

Fully specified class
name of a custom

ContextDataInjector
implementation class.

log4j2.garbagefreeThreadContextMap
LOG4J_GARBAGEFREE_THREAD_CONTEXT_MAP
false
(
log4j2.garbagefree.threadContextMap)

Specify "true" to make
the ThreadContext map
garbage-free.

log4j2.disableJmx
( log4j2.disable.jmx)

LOG4J_DISABLE_JMX

If true, Log4j
configuration objects
like LoggerContexts,
Appenders, Loggers, etc.
will not be instrumented
with MBeans and cannot
be remotely monitored
and managed.

log4j2.jmxNotifyAsync
( log4j2.jmx.notify.async)

LOG4J_JMX_NOTIFY_ASYNC
false for web apps, true
otherwise

false

If true, log4j's JMX
notifications are sent from
a separate background
thread, otherwise they
are sent from the caller
thread. If system property

log4j2.is.webapp
is true or the
javax.servlet.Servlet
class is on the classpath,
the default behaviour is
to use the caller thread to
send JMX notifications.
log4j2.skipJansi
( log4j.skipJansi)

LOG4J_SKIP_JANSI

true

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

If true, the
ConsoleAppender will not
try to use the Jansi output
stream on Windows.

5 Configuration

log4j2.ignoreTCL
( log4j.ignoreTCL)

52

LOG4J_IGNORE_TCL

false

If true, classes are only
loaded with the default
class loader. Otherwise,
an attempt is made to
load classes with the
current thread's context
class loader before falling
back to the default class
loader.

log4j2.uuidSequence
LOG4J_UUID_SEQUENCE 0
(
org.apache.logging.log4j.uuidSequence)

System property that may
be used to seed the UUID
generation with an integer
value.

log4j2.simplelogShowContextMap
LOG4J_SIMPLELOG_SHOW_CONTEXT_MAP
false
(
org.apache.logging.log4j .simplelog.showContextMap)

If true, the full
ThreadContext map
is included in each
SimpleLogger log
message.

log4j2.simplelogShowlogname
LOG4J_SIMPLELOG_SHOWLOGNAME
false
(
org.apache.logging.log4j .simplelog.showlogname)

If true, the logger
name is included in
each SimpleLogger log
message.

log4j2.simplelogShowShortLogname
LOG4J_SIMPLELOG_SHOW_SHORT_LOGNAME
true
(
org.apache.logging.log4j .simplelog.showShortLogname)

If true, only the last
component of a logger
name is included in
SimpleLogger log
messages. (E.g., if
the logger name is
"mycompany.myproject.mycomponent",
only "mycomponent" is
logged.

log4j2.simplelogShowdatetime
LOG4J_SIMPLELOG_SHOWDATETIME
false
(
org.apache.logging.log4j .simplelog.showdatetime)

If true, SimpleLogger
log messages contain
timestamp information.

log4j2.simplelogDateTimeFormat
LOG4J_SIMPLELOG_DATE_TIME_FORMAT
"yyyy/MM/dd
(
HH:mm:ss:SSS zzz"
org.apache.logging.log4j .simplelog.dateTimeFormat)

Date-time format
to use. Ignored if

log4j2.simplelogLogFile
LOG4J_SIMPLELOG_LOG_FILE
system.err
(
org.apache.logging.log4j .simplelog.logFile)

"system.err" (caseinsensitive) logs
to System.err,
"system.out" (caseinsensitive) logs to
System.out, any other
value is interpreted
as a file name to save
SimpleLogger messages
to.

log4j2.simplelogLevel
LOG4J_SIMPLELOG_LEVEL
ERROR
(
org.apache.logging.log4j .simplelog.level)

Default level for new
SimpleLogger instances.

log4j2.simplelog..level
LOG4J_SIMPLELOG__LEVEL
SimpleLogger default log
(
level
org.apache.logging.log4j .simplelog..level)

Log level for a the
SimpleLogger instance
with the specified name.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

org.apache.logging.log4j .simpl
is false.

5 Configuration

53

log4j2.simplelogStatusLoggerLevel
LOG4J_SIMPLELOG_STATUS_LOGGER_LEVEL
ERROR
(
org.apache.logging.log4j.simplelog .StatusLogger.level)

This property is used
to control the initial
StatusLogger level,
and can be overridden
in code by calling

StatusLogger.getLogger() .setLe
Note that the
StatusLogger level is
only used to determine
the status log output
level until a listener is
registered. In practice,
a listener is registered
when a configuration
is found, and from that
point onwards, status
messages are only sent to
the listeners (depending
on their statusLevel).
log4j2.defaultStatusLevel
(
Log4jDefaultStatusLevel)

LOG4J_DEFAULT_STATUS_LEVEL
ERROR

The StatusLogger
logs events that
occur in the logging
system to the console.
During configuration,
AbstractConfiguration
registers a
StatusConsoleListener
with the StatusLogger
that may redirect
status log events from
the default console
output to a file. The
listener also supports
fine-grained filtering.
This system property
specifies the default
status log level for the
listener to use if the
configuration does not
specify a status level.
Note: this property is
used by the log4j-core
implementation only
after a configuration
file has been found.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

54

log4j2.statusLoggerLevel LOG4J_STATUS_LOGGER_LEVEL
WARN
(
log4j2.StatusLogger.level)

The initial
"listenersLevel" of
the StatusLogger.
If StatusLogger
listeners are added,
the "listenerLevel"
is changed to that
of the most verbose
listener. If any listeners
are registered, the
listenerLevel is used
to quickly determine
if an interested listener
exists.
By default,
StatusLogger listeners
are added when a
configuration is found
and by the JMX
StatusLoggerAdmin
MBean. For
example, if a
configuration contains
,

a listener with
statusLevel TRACE
is registered and
the StatusLogger
listenerLevel is set
to TRACE, resulting
in verbose status
messages displayed on
the console.
If no listeners are
registered, the
listenersLevel is
not used, and the
StatusLogger output
level is determined by

StatusLogger.getLogger().getLev

(see property

org.apache.logging.log4j.simple
log4j2.statusEntries
( log4j2.status.entries)

LOG4J_STATUS_ENTRIES200

Number of StatusLogger
events that are kept
in a buffer and can
be retrieved with

StatusLogger.getStatusData().

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

55

log4j2.statusLoggerDateformat
LOG4J_STATUS_LOGGER_DATEFORMAT
(
log4j2.StatusLogger.DateFormat)

Date-time format string
to use as the format
for timestamps in the
status logger output. See

java.text.SimpleDateFormat
for supported formats.
log4j2.asyncLoggerExceptionHandler
LOG4J_ASYNC_LOGGER_EXCEPTION_HANDLER
default handler
(
AsyncLogger.ExceptionHandler)

See Async Logger
System Properties for
details.

log4j2.asyncLoggerRingBufferSize
LOG4J_ASYNC_LOGGER_RING_BUFFER_SIZE
256 * 1024
(
AsyncLogger.RingBufferSize)

See Async Logger
System Properties for
details.

log4j2.asyncLoggerWaitStrategy
LOG4J_ASYNC_LOGGER_WAIT_STRATEGY
Timeout
(
AsyncLogger.WaitStrategy)

See Async Logger
System Properties for
details.

log4j2.asyncLoggerThreadNameStrategy
LOG4J_ASYNC_LOGGER_THREAD_NAME_STRATEGY
CACHED
See Async Logger
(
System Properties for
AsyncLogger.ThreadNameStrategy)
details.
log4j2.asyncLoggerConfigExceptionHandler
LOG4J_ASYNC_LOGGER_CONFIG_EXCEPTION_HANDLER
default handler
See Mixed Async/
(
Synchronous Logger
AsyncLoggerConfig.ExceptionHandler)
System Properties for
details.
log4j2.asyncLoggerConfigRingBufferSize
LOG4J_ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE
256 * 1024
See Mixed Async/
(
Synchronous Logger
AsyncLoggerConfig.RingBufferSize)
System Properties for
details.
log4j2.asyncLoggerConfigWaitStrategy
LOG4J_ASYNC_LOGGER_CONFIG_WAIT_STRATEGY
Timeout
See Mixed Async/
(
Synchronous Logger
AsyncLoggerConfig.WaitStrategy)
System Properties for
details.
log4j2.julLoggerAdapter
( log4j.jul.LoggerAdapter)

LOG4J_JUL_LOGGER_ADAPTER
org.apache.logging.log4j .jul.ApiLoggerAdapter
Default LoggerAdapter to
use in the JUL adapter.
By default, if log4j-core is
available, then the class

org.apache.logging.log4j.jul .C
will be used.
Otherwise, the

ApiLogggerAdapter
will be used. Custom
implementations must
provide a public default
constructor.
log4j2.formatMsgAsync
( log4j.format.msg.async)

LOG4J_FORMAT_MSG_ASYNC
false

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

If false (the default),
Log4j will make sure the
message is formatted
in the caller thread, to
ensure the value at the
time of the call to the
logger is the value that is
logged.

5 Configuration

56

log4j2.asyncQueueFullPolicyLOG4J_ASYNC_QUEUE_FULL_POLICY
(
log4j2.AsyncQueueFullPolicy)

Used by Async
Loggers and the
AsyncAppender to
maintain application
throughput even
when the underlying
appender cannot keep
up with the logging rate
and the queue is filling
up.
If no value is specified
(the default) events are
never discarded. If the
queue is full, the logger
call blocks until the
event can be added to
the queue.
Specify Discard to
drop events whose
level is equal or less
than the threshold level
(INFO by default)
when the queue is full.

log4j2.discardThreshold
(
log4j2.DiscardThreshold)

LOG4J_DISCARD_THRESHOLD
INFO

Used by the
DiscardingAsyncQueueFullPolicy
to determine which
events to drop when
the queue becomes
full. By default, INFO,
DEBUG and TRACE level
events are discarded
when the queue is full.
This property only has
effect if Discard
is specified as the

log4j2.AsyncQueueFullPolicy.
log4j2.messageFactory
( log4j2.messageFactory)

LOG4J_MESSAGE_FACTORY
org.apache.logging.log4j.message.
Default message factory
ParameterizedMessageFactory
used by Loggers if no
or
factory was specified.
org.apache.logging.log4j.message.
ReusableMessageFactory
in garbage-free mode

log4j2.flowMessageFactory LOG4J_FLOW_MESSAGE_FACTORY
org.apache.logging.log4j.message.
Default flow message
(
DefaultFlowMessageFactoryfactory used by Loggers.
log4j2.flowMessageFactory)
log4j2.isWebapp
( log4j2.is.webapp)

LOG4J_IS_WEBAPP

true if Servlet class on
class path

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

This system property can
be used to force Log4j 2
to behave as if it is part of
a web application (when
true) or as if it is not part
of a web application
(when false).

5 Configuration

57

log4j2.enableThreadlocals LOG4J_ENABLE_THREADLOCALS
true
(
log4j2.enable.threadlocals)

This system property can
be used to switch off the
use of threadlocals, which
will partly disable Log4j's
garbage-free behaviour:
to be fully garbage-free,
Log4j stores objects in
ThreadLocal fields to
reuse them, otherwise
new objects are created
for each log event. Note
that this property is not
effective when Log4j
detects it is running in a
web application.

log4j2.enableDirectEncodersLOG4J_ENABLE_DIRECT_ENCODERS
true
(
log4j2.enable.direct.encoders)

This property can be
used to force garbageaware Layouts and
Appenders to revert to
the pre-2.6 behaviour
where converting log
events to text generates
temporary objects like
Strings and char[] arrays,
and converting this
text to bytes generates
temporary byte[] arrays.
By default, this property is
true and garbage-aware
Layouts and Appenders
that convert log events to
text will convert this text
to bytes without creating
temporary objects.

log4j2.initialReusableMsgSize
LOG4J_INITIAL_REUSABLE_MSG_SIZE
128
(
log4j.initialReusableMsgSize)

In GC-free mode, this
property determines the
initial size of the reusable
StringBuilders where the
message text is formatted
and potentially passed to
background threads.

log4j2.maxReusableMsgSizeLOG4J_MAX_REUSABLE_MSG_SIZE
518
(
log4j.maxReusableMsgSize)

In GC-free mode, this
property determines the
maximum size of the
reusable StringBuilders
where the message text is
formatted and potentially
passed to background
threads.

log4j2.layoutStringBuilderMaxSize
LOG4J_LAYOUT_STRING_BUILDER_MAX_SIZE
2048
(
log4j.layoutStringBuilder.maxSize)

This property determines
the maximum size
of the thread-local
reusable StringBuilders
used to format the
log event to text by
Layouts that extend
AbstractStringLayout.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

5 Configuration

58

log4j2.unboxRingbufferSize LOG4J_UNBOX_RINGBUFFER_SIZE
32
(
log4j.unbox.ringbuffer.size)

The

org.apache.logging.log4j.util.U
utility manages a small
thread-local ring buffer
of StringBuilders. Each
time one of the box()
methods is called, the
next slot in the ring buffer
is used, until the ring
buffer is full and the first
slot is reused. By default
the Unbox ring buffer has
32 slots, so user code
can have up to 32 boxed
primitives in a single
logger call.

If more slots
are required, set
system property
log4j.unbox.ringbuffer.size

to the desired ring
buffer size. Note that
the specified number
will be rounded up to
the nearest power of 2.
log4j2.loggerContextStacktraceOnStart
LOG4J_LOGGER_CONTEXT_STACKTRACE_ON_START
false
Prints a stacktrace to
(
the status logger at
log4j.LoggerContext.stacktrace.on.start)
DEBUG level when the
LoggerContext is started.
For debug purposes.
log4j2.formatMsgNoLookupsFORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
false
Disables message pattern
(
lookups globally when
log4j2.formatMsgNoLookups)
set to true. This is
equivalent to defining all
message patterns using
%m{nolookups}.

Log4j 2 global configuration properties

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

6 Web Applications and JSPs

59

6 Web Applications and JSPs

.......................................................................................................................................
6.1 Using Log4j 2 in Web Applications
You must take particular care when using Log4j or any other logging framework within a Java EE
web application. It's important for logging resources to be properly cleaned up (database connections
closed, files closed, etc.) when the container shuts down or the web application is undeployed.
Because of the nature of class loaders within web applications, Log4j resources cannot be cleaned up
through normal means. Log4j must be "started" when the web application deploys and "shut down"
when the web application undeploys. How this works varies depending on whether your application is
a Servlet 3.0 or newer or Servlet 2.5 web application.
In either case, you'll need to add the log4j-web module to your deployment as detailed in the
Maven, Ivy, and Gradle Artifacts manual page.
To avoid problems the Log4j shutdown hook will automatically be disabled when the log4j-web jar is
included.

6.1.1 Configuration

Log4j allows the configuration file to be specified in web.xml using the log4jConfiguration
context parameter. Log4j will search for configuration files by:
1. If a location is provided it will be searched for as a servlet context resource. For example, if
log4jConfiguration contains "logging.xml" then Log4j will look for a file with that name in
the root directory of the web application.
2. If no location is defined Log4j will search for a file that starts with "log4j2" in the WEB-INF
directory. If more than one file is found, and if a file that starts with "log4j2-name" is present,
where name is the name of the web application, then it will be used. Otherwise the first file will
be used.
3. The "normal" search sequence using the classpath and file URLs will be used to locate the
configuration file.
6.1.2 Servlet 3.0 and Newer Web Applications

A Servlet 3.0 or newer web application is any  whose version attribute has a value
of "3.0" or higher. Of course, the application must also be running in a compatible web container.
Some examples are: Tomcat 7.0 and higher, GlassFish 3.0 and higher, JBoss 7.0 and higher, Oracle
WebLogic 12c and higher, and IBM WebSphere 8.0 and higher.
6.1.2.1 The Short Story

Log4j 2 "just works" in Servlet 3.0 and newer web applications. It is capable of automatically
starting when the application deploys and shutting down when the application undeploys.
Thanks to the ServletContainerInitializer API added to Servlet 3.0, the relevant Filter and
ServletContextListener classes can be registered dynamically on web application startup.
Important Note! For performance reasons, containers often ignore certain JARs known not to
contain TLDs or ServletContainerInitializers and do not scan them for web-fragments and
initializers. Importantly, Tomcat 7 <7.0.43 ignores all JAR files named log4j*.jar, which prevents this
feature from working. This has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 <7.0.43
you will need to change catalina.properties and remove "log4j*.jar" from the jarsToSkip

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

6 Web Applications and JSPs

60

property. You may need to do something similar on other containers if they skip scanning Log4j JAR
files.
6.1.2.2 The Long Story

The Log4j 2 Web JAR file is a web-fragment configured to order before any other web
fragments in your application. It contains a ServletContainerInitializer (
Log4jServletContainerInitializer) that the container automatically discovers and initializes. This adds
the Log4jServletContextListener and Log4jServletFilter to the ServletContext. These classes
properly initialize and deinitialize the Log4j configuration.
For some users, automatically starting Log4j is problematic or undesirable. You can easily disable
this feature using the isLog4jAutoInitializationDisabled context parameter. Simply add it
to your deployment descriptor with the value "true" to disable auto-initialization. You must define the
context parameter in web.xml. If you set in programmatically, it will be too late for Log4j to detect
the setting.

isLog4jAutoInitializationDisabled
true


Once you disable auto-initialization, you must initialize Log4j as you would a Servlet 2.5 web
application. You must do so in a way that this initialization happens before any other application code
(such as Spring Framework startup code) executes.
You can customize the behavior of the listener and filter using the log4jContextName,
log4jConfiguration, and/or isLog4jContextSelectorNamed context parameters. Read
more about this in the Context Parameters section below. You must not manually configure the
Log4jServletContextListener or Log4jServletFilter in your deployment descriptor (
web.xml) or in another initializer or listener in a Servlet 3.0 or newer application unless you disable
auto-initialization with isLog4jAutoInitializationDisabled. Doing so will result in startup
errors and unspecified erroneous behavior.
6.1.3 Servlet 2.5 Web Applications

A Servlet 2.5 web application is any  whose version attribute has a value of "2.5." The
version attribute is the only thing that matters; even if the web application is running in a Servlet
3.0 or newer container, it is a Servlet 2.5 web application if the version attribute is "2.5." Note that
Log4j 2 does not support Servlet 2.4 and older web applications.
If you are using Log4j in a Servlet 2.5 web application, or if you have disabled auto-initialization
with the isLog4jAutoInitializationDisabled context parameter, you must configure
the Log4jServletContextListener and Log4jServletFilter in the deployment descriptor or
programmatically. The filter should match all requests of any type. The listener should be the very
first listener defined in your application, and the filter should be the very first filter defined and
mapped in your application. This is easily accomplished using the following web.xml code:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

6 Web Applications and JSPs

61


org.apache.logging.log4j.web.Log4jServletContextListener


log4jServletFilter
org.apache.logging.log4j.web.Log4jServletFilter


log4jServletFilter
/*

REQUEST
FORWARD
INCLUDE
ERROR
ASYNC


©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

116

9.1.12 MemoryMappedFileAppender

New since 2.1. Be aware that this is a new addition, and although it has been tested on several
platforms, it does not have as much track record as the other file appenders.
The MemoryMappedFileAppender maps a part of the specified file into memory and writes log
events to this memory, relying on the operating system's virtual memory manager to synchronize the
changes to the storage device. The main benefit of using memory mapped files is I/O performance.
Instead of making system calls to write to disk, this appender can simply change the program's
local memory, which is orders of magnitude faster. Also, in most operating systems the memory
region mapped actually is the kernel's page cache (file cache), meaning that no copies need to be
created in user space. (TODO: performance tests that compare performance of this appender to
RandomAccessFileAppender and FileAppender.)
There is some overhead with mapping a file region into memory, especially very large regions (half
a gigabyte or more). The default region size is 32 MB, which should strike a reasonable balance
between the frequency and the duration of remap operations. (TODO: performance test remapping
various sizes.)
Similar to the FileAppender and the RandomAccessFileAppender, MemoryMappedFileAppender uses
a MemoryMappedFileManager to actually perform the file I/O. While MemoryMappedFileAppender
from different Configurations cannot be shared, the MemoryMappedFileManagers can be if the
Manager is accessible. For example, two web applications in a servlet container can have their own
configuration and safely write to the same file if Log4j is in a ClassLoader that is common to both of
them.
Parameter Name

Type

Description

append

boolean

When true - the default, records
will be appended to the end of the
file. When set to false, the file will
be cleared before new records are
written.

fileName

String

The name of the file to write to.
If the file, or any of its parent
directories, do not exist, they will be
created.

filters

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

immediateFlush

117

boolean

When set to true, each write
will be followed by a call to
MappedByteBuffer.force().
This will guarantee the data is
written to the storage device.
The default for this parameter is
false. This means that the data
is written to the storage device
even if the Java process crashes,
but there may be data loss if the
operating system crashes.
Note that manually forcing
a sync on every log event
loses most of the performance
benefits of using a memory
mapped file.
Flushing after every write is
only useful when using this
appender with synchronous
loggers. Asynchronous
loggers and appenders will
automatically flush at the end
of a batch of events, even if
immediateFlush is set to false.
This also guarantees the data
is written to disk but is more
efficient.

regionLength

int

The length of the mapped region,
defaults to 32 MB (32 * 1024
* 1024 bytes). This parameter
must be a value between 256 and
1,073,741,824 (1 GB or 2^30);
values outside this range will be
adjusted to the closest valid value.
Log4j will round the specified value
up to the nearest power of two.

layout

Layout

The Layout to use to format the
LogEvent. If no layout is supplied
the default pattern layout of "%m
%n" will be used.

name

String

The name of the Appender.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

MemoryMappedFileAppender Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

118

Here is a sample MemoryMappedFile configuration:





%d %p %c{1.} [%t] %m%n










9.1.13 NoSQLAppender

The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider
interface. Provider implementations currently exist for MongoDB and Apache CouchDB, and writing
a custom provider is quite simple.
Parameter Name

Type

Description

name

String

Required. The name of the
Appender.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

bufferSize

int

If an integer greater than 0, this
causes the appender to buffer log
events and flush whenever the
buffer reaches this size.

NoSqlProvider

NoSQLProvider>>

Required. The NoSQL provider that
provides connections to the chosen
NoSQL database.

NoSQLAppender Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

119

You specify which NoSQL provider to use by specifying the appropriate configuration element within
the  element. The types currently supported are  and . To create
your own custom provider, read the JavaDoc for the NoSQLProvider, NoSQLConnection, and
NoSQLObject classes and the documentation about creating Log4j plugins. We recommend you
review the source code for the MongoDB and CouchDB providers as a guide for creating your own
provider.
The following example demonstrates how log events are persisted in NoSQL databases if represented
in a JSON format:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

120

{
"level": "WARN",
"loggerName": "com.example.application.MyClass",
"message": "Something happened that you might want to know about.",
"source": {
"className": "com.example.application.MyClass",
"methodName": "exampleMethod",
"fileName": "MyClass.java",
"lineNumber": 81
},
"marker": {
"name": "SomeMarker",
"parent" {
"name": "SomeParentMarker"
}

},
"threadName": "Thread-1",
"millis": 1368844166761,
"date": "2013-05-18T02:29:26.761Z",
"thrown": {
"type": "java.sql.SQLException",
"message": "Could not insert record. Connection lost.",
"stackTrace": [
{ "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "file
{ "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fi
{ "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName":
{ "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainCl
],
"cause": {
"type": "java.io.IOException",
"message": "Connection lost.",
"stackTrace": [
{ "className": "java.nio.channels.SocketChannel", "methodName": "write", "fileName": null, "l
{ "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "file
{ "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fi
{ "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName":
{ "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainCl
]
}
},
"contextMap": {
"ID": "86c3a497-4e67-4eed-9d6a-2e5797324d7b",
"username": "JohnDoe"
},
"contextStack": [
"topItem",
"anotherItem",
"bottomItem"
]
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

121

9.1.14 NoSQLAppender for MongoDB

Starting with Log4 2.11.0, we provide two MongoDB modules:
• log4j-mongodb2 defines the configuration element MongoDb2 matching the MongoDB
Driver version 2.
• log4j-mongodb3 defines the configuration element MongoDb3 matching the MongoDB
Driver version 3.
We no longer provide the module log4j-mongodb.
The module log4j-mongodb2 aliases the old configuration element MongoDb to MongoDb2.

9.1.15 NoSQLAppender for MongoDB 2

This section details specializations of the NoSQLAppender provider for MongoDB using the
MongoDB driver version 2. The NoSQLAppender Appender writes log events to a NoSQL database
using an internal lightweight provider interface.
Parameter Name

Type

Description

collectionName

String

Required. The name of the
MongoDB collection to insert the
events into.

writeConcernConstant

Field

By default, the MongoDB provider
inserts records with the instructions

com.mongodb.WriteConcern.ACKNOWLEDGED
Use this optional attribute to specify
the name of a constant other than
ACKNOWLEDGED.
writeConcernConstantClass

Class

If you specify

writeConcernConstant,
you can use this attribute to
specify a class other than

com.mongodb.WriteConcern
to find the constant on (to create
your own custom instructions).
factoryClassName

Class

To provide a connection to
the MongoDB database, you
can use this attribute and
factoryMethodName to specify
a class and static method to get the
connection from. The method must
return a com.mongodb.DB or a
com.mongodb.MongoClient.
If the DB is not authenticated, you
must also specify a username
and password. If you use the
factory method for providing a
connection, you must not specify
the databaseName, server, or
port attributes.

factoryMethodName

Method

See the documentation for attribute
factoryClassName.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

databaseName

122

String

If you do not specify a

factoryClassName and
factoryMethodName for
providing a MongoDB connection,
you must specify a MongoDB
database name using this
attribute. You must also specify
a username and password.
You can optionally also specify a
server (defaults to localhost),
and a port (defaults to the default
MongoDB port).
server

String

See the documentation for attribute
databaseName.

port

int

See the documentation for attribute
databaseName.

username

String

See the documentation for
attributes databaseName and
factoryClassName.

password

String

See the documentation for
attributes databaseName and
factoryClassName.

capped

boolean

Enable support for capped
collections

collectionSize

int

Specify the size in bytes of the
capped collection to use if enabled.
The minimum size is 4096 bytes,
and larger sizes will be increased
to the nearest integer multiple of
256. See the capped collection
documentation linked above for
more information.

MongoDB2 Provider Parameters
This appender is MapMessage-aware.
Here are a few sample configurations for the NoSQLAppender and MongoDB2 provider:














©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

123















Starting in Log4j version 2.11.0, the provider element name is MongoDb2. The name MongoDb is now
a deprecated alias for MongoDb2.

9.1.16 NoSQLAppender for MongoDB 3

This section details specializations of the NoSQLAppender provider for MongoDB using the
MongoDB driver version 3. The NoSQLAppender Appender writes log events to a NoSQL database
using an internal lightweight provider interface.
Parameter Name

Type

Description

collectionName

String

Required. The name of the
MongoDB collection to insert the
events into.

writeConcernConstant

Field

By default, the MongoDB provider
inserts records with the instructions

com.mongodb.WriteConcern.ACKNOWLEDGED
Use this optional attribute to specify
the name of a constant other than
ACKNOWLEDGED.
writeConcernConstantClass

Class

If you specify

writeConcernConstant,
you can use this attribute to
specify a class other than

com.mongodb.WriteConcern
to find the constant on (to create
your own custom instructions).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

factoryClassName

124

Class

To provide a connection to
the MongoDB database, you
can use this attribute and

factoryMethodName
to specify a class and static
method to get the connection
from. The method must return a

com.mongodb.client.MongoDatabase
or a

com.mongodb.MongoClient.
If the

com.mongodb.client.MongoDatabase
is not authenticated, you must
also specify a username and
password. If you use the
factory method for providing a
connection, you must not specify
the databaseName, server, or
port attributes.
factoryMethodName

Method

See the documentation for attribute
factoryClassName.

databaseName

String

If you do not specify a

factoryClassName and
factoryMethodName for
providing a MongoDB connection,
you must specify a MongoDB
database name using this
attribute. You must also specify
a username and password.
You can optionally also specify a
server (defaults to localhost),
and a port (defaults to the default
MongoDB port).
server

String

See the documentation for attribute
databaseName.

port

int

See the documentation for attribute
databaseName.

username

String

See the documentation for
attributes databaseName and
factoryClassName.

password

String

See the documentation for
attributes databaseName and
factoryClassName.

capped

boolean

Enable support for capped
collections

collectionSize

int

Specify the size in bytes of the
capped collection to use if enabled.
The minimum size is 4096 bytes,
and larger sizes will be increased
to the nearest integer multiple of
256. See the capped collection
documentation linked above for
more information.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

125

MongoDB3 Provider Parameters
This appender is MapMessage-aware.
Here are a few sample configurations for the NoSQLAppender and MongoDB3 provider:



























9.1.17 NoSQLAppender for Apache CouchDB

This section details specializations of the NoSQLAppender provider for CouchDB. The
NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider
interface.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

factoryClassName

126

Class

To provide a connection to
the CouchDB database, you
can use this attribute and

factoryMethodName
to specify a class and static
method to get the connection
from. The method must return a

org.lightcouch.CouchDbClient
or a

org.lightcouch.CouchDbProperties.
If you use the factory method for
providing a connection, you must
not specify the databaseName,
protocol, server, port,
username, or password
attributes.
factoryMethodName

Method

See the documentation for attribute
factoryClassName.

databaseName

String

If you do not specify a

factoryClassName and
factoryMethodName for
providing a CouchDB connection,
you must specify a CouchDB
database name using this
attribute. You must also specify
a username and password.
You can optionally also specify
a protocol (defaults to http),
server (defaults to localhost),
and a port (defaults to 80 for http
and 443 for https).
protocol

String

Must either be "http" or "https."
See the documentation for attribute
databaseName.

server

String

See the documentation for attribute
databaseName.

port

int

See the documentation for attribute
databaseName.

username

String

See the documentation for
attributes databaseName.

password

String

See the documentation for
attributes databaseName.

CouchDB Provider Parameters
Here are a few sample configurations for the NoSQLAppender and CouchDB provider:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

127















9.1.18 OutputStreamAppender

The OutputStreamAppender provides the base for many of the other Appenders such as the File
and Socket appenders that write the event to an Output Stream. It cannot be directly configured.
Support for immediateFlush and buffering is provided by the OutputStreamAppender. The
OutputStreamAppender uses an OutputStreamManager to handle the actual I/O, allowing the stream
to be shared by Appenders in multiple configurations.

9.1.19 RandomAccessFileAppender

The RandomAccessFileAppender is similar to the standard FileAppender except it is always
buffered (this cannot be switched off) and internally it uses a ByteBuffer + RandomAccessFile
instead of a BufferedOutputStream. We saw a 20-200% performance improvement compared
to FileAppender with "bufferedIO=true" in our measurements. Similar to the FileAppender,
RandomAccessFileAppender uses a RandomAccessFileManager to actually perform the file
I/O. While RandomAccessFileAppender from different Configurations cannot be shared, the
RandomAccessFileManagers can be if the Manager is accessible. For example, two web applications
in a servlet container can have their own configuration and safely write to the same file if Log4j is in a
ClassLoader that is common to both of them.
Parameter Name

Type

Description

append

boolean

When true - the default, records
will be appended to the end of the
file. When set to false, the file will
be cleared before new records are
written.

fileName

String

The name of the file to write to.
If the file, or any of its parent
directories, do not exist, they will be
created.

filters

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

immediateFlush

128

boolean

When set to true - the default,
each write will be followed by
a flush. This will guarantee the
data is written to disk but could
impact performance.
Flushing after every write is
only useful when using this
appender with synchronous
loggers. Asynchronous
loggers and appenders will
automatically flush at the end
of a batch of events, even if
immediateFlush is set to false.
This also guarantees the data
is written to disk but is more
efficient.

bufferSize

int

The buffer size, defaults to 262,144
bytes (256 * 1024).

layout

Layout

The Layout to use to format the
LogEvent. If no layout is supplied
the default pattern layout of "%m
%n" will be used.

name

String

The name of the Appender.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

RandomAccessFileAppender Parameters
Here is a sample RandomAccessFile configuration:





%d %p %c{1.} [%t] %m%n










©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

129

9.1.20 RewriteAppender

The RewriteAppender allows the LogEvent to manipulated before it is processed by another
Appender. This can be used to mask sensitive information such as passwords or to inject
information into each event. The RewriteAppender must be configured with a RewritePolicy. The
RewriteAppender should be configured after any Appenders it references to allow it to shut down
properly.
Parameter Name

Type

Description

AppenderRef

String

The name of the Appenders to
call after the LogEvent has been
manipulated. Multiple AppenderRef
elements can be configured.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

name

String

The name of the Appender.

rewritePolicy

RewritePolicy

The RewritePolicy that will
manipulate the LogEvent.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

RewriteAppender Parameters
9.1.20.1 RewritePolicy

RewritePolicy is an interface that allows implementations to inspect and possibly modify LogEvents
before they are passed to Appender. RewritePolicy declares a single method named rewrite that must
be implemented. The method is passed the LogEvent and can return the same event or create a new
one.
9.MapRewritePolicy

MapRewritePolicy will evaluate LogEvents that contain a MapMessage and will add or update
elements of the Map.
Parameter Name

Type

Description

mode

String

"Add" or "Update"

keyValuePair

KeyValuePair[]

An array of keys and their values.

The following configuration shows a RewriteAppender configured to add a product key and its value
to the MapMessage.:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

130





















9.PropertiesRewritePolicy

PropertiesRewritePolicy will add properties configured on the policy to the ThreadContext Map being
logged. The properties will not be added to the actual ThreadContext Map. The property values may
contain variables that will be evaluated when the configuration is processed as well as when the event
is logged.
Parameter Name

Type

Description

properties

Property[]

One of more Property elements to
define the keys and values to be
added to the ThreadContext Map.

The following configuration shows a RewriteAppender configured to add a product key and its value
to the MapMessage:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

131










${sys:user.name}
${sys:environment}










9.LoggerNameLevelRewritePolicy

You can use this policy to make loggers in third party code less chatty by changing event levels. The
LoggerNameLevelRewritePolicy will rewrite log event levels for a given logger name prefix. You
configure a LoggerNameLevelRewritePolicy with a logger name prefix and a pairs of levels, where a
pair defines a source level and a target level.
Parameter Name

Type

Description

logger

String

A logger name used as a prefix to
test each event's logger name.

LevelPair

KeyValuePair[]

An array of keys and their values,
each key is a source level, each
value a target level.

The following configuration shows a RewriteAppender configured to map level INFO to DEBUG and
level WARN to INFO for all loggers that start with com.foo.bar.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

132






















9.1.21 RollingFileAppender

The RollingFileAppender is an OutputStreamAppender that writes to the File named in the fileName
parameter and rolls the file over according the TriggeringPolicy and the RolloverPolicy. The
RollingFileAppender uses a RollingFileManager (which extends OutputStreamManager) to
actually perform the file I/O and perform the rollover. While RolloverFileAppenders from different
Configurations cannot be shared, the RollingFileManagers can be if the Manager is accessible. For
example, two web applications in a servlet container can have their own configuration and safely
write to the same file if Log4j is in a ClassLoader that is common to both of them.
A RollingFileAppender requires a TriggeringPolicy and a RolloverStrategy. The triggering
policy determines if a rollover should be performed while the RolloverStrategy defines how
the rollover should be done. If no RolloverStrategy is configured, RollingFileAppender will
use the DefaultRolloverStrategy. Since log4j-2.5, a custom delete action can be configured
in the DefaultRolloverStrategy to run at rollover. Since 2.8 if no file name is configured then
DirectWriteRolloverStrategy will be used instead of DefaultRolloverStrategy. Since log4j-2.9, a
custom POSIX file attribute view action can be configured in the DefaultRolloverStrategy to run at
rollover, if not defined, inherited POSIX file attribute view from the RollingFileAppender will be
applied.
File locking is not supported by the RollingFileAppender.
Parameter Name

Type

Description

append

boolean

When true - the default, records
will be appended to the end of the
file. When set to false, the file will
be cleared before new records are
written.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

133

bufferedIO

boolean

When true - the default, records
will be written to a buffer and the
data will be written to disk when the
buffer is full or, if immediateFlush
is set, when the record is written.
File locking cannot be used with
bufferedIO. Performance tests
have shown that using buffered I/O
significantly improves performance,
even if immediateFlush is enabled.

bufferSize

int

When bufferedIO is true, this is
the buffer size, the default is 8192
bytes.

createOnDemand

boolean

The appender creates the file
on-demand. The appender only
creates the file when a log event
passes all filters and is routed to
this appender. Defaults to false.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

fileName

String

The name of the file to write to.
If the file, or any of its parent
directories, do not exist, they will be
created.

filePattern

String

The pattern of the file name of
the archived log file. The format
of the pattern is dependent on
the RolloverPolicy that is used.
The DefaultRolloverPolicy will
accept both a date/time pattern
compatible with SimpleDateFormat
and/or a %i which represents an
integer counter. The pattern also
supports interpolation at runtime so
any of the Lookups (such as the
DateLookup) can be included in the
pattern.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

immediateFlush

134

boolean

When set to true - the default,
each write will be followed by
a flush. This will guarantee the
data is written to disk but could
impact performance.
Flushing after every write is
only useful when using this
appender with synchronous
loggers. Asynchronous
loggers and appenders will
automatically flush at the end
of a batch of events, even if
immediateFlush is set to false.
This also guarantees the data
is written to disk but is more
efficient.

layout

Layout

The Layout to use to format the
LogEvent. If no layout is supplied
the default pattern layout of "%m
%n" will be used.

name

String

The name of the Appender.

policy

TriggeringPolicy

The policy to use to determine if a
rollover should occur.

strategy

RolloverStrategy

The strategy to use to determine
the name and location of the
archive file.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

filePermissions

String

File attribute permissions
in POSIX format to apply
whenever the file is created.
Underlying files system shall
support POSIX file attribute
view.
Examples: rw------- or rw-rwrw- etc...

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

fileOwner

135

String

File owner to define whenever
the file is created.
Changing file's owner may be
restricted for security reason
and Operation not permitted
IOException thrown. Only
processes with an effective
user ID equal to the user ID
of the file or with appropriate
privileges may change
the ownership of a file if
_POSIX_CHOWN_RESTRICTED
is in effect for path.
Underlying files system shall
support file owner attribute
view.

fileGroup

String

File group to define whenever
the file is created.
Underlying files system shall
support POSIX file attribute
view.

RollingFileAppender Parameters

9.1.21.1 Triggering Policies
9.Composite Triggering Policy

The CompositeTriggeringPolicy combines multiple triggering policies and returns true if any
of the configured policies return true. The CompositeTriggeringPolicy is configured simply by
wrapping other policies in a Policies element.
For example, the following XML fragment defines policies that rollover the log when the JVM starts,
when the log size reaches twenty megabytes, and when the current date no longer matches the log’s
start date.






9.Cron Triggering Policy

The CronTriggeringPolicy triggers rollover based on a cron expression.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

136

schedule

String

The cron expression. The
expression is the same as what is
allowed in the Quartz scheduler.
See CronExpression for a full
description of the expression.

evaluateOnStartup

boolean

On startup the cron expression
will be evaluated against the file's
last modification timestamp. If the
cron expression indicates a rollover
should have occurred between that
time and the current time the file
will be immediately rolled over.

CronTriggeringPolicy Parameters
9.OnStartup Triggering Policy

The OnStartupTriggeringPolicy policy causes a rollover if the log file is older than the current
JVM's start time and the minimum file size is met or exceeded.
Parameter Name

Type

Description

minSize

long

The minimum size the file must
have to roll over. A size of zero will
cause a roll over no matter what
the file size is. The default value is
1, which will prevent rolling over an
empty file.

OnStartupTriggeringPolicy Parameters
Google App Engine note:
When running in Google App Engine, the OnStartup policy causes a rollover if
the log file is older than the time when Log4J initialized. (Google App Engine
restricts access to certain classes so Log4J cannot determine JVM start time with
java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime() and

falls back to Log4J initialization time instead.)
9.SizeBased Triggering Policy

The SizeBasedTriggeringPolicy causes a rollover once the file has reached the specified size.
The size can be specified in bytes, with the suffix KB, MB or GB, for example 20MB.
9.TimeBased Triggering Policy

The TimeBasedTriggeringPolicy causes a rollover once the date/time pattern no longer applies
to the active file. This policy accepts an interval attribute which indicates how frequently the
rollover should occur based on the time pattern and a modulate boolean attribute.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

137

interval

integer

How often a rollover should
occur based on the most specific
time unit in the date pattern. For
example, with a date pattern with
hours as the most specific item and
and increment of 4 rollovers would
occur every 4 hours. The default
value is 1.

modulate

boolean

Indicates whether the interval
should be adjusted to cause the
next rollover to occur on the interval
boundary. For example, if the item
is hours, the current hour is 3 am
and the interval is 4 then the first
rollover will occur at 4 am and then
next ones will occur at 8 am, noon,
4pm, etc.

maxRandomDelay

integer

Indicates the maximum number
of seconds to randomly delay a
rollover. By default, this is 0 which
indicates no delay. This setting is
useful on servers where multiple
applications are configured to
rollover log files at the same time
and can spread the load of doing
so across time.

TimeBasedTriggeringPolicy Parameters

9.1.21.2 Rollover Strategies

9.Default Rollover Strategy

The default rollover strategy accepts both a date/time pattern and an integer from the filePattern
attribute specified on the RollingFileAppender itself. If the date/time pattern is present it will be
replaced with the current date and time values. If the pattern contains an integer it will be incremented
on each rollover. If the pattern contains both a date/time and integer in the pattern the integer will
be incremented until the result of the date/time pattern changes. If the file pattern ends with ".gz",
".zip", ".bz2", ".deflate", ".pack200", or ".xz" the resulting archive will be compressed using the
compression scheme that matches the suffix. The formats bzip2, Deflate, Pack200 and XZ require
Apache Commons Compress. In addition, XZ requires XZ for Java. The pattern may also contain
lookup references that can be resolved at runtime such as is shown in the example below.
The default rollover strategy supports three variations for incrementing the counter. The first is the
"fixed window" strategy. To illustrate how it works, suppose that the min attribute is set to 1, the max
attribute is set to 3, the file name is "foo.log", and the file name pattern is "foo-%i.log".
Number of rollovers

Active output target

Archived log files

Description

0

foo.log

-

All logging is going to the
initial file.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

138

1

foo.log

foo-1.log

During the first rollover
foo.log is renamed to
foo-1.log. A new foo.log
file is created and starts
being written to.

2

foo.log

foo-1.log, foo-2.log

During the second rollover
foo-1.log is renamed to
foo-2.log and foo.log is
renamed to foo-1.log. A
new foo.log file is created
and starts being written
to.

3

foo.log

foo-1.log, foo-2.log,
foo-3.log

During the third rollover
foo-2.log is renamed to
foo-3.log, foo-1.log is
renamed to foo-2.log and
foo.log is renamed to
foo-1.log. A new foo.log
file is created and starts
being written to.

4

foo.log

foo-1.log, foo-2.log,
foo-3.log

In the fourth and
subsequent rollovers,
foo-3.log is deleted,
foo-2.log is renamed to
foo-3.log, foo-1.log is
renamed to foo-2.log and
foo.log is renamed to
foo-1.log. A new foo.log
file is created and starts
being written to.

By way of contrast, when the fileIndex attribute is set to "max" but all the other settings are the same
the following actions will be performed.
Number of rollovers

Active output target

Archived log files

Description

0

foo.log

-

All logging is going to the
initial file.

1

foo.log

foo-1.log

During the first rollover
foo.log is renamed to
foo-1.log. A new foo.log
file is created and starts
being written to.

2

foo.log

foo-1.log, foo-2.log

During the second rollover
foo.log is renamed to
foo-2.log. A new foo.log
file is created and starts
being written to.

3

foo.log

foo-1.log, foo-2.log,
foo-3.log

During the third rollover
foo.log is renamed to
foo-3.log. A new foo.log
file is created and starts
being written to.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

4

139

foo.log

foo-1.log, foo-2.log,
foo-3.log

In the fourth and
subsequent rollovers,
foo-1.log is deleted,
foo-2.log is renamed to
foo-1.log, foo-3.log is
renamed to foo-2.log and
foo.log is renamed to
foo-3.log. A new foo.log
file is created and starts
being written to.

Finally, as of release 2.8, if the fileIndex attribute is set to "nomax" then the min and max values
will be ignored and file numbering will increment by 1 and each rollover will have an incrementally
higher value with no maximum number of files.
Parameter Name

Type

Description

fileIndex

String

If set to "max" (the default), files
with a higher index will be newer
than files with a smaller index.
If set to "min", file renaming and
the counter will follow the Fixed
Window strategy described above.

min

integer

The minimum value of the counter.
The default value is 1.

max

integer

The maximum value of the counter.
Once this values is reached
older archives will be deleted on
subsequent rollovers. The default
value is 7.

compressionLevel

integer

Sets the compression level, 0-9,
where 0 = none, 1 = best speed,
through 9 = best compression. Only
implemented for ZIP files.

tempCompressedFilePattern

String

The pattern of the file name
of the archived log file during
compression.

DefaultRolloverStrategy Parameters

9.DirectWrite Rollover Strategy

The DirectWriteRolloverStrategy causes log events to be written directly to files represented by the
file pattern. With this strategy file renames are not performed. If the size-based triggering policy
causes multiple files to be written durring the specified time period they will be numbered starting at
one and continually incremented until a time-based rollover occurs.
Warning: If the file pattern has a suffix indicating compression should take place the current file will
not be compressed when the application is shut down. Furthermore, if the time changes such that the
file pattern no longer matches the current file it will not be compressed at startup either.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

140

maxFiles

String

The maximum number of files to
allow in the time period matching
the file pattern. If the number of
files is exceeded the oldest file will
be deleted. If specified, the value
must be greater than 1. If the value
is less than zero or omitted then the
number of files will not be limited.

compressionLevel

integer

Sets the compression level, 0-9,
where 0 = none, 1 = best speed,
through 9 = best compression. Only
implemented for ZIP files.

tempCompressedFilePattern

String

The pattern of the file name
of the archived log file during
compression.

DirectWriteRolloverStrategy Parameters
Below is a sample configuration that uses a RollingFileAppender with both the time and size based
triggering policies, will create up to 7 archives on the same day (1-7) that are stored in a directory
based on the current year and month, and will compress each archive using gzip:





%d %p %c{1.} [%t] %m%n














This second example shows a rollover strategy that will keep up to 20 files before removing them.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

141






%d %p %c{1.} [%t] %m%n















Below is a sample configuration that uses a RollingFileAppender with both the time and size based
triggering policies, will create up to 7 archives on the same day (1-7) that are stored in a directory
based on the current year and month, and will compress each archive using gzip and will roll every 6
hours when the hour is divisible by 6:





%d %p %c{1.} [%t] %m%n














This sample configuration uses a RollingFileAppender with both the cron and size based triggering
policies, and writes directly to an unlimited number of archive files. The cron trigger causes a rollover
every hour while the file size is limited to 250MB:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

142






%d %p %c{1.} [%t] %m%n














This sample configuration is the same as the previous but limits the number of files saved each hour
to 10:





%d %p %c{1.} [%t] %m%n















9.Log Archive Retention Policy: Delete on Rollover

Log4j-2.5 introduces a Delete action that gives users more control over what files are deleted at
rollover time than what was possible with the DefaultRolloverStrategy max attribute. The Delete
action lets users configure one or more conditions that select the files to delete relative to a base
directory.
Note that it is possible to delete any file, not just rolled over log files, so use this action with care!
With the testMode parameter you can test your configuration without accidentally deleting the
wrong files.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

143

Parameter Name

Type

Description

basePath

String

Required. Base path from where to
start scanning for files to delete.

maxDepth

int

The maximum number of levels
of directories to visit. A value of 0
means that only the starting file (the
base path itself) is visited, unless
denied by the security manager.
A value of Integer.MAX_VALUE
indicates that all levels should be
visited. The default is 1, meaning
only the files in the specified base
directory.

followLinks

boolean

Whether to follow symbolic links.
Default is false.

testMode

boolean

If true, files are not deleted but
instead a message is printed to
the status logger at INFO level.
Use this to do a dry run to test if the
configuration works as expected.
Default is false.

pathSorter

PathSorter

A plugin implementing the
PathSorter interface to sort the files
before selecting the files to delete.
The default is to sort most recently
modified files first.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

pathConditions

144

PathCondition[]

Required if no ScriptCondition
is specified. One or more
PathCondition elements.
If more than one condition
is specified, they all need
to accept a path before it is
deleted. Conditions can be
nested, in which case the inner
condition(s) are evaluated only
if the outer condition accepts
the path. If conditions are not
nested they may be evaluated in
any order.
Conditions can also be
combined with the logical
operators AND, OR and NOT
by using the IfAll, IfAny and
IfNot composite conditions.
Users can create custom
conditions or use the built-in
conditions:
• IfFileName - accepts files
whose path (relative to the
base path) matches a regular
expression or a glob.
• IfLastModified - accepts files
that are as old as or older than
the specified duration.
• IfAccumulatedFileCount accepts paths after some
count threshold is exceeded
during the file tree walk.
• IfAccumulatedFileSize accepts paths after the
accumulated file size threshold
is exceeded during the file tree
walk.
• IfAll - accepts a path if all
nested conditions accept
it (logical AND). Nested
conditions may be evaluated in
any order.
• IfAny - accepts a path if one of
the nested conditions accept it
(logical OR). Nested conditions
may be evaluated in any order.
• IfNot - accepts a path if the
nested condition does not
accept it (logical NOT).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

scriptCondition

145

ScriptCondition

Required if no PathConditions
are specified. A
ScriptCondition element
specifying a script.
The ScriptCondition should
contain a Script, ScriptRef or
ScriptFile element that specifies
the logic to be executed.
(See also the ScriptFilter
documentation for more
examples of configuring
ScriptFiles and ScriptRefs.)
The script is passed a number of
parameters, including a list of
paths found under the base path
(up to maxDepth) and must
return a list with the paths to
delete.

Delete Parameters

Parameter Name

Type

Description

glob

String

Required if regex not specified.
Matches the relative path (relative
to the base path) using a limited
pattern language that resembles
regular expressions but with a
simpler syntax.

regex

String

Required if glob not specified.
Matches the relative path (relative
to the base path) using a regular
expression as defined by the
Pattern class.

nestedConditions

PathCondition[]

An optional set of nested
PathConditions. If any nested
conditions exist they all need
to accept the file before it is
deleted. Nested conditions are only
evaluated if the outer condition
accepts a file (if the path name
matches).

IfFileName Condition Parameters

Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

146

age

String

Required. Specifies a duration.
The condition accepts files that are
as old or older than the specified
duration.

nestedConditions

PathCondition[]

An optional set of nested
PathConditions. If any nested
conditions exist they all need
to accept the file before it is
deleted. Nested conditions are only
evaluated if the outer condition
accepts a file (if the file is old
enough).

IfLastModified Condition Parameters

Parameter Name

Type

Description

exceeds

int

Required. The threshold count from
which files will be deleted.

nestedConditions

PathCondition[]

An optional set of nested
PathConditions. If any nested
conditions exist they all need
to accept the file before it is
deleted. Nested conditions are only
evaluated if the outer condition
accepts a file (if the threshold count
has been exceeded).

IfAccumulatedFileCount Condition Parameters

Parameter Name

Type

Description

exceeds

String

Required. The threshold
accumulated file size from which
files will be deleted. The size can
be specified in bytes, with the suffix
KB, MB or GB, for example 20MB.

nestedConditions

PathCondition[]

An optional set of nested
PathConditions. If any nested
conditions exist they all need
to accept the file before it is
deleted. Nested conditions are only
evaluated if the outer condition
accepts a file (if the threshold
accumulated file size has been
exceeded).

IfAccumulatedFileSize Condition Parameters
Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy
configured to trigger every day at midnight. Archives are stored in a directory based on the current

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

147

year and month. All files under the base directory that match the "*/app-*.log.gz" glob and are 60
days old or older are deleted at rollover time.



logs




















Below is a sample configuration that uses a RollingFileAppender with both the time and size based
triggering policies, will create up to 100 archives on the same day (1-100) that are stored in a
directory based on the current year and month, and will compress each archive using gzip and will
roll every hour. During every rollover, this configuration will delete files that match "*/app-*.log.gz"
and are 30 days old or older, but keep the most recent 100 GB or the most recent 10 files, whichever
comes first.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

148




logs






























Parameter Name

Type

Description

script

Script, ScriptFile or ScriptRef

The Script element that specifies
the logic to be executed. The
script is passed a list of paths
found under the base path and
must return the paths to delete
as a java.util.List<
PathWithAttributes>. See
also the ScriptFilter documentation
for an example of how ScriptFiles
and ScriptRefs can be configured.

ScriptCondition Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

149

Parameter Name

Type

Description

basePath

java.nio.file.Path

The directory from where the
Delete action started scanning
for files to delete. Can be used to
relativize the paths in the pathList.

pathList

java.util.List<
PathWithAttributes>

The list of paths found under the
base path up to the specified
max depth, sorted most recently
modified files first. The script is free
to modify and return this list.

statusLogger

StatusLogger

The StatusLogger that can be used
to log internal events during script
execution.

configuration

Configuration

The Configuration that owns this
ScriptCondition.

substitutor

StrSubstitutor

The StrSubstitutor used to replace
lookup variables.

?

String

Any properties declared in the
configuration.

Script Parameters
Below is a sample configuration that uses a RollingFileAppender with the cron triggering policy
configured to trigger every day at midnight. Archives are stored in a directory based on the current
year and month. The script returns a list of rolled over files under the base directory dated Friday the
13th. The Delete action will delete all files returned by the script.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

150




logs





















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

151

9.Log Archive File Attribute View Policy: Custom file attribute on Rollover

Log4j-2.9 introduces a PosixViewAttribute action that gives users more control over which file
attribute permissions, owner and group should be applied. The PosixViewAttribute action lets users
configure one or more conditions that select the eligible files relative to a base directory.
Parameter Name

Type

Description

basePath

String

Required. Base path from where
to start scanning for files to apply
attributes.

maxDepth

int

The maximum number of levels
of directories to visit. A value of 0
means that only the starting file (the
base path itself) is visited, unless
denied by the security manager.
A value of Integer.MAX_VALUE
indicates that all levels should be
visited. The default is 1, meaning
only the files in the specified base
directory.

followLinks

boolean

Whether to follow symbolic links.
Default is false.

pathConditions

PathCondition[]

see DeletePathCondition

filePermissions

String

File attribute permissions in
POSIX format to apply when
action is executed.
Underlying files system shall
support POSIX file attribute
view.
Examples: rw------- or rw-rwrw- etc...

fileOwner

String

File owner to define when
action is executed.
Changing file's owner may be
restricted for security reason
and Operation not permitted
IOException thrown. Only
processes with an effective
user ID equal to the user ID
of the file or with appropriate
privileges may change
the ownership of a file if
_POSIX_CHOWN_RESTRICTED
is in effect for path.
Underlying files system shall
support file owner attribute
view.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

fileGroup

152

String

File group to define whene
action is executed.
Underlying files system shall
support POSIX file attribute
view.

PosixViewAttribute Parameters
Below is a sample configuration that uses a RollingFileAppender and defines different POSIX file
attribute view for current and rolled log files.



logs



















9.1.22 RollingRandomAccessFileAppender

The RollingRandomAccessFileAppender is similar to the standard RollingFileAppender except
it is always buffered (this cannot be switched off) and internally it uses a ByteBuffer +
RandomAccessFile instead of a BufferedOutputStream. We saw a 20-200% performance
improvement compared to RollingFileAppender with "bufferedIO=true" in our measurements. The
RollingRandomAccessFileAppender writes to the File named in the fileName parameter and rolls the
file over according the TriggeringPolicy and the RolloverPolicy. Similar to the RollingFileAppender,
RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager to actually perform
the file I/O and perform the rollover. While RollingRandomAccessFileAppender from different
Configurations cannot be shared, the RollingRandomAccessFileManagers can be if the Manager is
accessible. For example, two web applications in a servlet container can have their own configuration
and safely write to the same file if Log4j is in a ClassLoader that is common to both of them.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

153

A RollingRandomAccessFileAppender requires a TriggeringPolicy and a RolloverStrategy.
The triggering policy determines if a rollover should be performed while the RolloverStrategy
defines how the rollover should be done. If no RolloverStrategy is configured,
RollingRandomAccessFileAppender will use the DefaultRolloverStrategy. Since log4j-2.5, a custom
delete action can be configured in the DefaultRolloverStrategy to run at rollover.
File locking is not supported by the RollingRandomAccessFileAppender.
Parameter Name

Type

Description

append

boolean

When true - the default, records
will be appended to the end of the
file. When set to false, the file will
be cleared before new records are
written.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

fileName

String

The name of the file to write to.
If the file, or any of its parent
directories, do not exist, they will be
created.

filePattern

String

The pattern of the file name of the
archived log file. The format of the
pattern should is dependent on the
RolloverPolicy that is used. The
DefaultRolloverPolicy will accept
both a date/time pattern compatible
with SimpleDateFormat and/or
a %i which represents an integer
counter. The pattern also supports
interpolation at runtime so any
of the Lookups (such as the
DateLookup can be included in the
pattern.

immediateFlush

boolean

When set to true - the default,
each write will be followed by
a flush. This will guarantee the
data is written to disk but could
impact performance.
Flushing after every write is
only useful when using this
appender with synchronous
loggers. Asynchronous
loggers and appenders will
automatically flush at the end
of a batch of events, even if
immediateFlush is set to false.
This also guarantees the data
is written to disk but is more
efficient.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

154

bufferSize

int

The buffer size, defaults to 262,144
bytes (256 * 1024).

layout

Layout

The Layout to use to format the
LogEvent. If no layout is supplied
the default pattern layout of "%m
%n" will be used.

name

String

The name of the Appender.

policy

TriggeringPolicy

The policy to use to determine if a
rollover should occur.

strategy

RolloverStrategy

The strategy to use to determine
the name and location of the
archive file.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

filePermissions

String

File attribute permissions
in POSIX format to apply
whenever the file is created.
Underlying files system shall
support POSIX file attribute
view.
Examples: rw------- or rwrw-rw- etc...

fileOwner

String

File owner to define whenever
the file is created.
Changing file's owner may be
restricted for security reason
and Operation not permitted
IOException thrown. Only
processes with an effective
user ID equal to the user ID
of the file or with appropriate
privileges may change
the ownership of a file if
_POSIX_CHOWN_RESTRICTED
is in effect for path.
Underlying files system shall
support file owner attribute
view.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

fileGroup

155

String

File group to define whenever
the file is created.
Underlying files system shall
support POSIX file attribute
view.

RollingRandomAccessFileAppender Parameters

9.1.22.1 Triggering Policies

See RollingFileAppender Triggering Policies.

9.1.22.2 Rollover Strategies

See RollingFileAppender Rollover Strategies.
Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time
and size based triggering policies, will create up to 7 archives on the same day (1-7) that are stored in
a directory based on the current year and month, and will compress each archive using gzip:





%d %p %c{1.} [%t] %m%n














This second example shows a rollover strategy that will keep up to 20 files before removing them.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

156






%d %p %c{1.} [%t] %m%n















Below is a sample configuration that uses a RollingRandomAccessFileAppender with both the time
and size based triggering policies, will create up to 7 archives on the same day (1-7) that are stored in
a directory based on the current year and month, and will compress each archive using gzip and will
roll every 6 hours when the hour is divisible by 6:





%d %p %c{1.} [%t] %m%n














9.1.23 RoutingAppender

The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The
target Appender may be an appender previously configured and may be referenced by its name or the
Appender can be dynamically created as needed. The RoutingAppender should be configured after
any Appenders it references to allow it to shut down properly.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

157

You can also configure a RoutingAppender with scripts: you can run a script when the appender starts
and when a route is chosen for an log event.
Parameter Name

Type

Description

Filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

name

String

The name of the Appender.

RewritePolicy

RewritePolicy

The RewritePolicy that will
manipulate the LogEvent.

Routes

Routes

Contains one or more Route
declarations to identify the criteria
for choosing Appenders.

Script

Script

This Script runs when Log4j
starts the RoutingAppender and
returns a String Route key to
determine the default Route.
This script is passed the
following variables:
Parameter
Name
Type

Description

configurationConfiguration
The
active
Configuration.
staticVariables
Map

A Map
shared
between
all script
invocations
for this
appender
instance.
This is
the same
map
passed
to the
Routes
Script.

RoutingAppender
Script Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

ignoreExceptions

158

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

RoutingAppender Parameters
In this example, the script causes the "ServiceWindows" route to be the default route on Windows
and "ServiceOther" on all other operating systems. Note that the List Appender is one of our test
appenders, any appender can be used, it is only used as a shorthand.






















9.1.23.1 Routes

The Routes element accepts a single attribute named "pattern". The pattern is evaluated against all
the registered Lookups and the result is used to select a Route. Each Route may be configured with a
key. If the key matches the result of evaluating the pattern then that Route will be selected. If no key
is specified on a Route then that Route is the default. Only one Route can be configured as the default.
The Routes element may contain a Script child element. If specified, the Script is run for each log
event and returns the String Route key to use.
You must specify either the pattern attribute or the Script element, but not both.
Each Route must reference an Appender. If the Route contains a ref attribute then the Route will
reference an Appender that was defined in the configuration. If the Route contains an Appender
definition then an Appender will be created within the context of the RoutingAppender and will be
reused each time a matching Appender name is referenced through a Route.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

159

This script is passed the following variables:
Parameter Name

Type

Description

configuration

Configuration

The active Configuration.

staticVariables

Map

A Map shared between all script
invocations for this appender
instance. This is the same map
passed to the Routes Script.

logEvent

LogEvent

The log event.

RoutingAppender Routes Script Parameters
In this example, the script runs for each log event and picks a route based on the presence of a Marker
named "AUDIT".

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

160
















%d %p %c{1.} [%t] %m%n

















9.1.23.2 Purge Policy

The RoutingAppender can be configured with a PurgePolicy whose purpose is to stop and remove
dormant Appenders that have been dynamically created by the RoutingAppender. Log4j currently
provides the IdlePurgePolicy as the only PurgePolicy available for cleaning up the Appenders. The
IdlePurgePolicy accepts 2 attributes; timeToLive, which is the number of timeUnits the Appender
should survive without having any events sent to it, and timeUnit, the String representation of
java.util.concurrent.TimeUnit which is used with the timeToLive attribute.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

161

Below is a sample configuration that uses a RoutingAppender to route all Audit events to a
FlumeAppender and all other events will be routed to a RollingFileAppender that captures only the
specific event type. Note that the AuditAppender was predefined while the RollingFileAppenders are
created as needed.













%d %p %c{1.} [%t] %m%n
















9.1.24 SMTPAppender

Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors.
The number of logging events delivered in this e-mail depend on the value of BufferSize option.
The SMTPAppender keeps only the last BufferSize logging events in its cyclic buffer. This keeps
memory requirements at a reasonable level while still delivering useful application context. All events
in the buffer are included in the email. The buffer will contain the most recent events of level TRACE
to WARN preceding the event that triggered the email.
The default behavior is to trigger sending an email whenever an ERROR or higher severity event
is logged and to format it as HTML. The circumstances on when the email is sent can be controlled
by setting one or more filters on the Appender. As with other Appenders, the formatting can be
controlled by specifying a Layout for the Appender.
Parameter Name

Type

Description

name

String

The name of the Appender.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

162

from

String

The email address of the sender.

replyTo

String

The comma-separated list of replyto email addresses.

to

String

The comma-separated list of
recipient email addresses.

cc

String

The comma-separated list of CC
email addresses.

bcc

String

The comma-separated list of BCC
email addresses.

subject

String

The subject of the email message.

bufferSize

integer

The maximum number of log
events to be buffered for inclusion
in the message. Defaults to 512.

layout

Layout

The Layout to use to format the
LogEvent. If no layout is supplied
HTML layout will be used.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

smtpDebug

boolean

When set to true enables session
debugging on STDOUT. Defaults to
false.

smtpHost

String

The SMTP hostname to send to.
This parameter is required.

smtpPassword

String

The password required to
authenticate against the SMTP
server.

smtpPort

integer

The SMTP port to send to.

smtpProtocol

String

The SMTP transport protocol (such
as "smtps", defaults to "smtp").

smtpUsername

String

The username required to
authenticate against the SMTP
server.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

SMTPAppender Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

163














9.1.25 ScriptAppenderSelector

When the configuration is built, the ScriptAppenderSelector appender calls a Script
to compute an appender name. Log4j then creates one of the appender named listed under
AppenderSet using the name of the ScriptAppenderSelector. After configuration, Log4j
ignores the ScriptAppenderSelector. Log4j only builds the one selected appender from the
configuration tree, and ignores other AppenderSet child nodes.
In the following example, the script returns the name "List2". The appender name is recorded under
the name of the ScriptAppenderSelector, not the name of the selected appender, in this example,
"SelectIt".


















9.1.26 SocketAppender

The SocketAppender is an OutputStreamAppender that writes its output to a remote destination
specified by a host and port. The data can be sent over either TCP or UDP and can be sent in any
format. You can optionally secure communication with SSL.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

164

Parameter Name

Type

Description

name

String

The name of the Appender.

host

String

The name or address of the system
that is listening for log events. This
parameter is required.

port

integer

The port on the host that is listening
for log events. This parameter must
be specified.

protocol

String

"TCP" (default), "SSL" or "UDP".

SSL

SslConfiguration

Contains the configuration for the
KeyStore and TrustStore. See
SSL.

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

immediateFail

boolean

When set to true, log events will
not wait to try to reconnect and will
fail immediately if the socket is not
available.

immediateFlush

boolean

When set to true - the default,
each write will be followed by a
flush. This will guarantee the data
is written to disk but could impact
performance.

bufferedIO

boolean

When true - the default, events are
written to a buffer and the data will
be written to the socket when the
buffer is full or, if immediateFlush is
set, when the record is written.

bufferSize

int

When bufferedIO is true, this is
the buffer size, the default is 8192
bytes.

layout

Layout

The Layout to use to format the
LogEvent. Required, there is no
default. New since 2.9, in previous
versions SerializedLayout was
default.

reconnectionDelayMillis

integer

If set to a value greater than 0,
after an error the SocketManager
will attempt to reconnect to the
server after waiting the specified
number of milliseconds. If the
reconnect fails then an exception
will be thrown (which can be
caught by the application if
ignoreExceptions is set to
false).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

165

connectTimeoutMillis

integer

The connect timeout in
milliseconds. The default
is 0 (infinite timeout, like
Socket.connect() methods).

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

SocketAppender Parameters

This is an unsecured TCP configuration:














This is a secured SSL configuration:


















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

166

9.1.27 SSL Configuration

Several appenders can be configured to use either a plain network connection or a Secure Socket
Layer (SSL) connection. This section documents the parameters available for SSL configuration.
Parameter Name

Type

Description

protocol

String

SSL if omitted. See also Standard
names.

KeyStore

KeyStore

Contains your private keys and
certificates, and determines which
authentication credentials to send
to the remote host.

TrustStore

TrustStore

Contains the CA certificates
of the remote counterparty.
Determines whether the remote
authentication credentials (and thus
the connection) should be trusted.

SSL Configuration Parameters
9.1.27.1 KeyStore

The keystore is meant to contain your private keys and certificates, and determines which
authentication credentials to send to the remote host.
Parameter Name

Type

Description

location

String

Path to the keystore file.

password

char[]

Plain text password to
access the keystore. Cannot
be combined with either

passwordEnvironmentVariable
or passwordFile.
passwordEnvironmentVariable

String

Name of an environment variable
that holds the password. Cannot be
combined with either password
or passwordFile.

passwordFile

String

Path to a file that holds the
password. Cannot be combined
with either password or

passwordEnvironmentVariable.
type

String

Optional KeyStore type, e.g.
JKS, PKCS12, PKCS11, BKS,

Windows-MY/Windows-ROOT,
KeychainStore, etc. The
default is JKS. See also Standard
types.
keyManagerFactoryAlgorithm

String

Optional KeyManagerFactory
algorithm. The default is
SunX509. See also Standard
algorithms.

KeyStore Configuration Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

167

9.1.27.2 TrustStore

The trust store is meant to contain the CA certificates you are willing to trust when a remote party
presents its certificate. Determines whether the remote authentication credentials (and thus the
connection) should be trusted.
In some cases, they can be one and the same store, although it is often better practice to use distinct
stores (especially when they are file-based).
Parameter Name

Type

Description

location

String

Path to the keystore file.

password

char[]

Plain text password to
access the keystore. Cannot
be combined with either

passwordEnvironmentVariable
or passwordFile.
passwordEnvironmentVariable

String

Name of an environment variable
that holds the password. Cannot be
combined with either password
or passwordFile.

passwordFile

String

Path to a file that holds the
password. Cannot be combined
with either password or

passwordEnvironmentVariable.
type

String

Optional KeyStore type, e.g.
JKS, PKCS12, PKCS11, BKS,

Windows-MY/Windows-ROOT,
KeychainStore, etc. The
default is JKS. See also Standard
types.
trustManagerFactoryAlgorithm

String

Optional TrustManagerFactory
algorithm. The default is
SunX509. See also Standard
algorithms.

TrustStore Configuration Parameters
9.1.27.3 Example
...





passwordFile="${sys:user.home}/truststore.pwd"/>

...

9.1.28 SyslogAppender

The SyslogAppender is a SocketAppender that writes its output to a remote destination specified
by a host and port in a format that conforms with either the BSD Syslog format or the RFC 5424
format. The data can be sent over either TCP or UDP.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

168

Parameter Name

Type

Description

advertise

boolean

Indicates whether the appender
should be advertised.

appName

String

The value to use as the APPNAME in the RFC 5424 syslog
record.

charset

String

The character set to use when
converting the syslog String to a
byte array. The String must be
a valid Charset. If not specified,
the default system Charset will be
used.

connectTimeoutMillis

integer

The connect timeout in
milliseconds. The default
is 0 (infinite timeout, like
Socket.connect() methods).

enterpriseNumber

integer

The IANA enterprise number as
described in RFC 5424

filter

Filter

A Filter to determine if the
event should be handled by
this Appender. More than one
Filter may be used by using a
CompositeFilter.

facility

String

The facility is used to try to classify
the message. The facility option
must be set to one of "KERN",
"USER", "MAIL", "DAEMON",
"AUTH", "SYSLOG", "LPR",
"NEWS", "UUCP", "CRON",
"AUTHPRIV", "FTP", "NTP",
"AUDIT", "ALERT", "CLOCK",
"LOCAL0", "LOCAL1", "LOCAL2",
"LOCAL3", "LOCAL4", "LOCAL5",
"LOCAL6", or "LOCAL7". These
values may be specified as upper
or lower case characters.

format

String

If set to "RFC5424" the data will
be formatted in accordance with
RFC 5424. Otherwise, it will be
formatted as a BSD Syslog record.
Note that although BSD Syslog
records are required to be 1024
bytes or shorter the SyslogLayout
does not truncate them. The
RFC5424Layout also does not
truncate records since the receiver
must accept records of up to 2048
bytes and may accept records that
are longer.

host

String

The name or address of the system
that is listening for log events. This
parameter is required.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

169

id

String

The default structured data id to
use when formatting according to
RFC 5424. If the LogEvent contains
a StructuredDataMessage the id
from the Message will be used
instead of this value.

ignoreExceptions

boolean

The default is true, causing
exceptions encountered while
appending events to be internally
logged and then ignored. When
set to false exceptions will be
propagated to the caller, instead.
You must set this to false when
wrapping this Appender in a
FailoverAppender.

immediateFail

boolean

When set to true, log events will
not wait to try to reconnect and will
fail immediately if the socket is not
available.

immediateFlush

boolean

When set to true - the default,
each write will be followed by a
flush. This will guarantee the data
is written to disk but could impact
performance.

includeMDC

boolean

Indicates whether data from the
ThreadContextMap will be included
in the RFC 5424 Syslog record.
Defaults to true.

Layout

Layout

A custom layout which overrides
the format setting.

loggerFields

List of KeyValuePairs

Allows arbitrary PatternLayout
patterns to be included as
specified ThreadContext fields;
no default specified. To use,
include a >LoggerFields< nested
element, containing one or more
>KeyValuePair< elements. Each
>KeyValuePair< must have a key
attribute, which specifies the key
name which will be used to identify
the field within the MDC Structured
Data element, and a value attribute,
which specifies the PatternLayout
pattern to use as the value.

mdcExcludes

String

A comma separated list of mdc
keys that should be excluded from
the LogEvent. This is mutually
exclusive with the mdcIncludes
attribute. This attribute only applies
to RFC 5424 syslog records.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

170

mdcIncludes

String

A comma separated list of mdc
keys that should be included in
the FlumeEvent. Any keys in the
MDC not found in the list will be
excluded. This option is mutually
exclusive with the mdcExcludes
attribute. This attribute only applies
to RFC 5424 syslog records.

mdcRequired

String

A comma separated list of mdc
keys that must be present in the
MDC. If a key is not present a
LoggingException will be thrown.
This attribute only applies to RFC
5424 syslog records.

mdcPrefix

String

A string that should be prepended
to each MDC key in order to
distinguish it from event attributes.
The default string is "mdc:". This
attribute only applies to RFC 5424
syslog records.

messageId

String

The default value to be used in the
MSGID field of RFC 5424 syslog
records.

name

String

The name of the Appender.

newLine

boolean

If true, a newline will be appended
to the end of the syslog record. The
default is false.

port

integer

The port on the host that is listening
for log events. This parameter must
be specified.

protocol

String

"TCP" or "UDP". This parameter is
required.

SSL

SslConfiguration

Contains the configuration for the
KeyStore and TrustStore. See
SSL.

reconnectionDelayMillis

integer

If set to a value greater than 0,
after an error the SocketManager
will attempt to reconnect to the
server after waiting the specified
number of milliseconds. If the
reconnect fails then an exception
will be thrown (which can be
caught by the application if
ignoreExceptions is set to
false).

SyslogAppender Parameters

A sample syslogAppender configuration that is configured with two SyslogAppenders, one using
the BSD format and one using RFC 5424.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

171

















For SSL this appender writes its output to a remote destination specified by a host and port over SSL
in a format that conforms with either the BSD Syslog format or the RFC 5424 format.

















9.1.29 ZeroMQ/JeroMQ Appender

The ZeroMQ appender uses the JeroMQ library to send log events to one or more ZeroMQ
endpoints.
This is a simple JeroMQ configuration:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

172





tcp://*:5556
ipc://info-topic









The table below describes all options. Please consult the JeroMQ and ZeroMQ documentation for
details.
Parameter Name

Type

Description

name

String

The name of the Appender.
Required.

Layout

layout

The Layout to use to format the
LogEvent. If no layout is supplied
the default pattern layout of "%m
%n" will be used.

Filters

Filter

The Filter(s) of the Appender.

Properties

Property[]

One or more Property elements,
named endpoint.

ignoreExceptions

boolean

If true, exceptions will be logged
and suppressed. If false errors will
be logged and then passed to the
application.

affinity

long

The ZMQ_AFFINITY option.
Defaults to 0.

backlog

long

The ZMQ_BACKLOG option.
Defaults to 100.

delayAttachOnConnect

boolean

The
ZMQ_DELAY_ATTACH_ON_CONNECT
option. Defaults to false.

identity

byte[]

The ZMQ_IDENTITY option.
Defaults to none.

ipv4Only

boolean

The ZMQ_IPV4ONLY option.
Defaults to true.

linger

long

The ZMQ_LINGER option. Defaults
to -1.

maxMsgSize

long

The ZMQ_MAXMSGSIZE option.
Defaults to -1.

rcvHwm

long

The ZMQ_RCVHWM option.
Defaults to 1000.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

9 Appenders

173

receiveBufferSize

long

The ZMQ_RCVBUF option.
Defaults to 0.

receiveTimeOut

int

The ZMQ_RCVTIMEO option.
Defaults to -1.

reconnectIVL

long

The ZMQ_RECONNECT_IVL
option. Defaults to 100.

reconnectIVLMax

long

The
ZMQ_RECONNECT_IVL_MAX
option. Defaults to 0.

sendBufferSize

long

The ZMQ_SNDBUF option.
Defaults to 0.

sendTimeOut

int

The ZMQ_SNDTIMEO option.
Defaults to -1.

sndHwm

long

The ZMQ_SNDHWM option.
Defaults to 1000.

tcpKeepAlive

int

The ZMQ_TCP_KEEPALIVE
option. Defaults to -1.

tcpKeepAliveCount

long

The ZMQ_TCP_KEEPALIVE_CNT
option. Defaults to -1.

tcpKeepAliveIdle

long

The ZMQ_TCP_KEEPALIVE_IDLE
option. Defaults to -1.

tcpKeepAliveInterval

long

The
ZMQ_TCP_KEEPALIVE_INTVL
option. Defaults to -1.

xpubVerbose

boolean

The ZMQ_XPUB_VERBOSE
option. Defaults to false.

JeroMQ Parameters

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

174

10 Layouts

.......................................................................................................................................
10.1 Layouts
An Appender uses a Layout to format a LogEvent into a form that meets the needs of whatever will
be consuming the log event. In Log4j 1.x and Logback Layouts were expected to transform an event
into a String. In Log4j 2 Layouts return a byte array. This allows the result of the Layout to be useful
in many more types of Appenders. However, this means you need to configure most Layouts with a
Charset to ensure the byte array contains correct values.
The root class for layouts that use a Charset is
org.apache.logging.log4j.core.layout.AbstractStringLayout where the default is
UTF-8. Each layout that extends AbstractStringLayout can provide its own default. See each

layout below.
A custom character encoder was added to Log4j 2.4.1 for the ISO-8859-1 and US-ASCII charsets,
to bring some of the performance improvements built-in to Java 8 to Log4j for use on Java 7. For
applications that log only ISO-8859-1 characters, specifying this charset will improve performance
significantly.

10.1.1 CSV Layouts

This layout creates Comma Separated Value (CSV) records and requires Apache Commons CSV
1.4.
The CSV layout can be used in two ways: First, using CsvParameterLayout to log event
parameters to create a custom database, usually to a logger and file appender uniquely configured for
this purpose. Second, using CsvLogEventLayout to log events to create a database, as an alternative
to using a full DBMS or using a JDBC driver that supports the CSV format.
The CsvParameterLayout converts an event's parameters into a CSV record, ignoring the message.
To log CSV records, you can use the usual Logger methods info(), debug(), and so on:
logger.info("Ignored", value1, value2, value3);

Which will create the CSV record:
value1, value2, value3

Alternatively, you can use a ObjectArrayMessage, which only carries parameters:
logger.info(new ObjectArrayMessage(value1, value2, value3));

The layouts CsvParameterLayout and CsvLogEventLayout are configured with the following
parameters:
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

175

format

String

One of the predefined formats:
Default, Excel, MySQL,
RFC4180, TDF. See
CSVFormat.Predefined.

delimiter

Character

Sets the delimiter of the format to
the specified character.

escape

Character

Sets the escape character of the
format to the specified character.

quote

Character

Sets the quoteChar of the format to
the specified character.

quoteMode

String

Sets the output quote policy
of the format to the specified
value. One of: ALL, MINIMAL,
NON_NUMERIC, NONE.

nullString

String

Writes null as the given nullString
when writing records.

recordSeparator

String

Sets the record separator of the
format to the specified String.

charset

Charset

The output Charset.

header

Sets the header to include when
the stream is opened.

Desc.

footer

Sets the footer to include when the
stream is closed.

Desc.

CsvParameterLayout and CsvLogEventLayout
Logging as a CSV events looks like this:
logger.debug("one={}, two={}, three={}", 1, 2, 3);

Produces a CSV record with the following fields:
1. Time Nanos
2. Time Millis
3. Level
4. Thread ID
5. Thread Name
6. Thread Priority
7. Formatted Message
8. Logger FQCN
9. Logger Name
10.Marker
11.Thrown Proxy
12.Source
13.Context Map
14.Context Stack

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

176

0,1441617184044,DEBUG,main,"one=1, two=2, three=3",org.apache.logging.log4j.spi.AbstractLogger,,,,org.apache.

Additional runtime dependencies are required for using CSV layouts.

10.1.2 GELF Layout

Lays out events in the Graylog Extended Log Format (GELF) 1.1.
This layout compresses JSON to GZIP or ZLIB (the compressionType) if log event data is larger
than 1024 bytes (the compressionThreshold). This layout does not implement chunking.
Configure as follows to send to a Graylog 2.x server with UDP:






Configure as follows to send to a Graylog 2.x server with TCP:






Parameter Name

Type

Description

host

String

The value of the host property
(optional, defaults to local host
name).

compressionType

GZIP, ZLIB or OFF

Compression to use (optional,
defaults to GZIP)

compressionThreshold

int

Compress if data is larger than this
number of bytes (optional, defaults
to 1024)

includeStacktrace

boolean

Whether to include full stacktrace
of logged Throwables (optional,
default to true). If set to false, only
the class name and message of the
Throwable will be included.

includeThreadContext

boolean

Whether to include thread context
as additional fields (optional,
default to true).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

includeNullDelimiter

177

boolean

Whether to include NULL byte as
delimiter after each event (optional,
default to false). Useful for Graylog
GELF TCP input. Cannot be used
with compression.

GelfLayout Parameters
To include any custom field in the output, use following syntax:





Custom fields are included in the order they are declared. The values support lookups.
See also:
• The GELF specification

10.1.3 HTML Layout

The HtmlLayout generates an HTML page and adds each LogEvent to a row in a table.
Parameter Name

Type

Description

charset

String

The character set to use when
converting the HTML String to a
byte array. The value must be a
valid Charset. If not specified, this
layout uses UTF-8.

contentType

String

The value to assign to the ContentType header. The default is "text/
html".

locationInfo

boolean

If true, the filename and line
number will be included in
the HTML output. The default
value is false.
Generating location
information is an expensive
operation and may impact
performance. Use with caution.
title

String

A String that will appear as the
HTML title.

fontName

String

The font-family to use. The
default is "arial,sans-serif".

fontSize

String

The font-size to use. The
default is "small".

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

178

HtmlLayout Parameters

10.1.4 JSON Layout

Appends a series of JSON events as strings serialized as bytes.
10.1.4.1 Complete well-formed JSON vs. fragment JSON

If you configure complete="true", the appender outputs a well-formed JSON document. By
default, with complete="false", you should include the output as an external file in a separate file
to form a well-formed JSON document.
If complete="false", the appender does not write the JSON open array character "[" at the start of
the document, "]" and the end, nor comma "," between records.
Log event follows this pattern:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

179

{
"instant" : {
"epochSecond" : 1493121664,
"nanoOfSecond" : 118000000
},
"thread" : "main",
"level" : "INFO",
"loggerName" : "HelloWorld",
"marker" : {
"name" : "child",
"parents" : [ {
"name" : "parent",
"parents" : [ {
"name" : "grandparent"
} ]
} ]
},
"message" : "Hello, world!",
"thrown" : {
"commonElementCount" : 0,
"message" : "error message",
"name" : "java.lang.RuntimeException",
"extendedStackTrace" : [ {
"class" : "logtest.Main",
"method" : "main",
"file" : "Main.java",
"line" : 29,
"exact" : true,
"location" : "classes/",
"version" : "?"
} ]
},
"contextStack" : [ "one", "two" ],
"endOfBatch" : false,
"loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
"contextMap" : {
"bar" : "BAR",
"foo" : "FOO"
},
"threadId" : 1,
"threadPriority" : 5,
"source" : {
"class" : "logtest.Main",
"method" : "main",
"file" : "Main.java",
"line" : 29
}
}

If complete="false", the appender does not write the JSON open array character "[" at the start of
the document, "]" and the end, nor comma "," between records.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

180

10.1.4.2 Pretty vs. compact JSON

By default, the JSON layout is not compact (a.k.a. not "pretty") with compact="false",
which means the appender uses end-of-line characters and indents lines to format the text. If
compact="true", then no end-of-line or indentation is used. Message content may contain, of
course, escaped end-of-lines.
Parameter Name

Type

Description

charset

String

The character set to use when
converting to a byte array. The
value must be a valid Charset. If
not specified, UTF-8 will be used.

compact

boolean

If true, the appender does not
use end-of-lines and indentation.
Defaults to false.

eventEol

boolean

If true, the appender appends
an end-of-line after each record.
Defaults to false. Use with
eventEol=true and compact=true to
get one record per line.

complete

boolean

If true, the appender includes the
JSON header and footer, and
comma between records. Defaults
to false.

properties

boolean

If true, the appender includes
the thread context map in the
generated JSON. Defaults to false.

propertiesAsList

boolean

If true, the thread context map
is included as a list of map entry
objects, where each entry has a
"key" attribute (whose value is
the key) and a "value" attribute
(whose value is the value). Defaults
to false, in which case the thread
context map is included as a simple
map of key-value pairs.

locationInfo

boolean

If true, the appender includes
the location information in the
generated JSON. Defaults to
false.
Generating location
information is an expensive
operation and may impact
performance. Use with caution.

includeStacktrace

boolean

If true, include full stacktrace of
any logged Throwable (optional,
default to true).

stacktraceAsString

boolean

Whether to format the stacktrace
as a string, and not a nested object
(optional, defaults to false).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

181

includeNullDelimiter

boolean

Whether to include NULL byte as
delimiter after each event (optional,
default to false).

objectMessageAsJsonObject

boolean

If true, ObjectMessage is serialized
as JSON object to the "message"
field of the output log. Defaults to
false.

JsonLayout Parameters
To include any custom field in the output, use following syntax:





Custom fields are always last, in the order they are declared. The values support lookups.
Additional runtime dependencies are required for using JsonLayout.

10.1.5 Pattern Layout

A flexible layout configurable with pattern string. The goal of this class is to format a LogEvent and
return the results. The format of the result depends on the conversion pattern.
The conversion pattern is closely related to the conversion pattern of the printf function in C. A
conversion pattern is composed of literal text and format control expressions called conversion
specifiers.
Note that any literal text, including Special Characters, may be included in the conversion pattern.
Special Characters include \t, \n, \r, \f. Use \\ to insert a single backslash into the output.
Each conversion specifier starts with a percent sign (%) and is followed by optional format modifiers
and a conversion character. The conversion character specifies the type of data, e.g. category,
priority, date, thread name. The format modifiers control such things as field width, padding, left and
right justification. The following is a simple example.
Let the conversion pattern be "%-5p [%t]: %m%n" and assume that the Log4j environment was set
to use a PatternLayout. Then the statements
Logger logger = LogManager.getLogger("MyLogger");
logger.debug("Message 1");
logger.warn("Message 2");

would yield the output
DEBUG [main]: Message 1
WARN [main]: Message 2

Note that there is no explicit separator between text and conversion specifiers. The pattern parser
knows when it has reached the end of a conversion specifier when it reads a conversion character. In
the example above the conversion specifier %-5p means the priority of the logging event should be
left justified to a width of five characters.
If the pattern string does not contain a specifier to handle a Throwable being logged, parsing of
the pattern will act as if the "%xEx" specifier had be added to the end of the string. To suppress
formatting of the Throwable completely simply add "%ex{0}" as a specifier in the pattern string.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

182

Parameter Name

Type

Description

charset

String

The character set to use when
converting the syslog String to a
byte array. The String must be a
valid Charset. If not specified, this
layout uses the platform default
character set.

pattern

String

A composite pattern string of one or
more conversion patterns from the
table below. Cannot be specified
with a PatternSelector.

patternSelector

PatternSelector

A component that analyzes
information in the LogEvent and
determines which pattern should
be used to format the event.
The pattern and patternSelector
parameters are mutually exclusive.

replace

RegexReplacement

Allows portions of the resulting
String to be replaced. If configured,
the replace element must
specify the regular expression to
match and the substitution. This
performs a function similar to the
RegexReplacement converter but
applies to the whole message while
the converter only applies to the
String its pattern generates.

alwaysWriteExceptions

boolean

If true (it is by default) exceptions
are always written even if the
pattern contains no exception
conversions. This means that if
you do not include a way to output
exceptions in your pattern, the
default exception formatter will be
added to the end of the pattern.
Setting this to false disables
this behavior and allows you to
exclude exceptions from your
pattern output.

header

String

The optional header string to
include at the top of each log file.

footer

String

The optional footer string to include
at the bottom of each log file.

disableAnsi

boolean

If true (default is false), do not
output ANSI escape codes.

noConsoleNoAnsi

boolean

If true (default is false) and
System.console() is null, do
not output ANSI escape codes.

PatternLayout Parameters
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

183

regex

String

A Java-compliant regular
expression to match in the resulting
string. See Pattern .

replacement

String

The string to replace any matched
sub-strings with.

RegexReplacement Parameters
10.1.5.1 Patterns

The conversions that are provided with Log4j are:
Conversion Pattern

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

184

c{precision}
logger{precision}

Outputs the name of the logger that published
the logging event. The logger conversion
specifier can be optionally followed by precision
specifier, which consists of a decimal integer, or
a pattern starting with a decimal integer.
When the precision specifier is an integer
value, it reduces the size of the logger name.
If the number is positive, the layout prints the
corresponding number of rightmost logger name
components. If negative, the layout removes the
corresponding number of leftmost logger name
components.
If the precision contains any non-integer
characters, then the layout abbreviates the name
based on the pattern. If the precision integer is
less than one, the layout still prints the right-most
token in full. By default, the layout prints the
logger name in full.
Conversion
Pattern

Logger Name Result

%c{1}

org.apache.
commons.Foo

Foo

%c{2}

org.apache.
commons.Foo

commons.Foo

%c{10}

org.apache.
commons.Foo

org.apache.
commons.Foo

%c{-1}

org.apache.
commons.Foo

apache.
commons.Foo

%c{-2}

org.apache.
commons.Foo

commons.Foo

%c{-10}

org.apache.
commons.Foo

org.apache.
commons.Foo

%c{1.}

org.apache.
commons.Foo

o.a.c.Foo

%c{1.1.~.~}

org.apache.
commons.test.
Foo

o.a.~.~.Foo

%c{.}

org.apache.
commons.test.
Foo

....Foo

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

185

C{precision}
class{precision}

Outputs the fully qualified class name of
the caller issuing the logging request. This
conversion specifier can be optionally followed
by precision specifier, that follows the same
rules as the logger name converter.
Generating the class name of the caller (
location information) is an expensive operation
and may impact performance. Use with caution.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

186

d{pattern}
date{pattern}

Outputs the date of the logging event. The date
conversion specifier may be followed by a set of
braces containing a date and time pattern string
per SimpleDateFormat .
The predefined formats are DEFAULT,
ABSOLUTE, COMPACT, DATE, ISO8601, and
ISO8601_BASIC.
You can also use a set of braces
containing a time zone id per
java.util.TimeZone.getTimeZone. If no date
format specifier is given then the DEFAULT
format is used.
Pattern

Example

%d{DEFAULT}

2012-11-02 14:34:02,123

%d{DEFAULT_MICROS} 2012-11-02
14:34:02,123456
%d{DEFAULT_NANOS}

2012-11-02
14:34:02,123456789

%d{ISO8601}

2012-11-02T14:34:02,781

%d{ISO8601_BASIC}

20121102T143402,781

%d{ABSOLUTE}

14:34:02,781

%d{ABSOLUTE_MICROS} 14:34:02,123456
%d{ABSOLUTE_NANOS} 14:34:02,123456789
%d{DATE}

02 Nov 2012
14:34:02,781

%d{COMPACT}

20121102143402781

%d{HH:mm:ss,SSS}

14:34:02,123

%d{HH:mm:ss,nnnn} to
14:34:02,1234 to
%d{HH:mm:ss,nnnnnnnnn} 14:34:02,123456789

©2018, The Apache Software Foundation • ALL

%d{dd MMM yyyy
HH:mm:ss,SSS}

02 Nov 2012
14:34:02,123

%d{dd MMM yyyy
HH:mm:ss,nnnn} to
%d{dd MMM yyyy
HH:mm:ss,nnnnnnnnn}

02 Nov 2012
14:34:02,1234
to 02 Nov 2012
14:34:02,123456789

%d{HH:mm:ss}{GMT+0}

18:34:02

%d{UNIX}

1351866842

%d{UNIX_MILLIS}

1351866842781

%d{UNIX} outputs the UNIX time in seconds.
%d{UNIX_MILLIS} outputs the UNIX time in
milliseconds. The UNIX time is the difference,
in seconds for UNIX and in milliseconds for
UNIX_MILLIS, between the current time and
midnight, January 1, 1970 UTC. While the time
unit is milliseconds, the granularity depends on
the operating system ( Windows). This is an
efficient way to output the event time because
only a conversion from long to String takes
noD .Date formatting involved.
R I Gplace,
H T S Rthere
E S E Ris
VE
Log4j 2.11 adds limited support for timestamps
more precise than milliseconds when running
on Java 9. Note that not all DateTimeFormatter

10 Layouts

enc{ pattern}{[HTML|XML|JSON|CRLF]}
encode{ pattern}{[HTML|XML|JSON|CRLF]}

187

Encodes and escapes special characters suitable
for output in specific markup languages. By
default, this encodes for HTML if only one
option is specified. The second option is used to
specify which encoding format should be used.
This converter is particularly useful for encoding
user provided data so that the output data is not
written improperly or insecurely.
A typical usage would encode the message
%enc{%m} but user input could come from
other locations as well, such as the MDC
%enc{%mdc{key}}

Using the HTML encoding format, the following
characters are replaced:
Character

Replacement

'\r', '\n'

Converted into escaped
strings "\\r" and "\\n"
respectively

&, <, >, ", ', /

Replaced with the
corresponding HTML
entity

Using the XML encoding format, this follows
the escaping rules specified by the XML
specification:
Character

Replacement

&, <, >, ", '

Replaced with the
corresponding XML
entity

Using the JSON encoding format, this follows
the escaping rules specified by RFC 4627
section 2.5:
Character

Replacement

U+0000 - U+001F

\u0000 - \u001F

Any other control
characters

Encoded into its
\uABCD equivalent
escaped code point

"

\"

\

\\

For example, the pattern {"message":
"%enc{%m}{JSON}"} could be used to output
a valid JSON document containing the log
message as a string value.
Using the CRLF encoding format, the following
characters are replaced:
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

Character

Replacement

'\r', '\n'

Converted into escaped
strings "\\r" and "\\n"

10 Layouts

188

equals{pattern}{test}{substitution}
equalsIgnoreCase{pattern}{test}{substitution}

Replaces occurrences of 'test', a string, with its
replacement 'substitution' in the string resulting
from evaluation of the pattern. For example,
"%equals{[%marker]}{[]}{}" will replace '[]'
strings produces by events without markers with
an empty string.
The pattern can be arbitrarily complex and
in particular can contain multiple conversion
keywords.

ex| exception| throwable
{
[ "none"
| "full"
| depth
| "short"
| "short.className"
| "short.fileName"
| "short.lineNumber"
| "short.methodName"
| "short.message"
| "short.localizedMessage"]
}
{filters(package,package,...)}
{suffix( pattern)}
{separator( separator)}

Outputs the Throwable trace bound to the
logging event, by default this will output the full
trace as one would normally find with a call to
Throwable.printStackTrace().
You can follow the throwable conversion
word with an option in the form
%throwable{option}.
%throwable{short} outputs the first line of

the Throwable.
%throwable{short.className} outputs the

name of the class where the exception occurred.
%throwable{short.methodName} outputs

the method name where the exception occurred.
%throwable{short.fileName} outputs the

name of the class where the exception occurred.
%throwable{short.lineNumber} outputs

the line number where the exception occurred.
%throwable{short.message} outputs the

message.
%throwable{short.localizedMessage}

outputs the localized message.
%throwable{n} outputs the first n lines of the

stack trace.
Specifying %throwable{none} or
%throwable{0} suppresses output of the
exception.
Use {filters( packages)} where packages
is a list of package names to suppress matching
stack frames from stack traces.
Use {suffix( pattern)} to add the output of
pattern at the end of each stack frames.
Use a {separator(...)} as the end-ofline string. For example: separator(|). The
default value is the line.separator system
property, which is operating system dependent.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

189

F
file

Outputs the file name where the logging request
was issued.
Generating the file information ( location
information) is an expensive operation and may
impact performance. Use with caution.

highlight{pattern}{style}

Adds ANSI colors to the result of the enclosed
pattern based on the current event's logging
level. (See Jansi configuration.)
The default colors for each level are:
Level

ANSI color

FATAL

Bright red

ERROR

Bright red

WARN

Yellow

INFO

Green

DEBUG

Cyan

TRACE

Black (looks dark grey)

The color names are ANSI names defined in the
AnsiEscape class.
The color and attribute names and are standard,
but the exact shade, hue, or value.
Intensity
Code0
1

2

3

4

5

6

7

Black Red GreenYellowBlue Magenta
Cyan White
Normal
Black Red GreenYellowBlue Magenta
Cyan White
Bright

Color table
You can use the default colors with:
%highlight{%d [%t] %-5level: %msg%n%throwable}

You can override the default colors in the
optional {style} option. For example:
%highlight{%d [%t] %-5level: %msg%n%throwable}
{FATAL=white, ERROR=red, WARN=blue, INFO=black,
DEBUG=green, TRACE=blue}

You can highlight only the a portion of the log
event:
%d [%t] %highlight{%-5level: %msg%n%throwable}

You can style one part of the message and
highlight the rest the log event:
%style{%d [%t]}{black} %highlight{%-5level:
%msg%n%throwable}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

190

You can also use the STYLE key to use a
predefined group of colors:
%highlight{%d [%t] %-5level: %msg%n%throwable}
{STYLE=Logback}

The STYLE value can be one of:
Style

Description

Default

See above

Logback

Level

ANSI
color

FATAL

Blinking
bright red

ERROR

Bright red

WARN

Red

INFO

Blue

DEBUG

Normal

TRACE

Normal

K{key}
map{key}
MAP{key}

Outputs the entries in a MapMessage, if one is
present in the event. The K conversion character
can be followed by the key for the map placed
between braces, as in %K{clientNumber}
where clientNumber is the key. The value in
the Map corresponding to the key will be output.
If no additional sub-option is specified, then the
entire contents of the Map key value pair set is
output using a format {{key1,val1},{key2,val2}}

l
location

Outputs location information of the caller which
generated the logging event.
The location information depends on the JVM
implementation but usually consists of the fully
qualified name of the calling method followed by
the callers source the file name and line number
between parentheses.
Generating location information is an expensive
operation and may impact performance. Use with
caution.

L
line

Outputs the line number from where the logging
request was issued.
Generating line number information ( location
information) is an expensive operation and may
impact performance. Use with caution.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

191

m{nolookups}{ansi}
msg{nolookups}{ansi}
message{nolookups}{ansi}

Outputs the application supplied message
associated with the logging event.
Add {ansi} to render messages with ANSI
escape codes (requires JAnsi, see configuration.)
The default syntax for embedded ANSI codes is:
@|
code(,
code)*
text|@

For example, to render the message "Hello" in
green, use:
@|green Hello|@

To render the message "Hello" in bold and red,
use:
@|bold,red Warning!|@

You can also define custom style names in the
configuration with the syntax:

%message{ansi}{StyleName=value(,value)*( StyleName=value(,valu

For example:

%message{ansi}{WarningStyle=red,bold KeyStyle=white ValueStyle

The call site can look like this:

logger.info("@|KeyStyle {}|@ = @|ValueStyle {}|@", entry.getKe

Use {nolookups} to log messages like
"${esc.d}{date:YYYY-MM-dd}"

without using any lookups. Normally calling
logger.info("Try ${esc.d}{date:YYYYMM-dd}") would replace the date template
${esc.d}{date:YYYY-MM-dd} with an actual
date. Using nolookups disables this feature and

logs the message string untouched.
M
method

Outputs the method name where the logging
request was issued.
Generating the method name of the caller (
location information) is an expensive operation
and may impact performance. Use with caution.

marker
markerSimpleName

The full name of the marker, including parents, if one
is present.
The simple name of the marker (not including
parents), if one is present.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

192

maxLen
maxLength

Outputs the result of evaluating the pattern and
truncating the result. If the length is greater than
20, then the output will contain a trailing ellipsis.
If the provided length is invalid, a default value
of 100 is used.
Example syntax: %maxLen{%p: %c{1} - %m
%notEmpty{ =>%ex{short}}}{160} will be
limited to 160 characters with a trailing ellipsis.
Another example: %maxLen{%m}{20} will be
limited to 20 characters and no trailing ellipsis.

n

Outputs the platform dependent line separator
character or characters.
This conversion character offers practically
the same performance as using non-portable
line separator strings such as "\n", or "\r\n".
Thus, it is the preferred way of specifying a line
separator.

N
nano

Outputs the result of System.nanoTime() at
the time the log event was created.

pid{[defaultValue]}
processId{[defaultValue]}

Outputs the process ID if supported by the
underlying platform. An optional default value
may be specified to be shown if the platform
does not support process IDs.

variablesNotEmpty{pattern}
varsNotEmpty{pattern}
notEmpty{pattern}

Outputs the result of evaluating the pattern if and
only if all variables in the pattern are not empty.
For example:
%notEmpty{[%marker]}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

193

p| level{ level= label, level= label, ...} p|
level{length= n} p| level{lowerCase= true| false}

Outputs the level of the logging event.
You provide a level name map in the form
"level=value, level=value" where level is the
name of the Level and value is the value that
should be displayed instead of the name of the
Level.
For example:

%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, IN

Alternatively, for the compact-minded:
%level{WARN=W, DEBUG=D, ERROR=E, TRACE=T, INFO=I}

More succinctly, for the same result as above,
you can define the length of the level label:
%level{length=1}

If the length is greater than a level name length,
the layout uses the normal level name.
You can combine the two kinds of options:
%level{ERROR=Error, length=2}

This give you the Error level name and all other
level names of length 2.
Finally, you can output lower-case level names
(the default is upper-case):
%level{lowerCase=true}

r
relative
replace{pattern}{regex}{substitution}

Outputs the number of milliseconds elapsed since
the JVM was started until the creation of the logging
event.

Replaces occurrences of 'regex', a regular
expression, with its replacement 'substitution'
in the string resulting from evaluation of the
pattern. For example, "%replace{%msg}{\s}
{}" will remove all spaces contained in the event
message.
The pattern can be arbitrarily complex and
in particular can contain multiple conversion
keywords. For instance, "%replace{%logger
%msg}{\.}{/}" will replace all dots in the logger
or the message of the event with a forward slash.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

194

rEx| rException| rThrowable
{
["none" | "short" | "full" | depth]
[,filters(package,package,...)]
[,separator( separator)]
}
{ansi(
Key=Value,Value,...
Key=Value,Value,...
...)
}
{suffix( pattern)}

The same as the %throwable conversion word
but the stack trace is printed starting with the
first exception that was thrown followed by each
subsequent wrapping exception.
The throwable conversion word can be followed
by an option in the form %rEx{short} which
will only output the first line of the Throwable or
%rEx{n} where the first n lines of the stack trace
will be printed.
Specifying %rEx{none} or %rEx{0} will
suppress printing of the exception.
Use filters( packages) where packages
is a list of package names to suppress matching
stack frames from stack traces.
Use a separator string to separate the lines of
a stack trace. For example: separator(|). The
default value is the line.separator system
property, which is operating system dependent.
Use rEx{suffix( pattern) to add the output
of pattern to the output only when there is a
throwable to print.

sn
sequenceNumber

Includes a sequence number that will be incremented
in every event. The counter is a static variable so will
only be unique within applications that share the same
converter Class object.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

195

style{pattern}{ANSI style}

Uses ANSI escape sequences to style the result
of the enclosed pattern. The style can consist of
a comma separated list of style names from the
following table. (See Jansi configuration.)
Style Name

Description

Normal

Normal display

Bright

Bold

Dim

Dimmed or faint
characters

Underline

Underlined characters

Blink

Blinking characters

Reverse

Reverse video

Hidden
Black or FG_Black

Set foreground color to
black

Red or FG_Red

Set foreground color to
red

Green or FG_Green

Set foreground color to
green

Yellow or FG_Yellow

Set foreground color to
yellow

Blue or FG_Blue

Set foreground color to
blue

Magenta or FG_Magenta Set foreground color to
magenta
Cyan or FG_Cyan

Set foreground color to
cyan

White or FG_White

Set foreground color to
white

Default or FG_Default

Set foreground color to
default (white)

BG_Black

Set background color to
black

BG_Red

Set background color to
red

BG_Green

Set background color to
green

BG_Yellow

Set background color to
yellow

BG_Blue

Set background color to
blue

BG_Magenta

Set background color to
magenta

BG_Cyan

Set background color to
cyan

BG_White

Set background color to
white

For example:
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

%style{%d{ISO8601}}{black} %style{[%t]}{blue} %style{%-5level:

You can also combine styles:
%d %highlight{%p} %style{%logger}{bright,cyan} %C{1.} %msg%n

10 Layouts

196

T
tid
threadId

Outputs the ID of the thread that generated the logging
event.

t
tn
thread
threadName

Outputs the name of the thread that generated the
logging event.

tp
threadPriority

Outputs the priority of the thread that generated the
logging event.

fqcn

Outputs the fully qualified class name of the logger.

endOfBatch

Outputs the EndOfBatch status of the logging event,
as "true" or "false".

x
NDC

Outputs the Thread Context Stack (also known as the
Nested Diagnostic Context or NDC) associated with
the thread that generated the logging event.

X{key[,key2...]}
mdc{key[,key2...]}
MDC{key[,key2...]}

Outputs the Thread Context Map (also
known as the Mapped Diagnostic Context
or MDC) associated with the thread that
generated the logging event. The X conversion
character can be followed by one or more
keys for the map placed between braces, as in
%X{clientNumber} where clientNumber is
the key. The value in the MDC corresponding to
the key will be output.
If a list of keys are provided, such as %X{name,
number}, then each key that is present in the
ThreadContext will be output using the format
{name=val1, number=val2}. The key/value pairs
will be printed in the order they appear in the list.
If no sub-options are specified then the entire
contents of the MDC key value pair set is output
using a format {key1=val1, key2=val2}. The
key/value pairs will be printed in sorted order.
See the ThreadContext class for more details.

u{"RANDOM" | "TIME"}
uuid

Includes either a random or a time-based UUID.
The time-based UUID is a Type 1 UUID that can
generate up to 10,000 unique ids per millisecond,
will use the MAC address of each host, and to try
to insure uniqueness across multiple JVMs and/or
ClassLoaders on the same host a random number
between 0 and 16,384 will be associated with each
instance of the UUID generator Class and included
in each time-based UUID generated. Because
time-based UUIDs contain the MAC address and
timestamp they should be used with care as they can
cause a security vulnerability.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

197

xEx| xException| xThrowable
{
["none" | "short" | "full" | depth]
[,filters(package,package,...)]
[,separator( separator)]
}
{ansi(
Key=Value,Value,...
Key=Value,Value,...
...)
}
{suffix( pattern)}

The same as the %throwable conversion word
but also includes class packaging information.
At the end of each stack element of the
exception, a string containing the name of the
jar file that contains the class or the directory
the class is located in and the "ImplementationVersion" as found in that jar's manifest will be
added. If the information is uncertain, then the
class packaging data will be preceded by a tilde,
i.e. the '~' character.
The throwable conversion word can be followed
by an option in the form %xEx{short} which
will only output the first line of the Throwable
or %xEx{n} where the first n lines of the stack
trace will be printed. Specifying %xEx{none} or
%xEx{0} will suppress printing of the exception.
Use filters( packages) where packages
is a list of package names to suppress matching
stack frames from stack traces.
Use a separator string to separate the lines of
a stack trace. For example: separator(|). The
default value is the line.separator system
property, which is operating system dependent.
The ansi option renders stack traces with
ANSI escapes code using the JAnsi library.
(See configuration.) Use {ansi} to use the
default color mapping. You can specify your
own mappings with key=value pairs. The keys
are:
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•

Prefix
Name
NameMessageSeparator
Message
At
CauseLabel
Text
More
Suppressed
StackTraceElement.ClassName
StackTraceElement.ClassMethodSeparator
StackTraceElement.MethodName
StackTraceElement.NativeMethod
StackTraceElement.FileName
StackTraceElement.LineNumber
StackTraceElement.Container
StackTraceElement.ContainerSeparator
StackTraceElement.UnknownSource
ExtraClassInfo.Inexact
ExtraClassInfo.Container
ExtraClassInfo.ContainerSeparator
ExtraClassInfo.Location
ExtraClassInfo.Version

The values are names from JAnsi's Code class
like blue, bg_red, and so on (Log4j ignores
case.)

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

The special key StyleMapName can be set to

10 Layouts

198

%

The sequence %% outputs a single percent sign.

By default the relevant information is output as is. However, with the aid of format modifiers it is
possible to change the minimum field width, the maximum field width and justification.
The optional format modifier is placed between the percent sign and the conversion character.
The first optional format modifier is the left justification flag which is just the minus (-) character.
Then comes the optional minimum field width modifier. This is a decimal constant that represents the
minimum number of characters to output. If the data item requires fewer characters, it is padded on
either the left or the right until the minimum width is reached. The default is to pad on the left (right
justify) but you can specify right padding with the left justification flag. The padding character is
space. If the data item is larger than the minimum field width, the field is expanded to accommodate
the data. The value is never truncated.
This behavior can be changed using the maximum field width modifier which is designated by
a period followed by a decimal constant. If the data item is longer than the maximum field, then
the extra characters are removed from the beginning of the data item and not from the end. For
example, it the maximum field width is eight and the data item is ten characters long, then the first
two characters of the data item are dropped. This behavior deviates from the printf function in C
where truncation is done from the end.
Truncation from the end is possible by appending a minus character right after the period. In that
case, if the maximum field width is eight and the data item is ten characters long, then the last two
characters of the data item are dropped.
Below are various format modifier examples for the category conversion specifier.
Format modifier

left justify

minimum width

maximum width

comment

%20c

false

20

none

Left pad with spaces
if the category name
is less than 20
characters long.

%-20c

true

20

none

Right pad with
spaces if the
category name
is less than 20
characters long.

%.30c

NA

none

30

Truncate from the
beginning if the
category name
is longer than 30
characters.

%20.30c

false

20

30

Left pad with spaces
if the category
name is shorter
than 20 characters.
However, if category
name is longer than
30 characters, then
truncate from the
beginning.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

199

%-20.30c

true

20

30

Right pad with
spaces if the
category name
is shorter than
20 characters.
However, if category
name is longer than
30 characters, then
truncate from the
beginning.

%-20.-30c

true

20

30

Right pad with
spaces if the
category name
is shorter than
20 characters.
However, if category
name is longer than
30 characters, then
truncate from the
end.

Pattern Converters

10.1.5.2 ANSI Styling on Windows

ANSI escape sequences are supported natively on many platforms but are not by default on Windows.
To enable ANSI support add the Jansi jar to your application and set property log4j.skipJansi to
false. This allows Log4j to use Jansi to add ANSI escape codes when writing to the console.
NOTE: Prior to Log4j 2.10, Jansi was enabled by default. The fact that Jansi requires native code
means that Jansi can only be loaded by a single class loader. For web applications this means the Jansi
jar has to be in the web container's classpath. To avoid causing problems for web applications, Log4j
will no longer automatically try to load Jansi without explicit configuration from Log4j 2.10 onward.
10.1.5.3 Example Patterns
10.Filtered Throwables

This example shows how to filter out classes from unimportant packages in stack traces.

org.junit,org.apache.maven,sun.reflect,java.lang.reflect

...


The result printed to the console will appear similar to:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

200

Exception java.lang.IllegalArgumentException: IllegalArgument
at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.
testException(ExtendedThrowableTest.java:72) [test-classes/:?]
... suppressed 26 lines
at $Proxy0.invoke(Unknown Source)} [?:?]
... suppressed 3 lines
Caused by: java.lang.NullPointerException: null pointer
at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.
testException(ExtendedThrowableTest.java:71) ~[test-classes/:?]
... 30 more

10.ANSI Styled

The log level will be highlighted according to the event's log level. All the content that follows the
level will be bright green.

%d %highlight{%p} %style{%C{1.} [%t] %m}{bold,green}%n


10.1.5.4 Pattern Selectors

The PatternLayout can be configured with a PatternSelector to allow it to choose a pattern to
use based on attributes of the log event or other factors. A PatternSelector will normally be
configured with a defaultPattern attribute, which is used when other criteria don't match, and a set of
PatternMatch elements that identify the various patterns that can be selected.
10.MarkerPatternSelector

The MarkerPatternSelector selects patterns based on the Marker included in the log event. If the
Marker in the log event is equal to or is an ancestor of the name specified on the PatternMatch key
attribute, then the pattern specified on that PatternMatch element will be used.






10.ScriptPatternSelector

The ScriptPatternSelector executes a script as descibed in the Scripts section of the Configuration
chapter. The script is passed all the properties configured in the Properties section of the
configuration, the StrSubstitutor used by the Confguration in the "substitutor" vairables, and the log
event in the "logEvent" variable, and is expected to return the value of the PatternMatch key that
should be used, or null if the default pattern should be used.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

201









10.1.6 RFC5424 Layout

As the name implies, the Rfc5424Layout formats LogEvents in accordance with RFC 5424, the
enhanced Syslog specification. Although the specification is primarily directed at sending messages
via Syslog, this format is quite useful for other purposes since items are passed in the message as selfdescribing key/value pairs.
Parameter Name

Type

Description

appName

String

The value to use as the APPNAME in the RFC 5424 syslog
record.

charset

String

The character set to use when
converting the syslog String to a
byte array. The String must be
a valid Charset. If not specified,
the default system Charset will be
used.

enterpriseNumber

integer

The IANA enterprise number as
described in RFC 5424

exceptionPattern

String

One of the conversion specifiers
from PatternLayout that defines
which ThrowablePatternConverter
to use to format exceptions. Any
of the options that are valid for
those specifiers may be included.
The default is to not include the
Throwable from the event, if any, in
the output.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

202

facility

String

The facility is used to try to classify
the message. The facility option
must be set to one of "KERN",
"USER", "MAIL", "DAEMON",
"AUTH", "SYSLOG", "LPR",
"NEWS", "UUCP", "CRON",
"AUTHPRIV", "FTP", "NTP",
"AUDIT", "ALERT", "CLOCK",
"LOCAL0", "LOCAL1", "LOCAL2",
"LOCAL3", "LOCAL4", "LOCAL5",
"LOCAL6", or "LOCAL7". These
values may be specified as upper
or lower case characters.

format

String

If set to "RFC5424" the data will
be formatted in accordance with
RFC 5424. Otherwise, it will be
formatted as a BSD Syslog record.
Note that although BSD Syslog
records are required to be 1024
bytes or shorter the SyslogLayout
does not truncate them. The
RFC5424Layout also does not
truncate records since the receiver
must accept records of up to 2048
bytes and may accept records that
are longer.

id

String

The default structured data id to
use when formatting according to
RFC 5424. If the LogEvent contains
a StructuredDataMessage the id
from the Message will be used
instead of this value.

includeMDC

boolean

Indicates whether data from the
ThreadContextMap will be included
in the RFC 5424 Syslog record.
Defaults to true.

loggerFields

List of KeyValuePairs

Allows arbitrary PatternLayout
patterns to be included as
specified ThreadContext fields;
no default specified. To use,
include a  nested
element, containing one or more
 elements. Each
 must have a key
attribute, which specifies the key
name which will be used to identify
the field within the MDC Structured
Data element, and a value attribute,
which specifies the PatternLayout
pattern to use as the value.

mdcExcludes

String

A comma separated list of mdc
keys that should be excluded from
the LogEvent. This is mutually
exclusive with the mdcIncludes
attribute. This attribute only applies
to RFC 5424 syslog records.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

203

mdcIncludes

String

A comma separated list of mdc
keys that should be included in
the FlumeEvent. Any keys in the
MDC not found in the list will be
excluded. This option is mutually
exclusive with the mdcExcludes
attribute. This attribute only applies
to RFC 5424 syslog records.

mdcRequired

String

A comma separated list of mdc
keys that must be present in the
MDC. If a key is not present a
LoggingException will be thrown.
This attribute only applies to RFC
5424 syslog records.

mdcPrefix

String

A string that should be prepended
to each MDC key in order to
distinguish it from event attributes.
The default string is "mdc:". This
attribute only applies to RFC 5424
syslog records.

mdcId

String

A required MDC ID. This attribute
only applies to RFC 5424 syslog
records.

messageId

String

The default value to be used in the
MSGID field of RFC 5424 syslog
records.

newLine

boolean

If true, a newline will be appended
to the end of the syslog record. The
default is false.

newLineEscape

String

String that should be used to
replace newlines within the
message text.

Rfc5424Layout Parameters

10.1.7 Serialized Layout

The SerializedLayout simply serializes the LogEvent into a byte array using Java Serialization. The
SerializedLayout accepts no parameters.
This layout is deprecated since version 2.9. Java Serialization has inherent security weaknesses, using
this layout is no longer recommended. An alternative layout containing the same information is
JsonLayout, configured with properties="true".

10.1.8 Syslog Layout

The SyslogLayout formats the LogEvent as BSD Syslog records matching the same format used by
Log4j 1.2.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

204

charset

String

The character set to use when
converting the syslog String to a
byte array. The String must be a
valid Charset. If not specified, this
layout uses UTF-8.

facility

String

The facility is used to try to classify
the message. The facility option
must be set to one of "KERN",
"USER", "MAIL", "DAEMON",
"AUTH", "SYSLOG", "LPR",
"NEWS", "UUCP", "CRON",
"AUTHPRIV", "FTP", "NTP",
"AUDIT", "ALERT", "CLOCK",
"LOCAL0", "LOCAL1", "LOCAL2",
"LOCAL3", "LOCAL4", "LOCAL5",
"LOCAL6", or "LOCAL7". These
values may be specified as upper
or lower case characters.

newLine

boolean

If true, a newline will be appended
to the end of the syslog record. The
default is false.

newLineEscape

String

String that should be used to
replace newlines within the
message text.

SyslogLayout Parameters

10.1.9 XML Layout

Appends a series of Event elements as defined in the log4j.dtd.
10.1.9.1 Complete well-formed XML vs. fragment XML

If you configure complete="true", the appender outputs a well-formed XML document where
the default namespace is the Log4j namespace "http://logging.apache.org/log4j/2.0/
events". By default, with complete="false", you should include the output as an external
entity in a separate file to form a well-formed XML document, in which case the appender uses
namespacePrefix with a default of "log4j".
A well-formed XML document follows this pattern:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

205












Hello, world!





one
two









If complete="false", the appender does not write the XML processing instruction and the root
element.
10.1.9.2 Marker

Markers are represented by a Marker element within the Event element. The Marker element
appears only when a marker is used in the log message. The name of the marker's parent will be
provided in the parent attribute of the Marker element.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

206

10.1.9.3 Pretty vs. compact XML

By default, the XML layout is not compact (a.k.a. not "pretty") with compact="false",
which means the appender uses end-of-line characters and indents lines to format the XML. If
compact="true", then no end-of-line or indentation is used. Message content may contain, of
course, end-of-lines.
Parameter Name

Type

Description

charset

String

The character set to use when
converting to a byte array. The
value must be a valid Charset. If
not specified, UTF-8 will be used.

compact

boolean

If true, the appender does not
use end-of-lines and indentation.
Defaults to false.

complete

boolean

If true, the appender includes the
XML header and footer. Defaults to
false.

properties

boolean

If true, the appender includes
the thread context map in the
generated XML. Defaults to false.

locationInfo

boolean

If true, the appender includes
the location information in the
generated XML. Defaults to
false.
Generating location
information is an expensive
operation and may impact
performance. Use with caution.

includeStacktrace

boolean

If true, include full stacktrace of
any logged Throwable (optional,
default to true).

stacktraceAsString

boolean

Whether to format the stacktrace
as a string, and not a nested object
(optional, defaults to false).

includeNullDelimiter

boolean

Whether to include NULL byte as
delimiter after each event (optional,
default to false).

XmlLayout Parameters
To include any custom field in the output, use following syntax:





Custom fields are always last, in the order they are declared. The values support lookups.
Additional runtime dependencies are required for using XmlLayout.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

207

10.1.10 YAML Layout

Appends a series of YAML events as strings serialized as bytes.
A YAML log event follows this pattern:
--instant:
epochSecond: 1493121664
nanoOfSecond: 118000000
thread: "main"
level: "INFO"
loggerName: "HelloWorld"
marker:
name: "child"
parents:
- name: "parent"
parents:
- name: "grandparent"
message: "Hello, world!"
thrown:
commonElementCount: 0
message: "error message"
name: "java.lang.RuntimeException"
extendedStackTrace:
- class: "logtest.Main"
method: "main"
file: "Main.java"
line: 29
exact: true
location: "classes/"
version: "?"
contextStack:
- "one"
- "two"
endOfBatch: false
loggerFqcn: "org.apache.logging.log4j.spi.AbstractLogger"
contextMap:
bar: "BAR"
foo: "FOO"
threadId: 1
threadPriority: 5
source:
class: "logtest.Main"
method: "main"
file: "Main.java"
line: 29

Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

208

charset

String

The character set to use when
converting to a byte array. The
value must be a valid Charset. If
not specified, UTF-8 will be used.

properties

boolean

If true, the appender includes
the thread context map in the
generated YAML. Defaults to false.

locationInfo

boolean

If true, the appender includes
the location information in the
generated YAML. Defaults to
false.
Generating location
information is an expensive
operation and may impact
performance. Use with caution.

includeStacktrace

boolean

If true, include full stacktrace of
any logged Throwable (optional,
default to true).

stacktraceAsString

boolean

Whether to format the stacktrace
as a string, and not a nested object
(optional, defaults to false).

includeNullDelimiter

boolean

Whether to include NULL byte as
delimiter after each event (optional,
default to false).

YamlLayout Parameters
To include any custom field in the output, use following syntax:





Custom fields are always last, in the order they are declared. The values support lookups.
Additional runtime dependencies are required for using YamlLayout.

10.1.11 Location Information

If one of the layouts is configured with a location-related attribute like HTML locationInfo, or one of
the patterns %C or %class, %F or %file, %l or %location, %L or %line, %M or %method, Log4j
will take a snapshot of the stack, and walk the stack trace to find the location information.
This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. Synchronous loggers
wait as long as possible before they take this stack snapshot. If no location is required, the snapshot
will never be taken.
However, asynchronous loggers need to make this decision before passing the log message to another
thread; the location information will be lost after that point. The performance impact of taking a stack
trace snapshot is even higher for asynchronous loggers: logging with location is 30-100 times slower

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

10 Layouts

than without location. For this reason, asynchronous loggers and asynchronous appenders do not
include location information by default.
You can override the default behaviour in your logger or asynchronous appender configuration by
specifying includeLocation="true".

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

209

11 Filters

210

11 Filters

.......................................................................................................................................
11.1 Filters
Filters allow Log Events to be evaluated to determine if or how they should be published. A Filter
will be called on one of its filter methods and will return a Result, which is an Enum that has one of 3
values - ACCEPT, DENY or NEUTRAL.
Filters may be configured in one of four locations:
1. Context-wide Filters are configured directly in the configuration. Events that are rejected by
these filters will not be passed to loggers for further processing. Once an event has been accepted
by a Context-wide filter it will not be evaluated by any other Context-wide Filters nor will the
Logger's Level be used to filter the event. The event will be evaluated by Logger and Appender
Filters however.
2. Logger Filters are configured on a specified Logger. These are evaluated after the Contextwide Filters and the Log Level for the Logger. Events that are rejected by these filters will be
discarded and the event will not be passed to a parent Logger regardless of the additivity setting.
3. Appender Filters are used to determine if a specific Appender should handle the formatting and
publication of the event.
4. Appender Reference Filters are used to determine if a Logger should route the event to an
appender.

11.1.1 BurstFilter

The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by silently
discarding events after the maximum limit has been reached.
Parameter Name

Type

Description

level

String

Level of messages to be filtered.
Anything at or below this level will
be filtered out if maxBurst has
been exceeded. The default is
WARN meaning any messages that
are higher than warn will be logged
regardless of the size of a burst.

rate

float

The average number of events per
second to allow.

maxBurst

integer

The maximum number of events
that can occur before events are
filtered for exceeding the average
rate. The default is 10 times the
rate.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

onMismatch

211

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Burst Filter Parameters
A configuration containing the BurstFilter might look like:






%d %p %c{1.} [%t] %m%n











11.1.2 CompositeFilter

The CompositeFilter provides a way to specify more than one filter. It is added to the configuration as
a filters element and contains other filters to be evaluated. The filters element accepts no parameters.
A configuration containing the CompositeFilter might look like:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

212












%d %p %c{1.} [%t] %m%n





%d %p %c{1.} [%t] %m%n














11.1.3 DynamicThresholdFilter

The DynamicThresholdFilter allows filtering by log level based on specific attributes. For example,
if the user's loginId is being captured in the ThreadContext Map then it is possible to enable debug
logging for only that user. If the log event does not contain the specified ThreadContext item
NEUTRAL will be returned.
Parameter Name

Type

Description

key

String

The name of the item in the
ThreadContext Map to compare.

defaultThreshold

String

Level of messages to be filtered.
The default threshold only applies if
the log event contains the specified
ThreadContext Map item and its
value does not match any key in
the key/value pairs.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

213

keyValuePair

KeyValuePair[]

One or more KeyValuePair
elements that define the matching
value for the key and the Level to
evaluate when the key matches.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Dynamic Threshold Filter Parameters
Here is a sample configuration containing the DynamicThresholdFilter:









%d %p %c{1.} [%t] %m%n











11.1.4 MapFilter

The MapFilter allows filtering against data elements that are in a MapMessage.
Parameter Name

Type

Description

keyValuePair

KeyValuePair[]

One or more KeyValuePair
elements that define the key in the
map and the value to match on.
If the same key is specified more
than once then the check for that
key will automatically be an "or"
since a Map can only contain a
single value.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

214

operator

String

If the operator is "or" then a match
by any one of the key/value pairs
will be considered to be a match,
otherwise all the key/value pairs
must match.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Map Filter Parameters
As in this configuration, the MapFilter can be used to log particular events:










%d %p %c{1.} [%t] %m%n











This sample configuration will exhibit the same behavior as the preceding example since the only
logger configured is the root.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

215







%d %p %c{1.} [%t] %m%n
















This third sample configuration will exhibit the same behavior as the preceding examples since the
only logger configured is the root and the root is only configured with a single appender reference.






%d %p %c{1.} [%t] %m%n
















©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

216

11.1.5 MarkerFilter

The MarkerFilter compares the configured Marker value against the Marker that is included in the
LogEvent. A match occurs when the Marker name matches either the Log Event's Marker or one of its
parents.
Parameter Name

Type

Description

marker

String

The name of the Marker to
compare.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Marker Filter Parameters
A sample configuration that only allows the event to be written by the appender if the Marker
matches:






%d %p %c{1.} [%t] %m%n











11.1.6 RegexFilter

The RegexFilter allows the formatted or unformatted message to be compared against a regular
expression.
Parameter Name

Type

Description

regex

String

The regular expression.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

217

useRawMsg

boolean

If true the unformatted message will
be used, otherwise the formatted
message will be used. The default
value is false.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Regex Filter Parameters
A sample configuration that only allows the event to be written by the appender if it contains the word
"test":






%d %p %c{1.} [%t] %m%n











11.1.7 Script

The ScriptFilter executes a script that returns true or false.
Parameter Name

Type

Description

script

Script, ScriptFile or ScriptRef

The Script element that specifies
the logic to be executed.

onMatch

String

Action to take when the script
returns true. May be ACCEPT,
DENY or NEUTRAL. The default
value is NEUTRAL.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

onMismatch

218

String

Action to take when the filter
returns false. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Script Filter Parameters
Parameter Name

Type

Description

configuration

Configuration

The Configuration that owns this
ScriptFilter.

level

Level

The logging Level associated with
the event. Only present when
configured as a global filter.

loggerName

String

The name of the logger. Only
present when configured as a
global filter.

logEvent

LogEvent

The LogEvent being processed.
Not present when configured as a
global filter.

marker

Marker

The Marker passed on the logging
call, if any. Only present when
configured as a global filter.

message

Message

The Message associated with the
logging call. Only present when
configured as a global filter.

parameters

Object[]

The parameters passed to the
logging call. Only present when
configured as a global filter. Some
Messages include the parameters
as part of the Message.

throwable

Throwable

The Throwable passed to the
logging call, if any. Only present
when configured as a global filter.
Som Messages include Throwable
as part of the Message.

substitutor

StrSubstitutor

The StrSubstitutor used to replace
lookup variables.

Script Parameters
The sample below shows how to declare script fields and then reference them in specific components.
See ScriptCondition for an example of how the Script element can be used to embed script code
directly in the configuration.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

219































11.1.8 StructuredDataFilter

The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message.
Parameter Name

Type

Description

keyValuePair

KeyValuePair[]

One or more KeyValuePair
elements that define the key
in the map and the value to
match on. "id", "id.name",
"type", and "message" should
be used to match on the
StructuredDataId, the name portion
of the StructuredDataId, the
type, and the formatted message
respectively. If the same key is
specified more than once then the
check for that key will automatically
be an "or" since a Map can only
contain a single value.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

220

operator

String

If the operator is "or" then a match
by any one of the key/value pairs
will be considered to be a match,
otherwise all the key/value pairs
must match.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

StructuredData Filter Parameters
As in this configuration, the StructuredDataFilter can be used to log particular events:










%d %p %c{1.} [%t] %m%n











11.1.9 ThreadContextMapFilter (or ContextMapFilter)

The ThreadContextMapFilter or ContextMapFilter allows filtering against data elements that are in
the current context. By default this is the ThreadContext Map.
Parameter Name

Type

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

221

keyValuePair

KeyValuePair[]

One or more KeyValuePair
elements that define the key in the
map and the value to match on.
If the same key is specified more
than once then the check for that
key will automatically be an "or"
since a Map can only contain a
single value.

operator

String

If the operator is "or" then a match
by any one of the key/value pairs
will be considered to be a match,
otherwise all the key/value pairs
must match.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Context Map Filter Parameters
A configuration containing the ContextMapFilter might look like:










%d %p %c{1.} [%t] %m%n











The ContextMapFilter can also be applied to a logger for filtering:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

222







%d %p %c{1.} [%t] %m%n















11.1.10 ThresholdFilter

This filter returns the onMatch result if the level in the LogEvent is the same or more specific than
the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter is
configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value
will be returned since ERROR events are more specific than DEBUG.
Parameter Name

Type

Description

level

String

A valid Level name to match on.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Threshold Filter Parameters
A sample configuration that only allows the event to be written by the appender if the level matches:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters

223







%d %p %c{1.} [%t] %m%n











11.1.11 TimeFilter

The time filter can be used to restrict filter to only a certain portion of the day.
Parameter Name

Type

Description

start

String

A time in HH:mm:ss format.

end

String

A time in HH:mm:ss format.
Specifying an end time less than
the start time will result in no log
entries being written.

timezone

String

The timezone to use when
comparing to the event timestamp.

onMatch

String

Action to take when the filter
matches. May be ACCEPT, DENY
or NEUTRAL. The default value is
NEUTRAL.

onMismatch

String

Action to take when the filter does
not match. May be ACCEPT,
DENY or NEUTRAL. The default
value is DENY.

Time Filter Parameters
A sample configuration that only allows the event to be written by the appender from 5:00 to 5:30 am
each day using the default timezone:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

11 Filters







%d %p %c{1.} [%t] %m%n











©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

224

12 Async Loggers

225

12 Async Loggers

.......................................................................................................................................
12.1 Asynchronous Loggers for Low-Latency Logging
Asynchronous logging can improve your application's performance by executing the I/O operations in
a separate thread. Log4j 2 makes a number of improvements in this area.
• Asynchronous Loggers are a new addition in Log4j 2. Their aim is to return from the call to
Logger.log to the application as soon as possible. You can choose between making all Loggers
asynchronous or using a mixture of synchronous and asynchronous Loggers. Making all Loggers
asynchronous will give the best performance, while mixing gives you more flexibility.
• LMAX Disruptor technology. Asynchronous Loggers internally use the Disruptor, a lock-free
inter-thread communication library, instead of queues, resulting in higher throughput and lower
latency.
• As part of the work for Async Loggers, Asynchronous Appenders have been enhanced to
flush to disk at the end of a batch (when the queue is empty). This produces the same result as
configuring "immediateFlush=true", that is, all received log events are always available on disk,
but is more efficient because it does not need to touch the disk on each and every log event.
(Async Appenders use ArrayBlockingQueue internally and do not need the disruptor jar on the
classpath.)

12.1.1 Trade-offs

Although asynchronous logging can give significant performance benefits, there are situations where
you may want to choose synchronous logging. This section describes some of the trade-offs of
asynchronous logging.
Benefits
• Higher peak throughput. With an asynchronous logger your application can log messages at 6 68 times the rate of a synchronous logger.
This is especially interesting for applications that occasionally need to log bursts of messages.
Async logging can help prevent or dampen latency spikes by shortening the wait time until the
next message can be logged. If the queue size is configured large enough to handle the burst,
asynchronous logging will help prevent your application from falling behind (as much) during a
sudden increase of activity.
• Lower logging response time latency. Response time latency is the time it takes for a call to
Logger.log to return under a given workload. Asynchronous Loggers have consistently lower
latency than synchronous loggers or even queue-based asynchronous appenders.
Drawbacks
• Error handling. If a problem happens during the logging process and an exception is thrown, it
is less easy for an asynchronous logger or appender to signal this problem to the application.
This can partly be alleviated by configuring an ExceptionHandler, but this may still not cover
all cases. For this reason, if logging is part of your business logic, for example if you are using
Log4j as an audit logging framework, we would recommend to synchronously log those audit
messages. (Note that you can still combine them and use asynchronous logging for debug/trace
logging in addition to synchronous logging for the audit trail.)
• In some rare cases, care must be taken with mutable messages. Most of the time you don't need
to worry about this. Log4 will ensure that log messages like logger.debug("My object
is {}", myObject) will use the state of the myObject parameter at the time of the call to
logger.debug(). The log message will not change even if myObject is modified later. It is
safe to asynchronously log mutable objects because most Message implementations built-in to

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

226

Log4j take a snapshot of the parameters. There are some exceptions however: MapMessage and
StructuredDataMessage are mutable by design: fields can be added to these messages after the
message object was created. These messages should not be modified after they are logged with
asynchronous loggers or asynchronous appenders; you may or may not see the modifications in
the resulting log output. Similarly, custom Message implementations should be designed with
asynchronous use in mind, and either take a snapshot of their parameters at construction time, or
document their thread-safety characteristics.
• If your application is running in an environment where CPU resources are scarce, like a machine
with one CPU with a single core, starting another thread is not likely to give better performance.
• If the sustained rate at which your application is logging messages is faster than the maximum
sustained throughput of the underlying appender, the queue will fill up and the application will
end up logging at the speed of the slowest appender. If this happens, consider selecting a faster
appender, or logging less. If neither of these is an option, you may get better throughput and
fewer latency spikes by logging synchronously.

12.1.2 Making All Loggers Asynchronous

Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to Log4j-2.9,
disruptor-3.0.0.jar or higher was required.
This is simplest to configure and gives the best performance. To make all loggers asynchronous,
add the disruptor jar to the classpath and set the system property log4j2.contextSelector to
org.apache.logging.log4j.core.async.AsyncLoggerContextSelector.
By default, location is not passed to the I/O thread by asynchronous loggers. If one of your layouts or
custom filters needs location information, you need to set "includeLocation=true" in the configuration
of all relevant loggers, including the root logger.
A configuration that does not require location might look like:







%d %p %c{1.} [%t] %m %ex%n










When AsyncLoggerContextSelector is used to make all loggers asynchronous, make sure to use
normal  and  elements in the configuration. The AsyncLoggerContextSelector will

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

227

ensure that all loggers are asynchronous, using a mechanism that is different from what happens when
you configure  or . The latter elements are intended for mixing async
with sync loggers. If you use both mechanisms together you will end up with two background threads,
where your application passes the log message to thread A, which passes the message to thread B,
which then finally logs the message to disk. This works, but there will be an unnecessary step in the
middle.
There are a few system properties you can use to control aspects of the asynchronous logging
subsystem. Some of these can be used to tune logging performance.
The below properties can also be specified by creating a file named
log4j2.component.properties and including this file in the classpath of the application.
Note that system properties were renamed into a more consistent style in Log4j 2.10.0. All old
property names are still supported which are documented here.

System Property

Default Value

log4j2.asyncLoggerExceptionHandler default handler

Description
Fully qualified name of a
class that implements the

com.lmax.disruptor.ExceptionHandler
interface. The class needs to have
a public zero-argument constructor.
If specified, this class will be
notified when an exception occurs
while logging the messages.

If not specified, the default
exception handler will print a
message and stack trace to the
standard error output stream.
log4j2.asyncLoggerRingBufferSize

256 * 1024

Size (number of slots) in
the RingBuffer used by the
asynchronous logging subsystem.
Make this value large enough
to deal with bursts of activity.
The minimum size is 128. The
RingBuffer will be pre-allocated
at first use and will never grow or
shrink during the life of the system.

When the application is
logging faster than the
underlying appender can keep
up with for a long enough
time to fill up the queue, the
behavious is determined by the
AsyncQueueFullPolicy.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

log4j2.asyncLoggerWaitStrategy

228

Timeout

log4j2.asyncLoggerThreadNameStrategy
CACHED

Valid values: Block, Timeout,
Sleep, Yield.
Block is a strategy that uses
a lock and condition variable
for the I/O thread waiting for
log events. Block can be used
when throughput and low-latency
are not as important as CPU
resource. Recommended for
resource constrained/virtualised
environments.
Timeout is a variation of
the Block strategy that will
periodically wake up from the lock
condition await() call. This ensures
that if a notification is missed
somehow the consumer thread is
not stuck but will recover with a
small latency delay (default 10ms).
Sleep is a strategy that initially
spins, then uses a Thread.yield(),
and eventually parks for the
minimum number of nanos the OS
and JVM will allow while the I/O
thread is waiting for log events.
Sleep is a good compromise
between performance and CPU
resource. This strategy has very
low impact on the application
thread, in exchange for some
additional latency for actually
getting the message logged.
Yield is a strategy that uses a
Thread.yield() for waiting for log
events after an initially spinning.
Yield is a good compromise
between performance and CPU
resource, but may use more CPU
than Sleep in order to get the
message logged to disk sooner.
Valid values: CACHED,
UNCACHED.
By default, AsyncLogger caches
the thread name in a ThreadLocal
variable to improve performance.
Specify the UNCACHED option
if your application modifies the
thread name at runtime (with

Thread.currentThread().setName())
and you want to see the new thread
name reflected in the log.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

log4j2.clock

229

SystemClock

Implementation of the

org.apache.logging.log4j.core.util.Cl

interface that is used for
timestamping the log
events when all loggers are
asynchronous.
By default,
System.currentTimeMillis

is called on every log event.
CachedClock is an

optimization intended for lowlatency applications where
time stamps are generated
from a clock that updates its
internal time in a background
thread once every millisecond,
or every 1024 log events,
whichever comes first. This
reduces logging latency a
little, at the cost of some
precision in the logged time
stamps. Unless you are logging
many events, you may see
"jumps" of 10-16 milliseconds
between log time stamps. WEB
APPLICATION WARNING:
The use of a background
thread may cause issues for
web applications and OSGi
applications so CachedClock is
not recommended for this kind
of applications.
You can also specify the fully
qualified class name of a
custom class that implements
the Clock interface.
System Properties to configure all asynchronous loggers
There are also a few system properties that can be used to maintain application throughput
even when the underlying appender cannot keep up with the logging rate and the queue is
filling up. See the details for system properties log4j2.asyncQueueFullPolicy and
log4j2.discardThreshold.

12.1.3 Mixing Synchronous and Asynchronous Loggers

Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath. Prior to
Log4j-2.9, disruptor-3.0.0.jar or higher was required. There is no need to set system property
"Log4jContextSelector" to any value.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

230

Synchronous and asynchronous loggers can be combined in configuration. This gives you more
flexibility at the cost of a slight loss in performance (compared to making all loggers asynchronous).
Use the  or  configuration elements to specify the loggers that
need to be asynchronous. A configuration can contain only one root logger (either a  or an
 element), but otherwise async and non-async loggers may be combined. For example,
a configuration file containing  elements can also contain  and 
elements for the synchronous loggers.
By default, location is not passed to the I/O thread by asynchronous loggers. If one of your layouts or
custom filters needs location information, you need to set "includeLocation=true" in the configuration
of all relevant loggers, including the root logger.
A configuration that mixes asynchronous loggers might look like:







%d %p %class{1.} [%t] %location %m %ex%n














There are a few system properties you can use to control aspects of the asynchronous logging
subsystem. Some of these can be used to tune logging performance.
The below properties can also be specified by creating a file named
log4j2.component.properties and including this file in the classpath of the application.
Note that system properties were renamed into a more consistent style in Log4j 2.10. All old property
names are still supported which are documented here.

System Property

Default Value

Description

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

log4j2.asyncLoggerConfigExceptionHandler
default handler

231

Fully qualified name of a
class that implements the

com.lmax.disruptor.ExceptionHandler
interface. The class needs to have
a public zero-argument constructor.
If specified, this class will be
notified when an exception occurs
while logging the messages.

If not specified, the default
exception handler will print a
message and stack trace to the
standard error output stream.
log4j2.asyncLoggerConfigRingBufferSize
256 * 1024

Size (number of slots) in
the RingBuffer used by the
asynchronous logging subsystem.
Make this value large enough
to deal with bursts of activity.
The minimum size is 128. The
RingBuffer will be pre-allocated
at first use and will never grow or
shrink during the life of the system.

When the application is
logging faster than the
underlying appender can keep
up with for a long enough
time to fill up the queue, the
behavious is determined by the
AsyncQueueFullPolicy.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

log4j2.asyncLoggerConfigWaitStrategy
Timeout

232

Valid values: Block, Timeout,
Sleep, Yield.
Block is a strategy that uses
a lock and condition variable
for the I/O thread waiting for
log events. Block can be used
when throughput and low-latency
are not as important as CPU
resource. Recommended for
resource constrained/virtualised
environments.
Timeout is a variation of
the Block strategy that will
periodically wake up from the lock
condition await() call. This ensures
that if a notification is missed
somehow the consumer thread is
not stuck but will recover with a
small latency delay (default 10ms).
Sleep is a strategy that initially
spins, then uses a Thread.yield(),
and eventually parks for the
minimum number of nanos the OS
and JVM will allow while the I/O
thread is waiting for log events.
Sleep is a good compromise
between performance and CPU
resource. This strategy has very
low impact on the application
thread, in exchange for some
additional latency for actually
getting the message logged.
Yield is a strategy that uses a
Thread.yield() for waiting for log
events after an initially spinning.
Yield is a good compromise
between performance and CPU
resource, but may use more CPU
than Sleep in order to get the
message logged to disk sooner.

System Properties to configure mixed asynchronous and normal loggers
There are also a few system properties that can be used to maintain application throughput
even when the underlying appender cannot keep up with the logging rate and the queue is
filling up. See the details for system properties log4j2.asyncQueueFullPolicy and
log4j2.discardThreshold.

12.1.4 Location, location, location...

If one of the layouts is configured with a location-related attribute like HTML locationInfo, or one of
the patterns %C or $class, %F or %file, %l or %location, %L or %line, %M or %method, Log4j
will take a snapshot of the stack, and walk the stack trace to find the location information.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

233

This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. Synchronous loggers
wait as long as possible before they take this stack snapshot. If no location is required, the snapshot
will never be taken.
However, asynchronous loggers need to make this decision before passing the log message to another
thread; the location information will be lost after that point. The performance impact of taking a stack
trace snapshot is even higher for asynchronous loggers: logging with location is 30-100 times slower
than without location. For this reason, asynchronous loggers and asynchronous appenders do not
include location information by default.
You can override the default behaviour in your logger or asynchronous appender configuration by
specifying includeLocation="true".

12.1.5 Asynchronous Logging Performance

The throughput performance results below were derived from running the PerfTest, MTPerfTest and
PerfTestDriver classes which can be found in the Log4j 2 unit test source directory. For throughput
tests, the methodology used was:
• First, warm up the JVM by logging 200,000 log messages of 500 characters.
• Repeat the warm-up 10 times, then wait 10 seconds for the I/O thread to catch up and buffers to
drain.
• Measure how long it takes to execute 256 * 1024 / threadCount calls to Logger.log and express
the result in messages per second.
• Repeat the test 5 times and average the results.
The results below were obtained with log4j-2.0-beta5, disruptor-3.0.0.beta3, log4j-1.2.17 and
logback-1.0.10.
12.1.5.1 Logging Peak Throughput

The graph below compares the throughput of synchronous loggers, asynchronous appenders and
asynchronous loggers. This is the total throughput of all threads together. In the test with 64 threads,
asynchronous loggers are 12 times faster than asynchronous appenders, and 68 times faster than
synchronous loggers.
Asynchronous loggers' throughput increases with the number of threads, whereas both synchronous
loggers and asynchronous appenders have more or less constant throughput regardless of the number
of threads that are doing the logging.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

234

12.1.5.2 Asynchronous Throughput Comparison with Other Logging Packages

We also compared peak throughput of asynchronous loggers to the synchronous loggers and
asynchronous appenders available in other logging packages, specifically log4j-1.2.17 and
logback-1.0.10, with similar results. For asynchronous appenders, total logging throughput of all
threads together remains roughly constant when adding more threads. Asynchronous loggers make
more effective use of the multiple cores available on the machine in multi-threaded scenarios.

On Solaris 10 (64bit) with JDK1.7.0_06, 4-core Xeon X5570 dual CPU @2.93Ghz with
hyperthreading switched on (16 virtual cores):

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

Logger

235

1 thread

2 threads

4 threads

8 threads

16
threads

32
threads

64
threads

Log4j 2:
Loggers all
asynchronous

2,652,412

909,119

776,993

516,365

239,246

253,791

288,997

Log4j 2:
Loggers
mixed sync/
async

2,454,358

839,394

854,578

597,913

261,003

216,863

218,937

Log4j 2:
Async
Appender

1,713,429

603,019

331,506

149,408

86,107

45,529

23,980

Log4j1:
Async
Appender

2,239,664

494,470

221,402

109,314

60,580

31,706

14,072

Logback:
Async
Appender

2,206,907

624,082

307,500

160,096

85,701

43,422

21,303

Log4j 2:
Synchronous

273,536

136,523

67,609

34,404

15,373

7,903

4,253

Log4j1:
Synchronous

326,894

105,591

57,036

30,511

13,900

7,094

3,509

Logback:
Synchronous

178,063

65,000

34,372

16,903

8,334

3,985

1,967

Throughput per thread in messages/second
On Windows 7 (64bit) with JDK1.7.0_11, 2-core Intel i5-3317u CPU @1.70Ghz with hyperthreading
switched on (4 virtual cores):
Logger
Log4j 2:
Loggers all
asynchronous

1 thread

2 threads

4 threads

8 threads

16 threads

32 threads

1,715,344

928,951

1,045,265

1,509,109

1,708,989

773,565

571,099

1,204,774

1,632,204

1,368,041

462,093

908,529

Log4j 2:
Async
Appender

1,236,548

1,006,287

511,571

302,230

160,094

60,152

Log4j1: Async
Appender

1,373,195

911,657

636,899

406,405

202,777

162,964

Logback:
Async
Appender

1,979,515

783,722

582,935

289,905

172,463

133,435

281,250

225,731

129,015

66,590

34,401

17,347

Log4j 2:
Loggers
mixed sync/
async

Log4j 2:
Synchronous

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

236

Log4j1:
Synchronous

147,824

72,383

32,865

18,025

8,937

4,440

Logback:
Synchronous

149,811

66,301

32,341

16,962

8,431

3,610

Throughput per thread in messages/second

12.1.5.3 Response Time Latency
This section has been rewritten with the Log4j 2.6 release. The previous version only reported service time
instead of response time. See the response time side bar on the performance page on why this is too
optimistic. Furthermore the previous version reported average latency, which does not make sense since
latency is not a normal distribution. Finally, the previous version of this section only reported the maximum
latency of up to 99.99% of the measurements, which does not tell you how bad the worst 0.01% were. This is
unfortunate because often the "outliers" are all that matter when it comes to response time. From this release
we will try to do better and report response time latency across the full range of percentages, including all the
outliers. Our thanks to Gil Tene for his How NOT to measure latency presentation. (Now we know why this is
also known as the "Oh s#@t!" presentation.)

Response time is how long it takes to log a message under a certain load. What is often reported as
latency is actually service time: how long it took to perform the operation. This hides the fact that a
single spike in service time adds queueing delay for many of the subsequent operations. Service time
is easy to measure (and often looks good on paper) but is irrelevant for users since it omits the time
spent waiting for service. For this reason we report response time: service time plus wait time.
The response time test results below were all derived from running the ResponseTimeTest class
which can be found in the Log4j 2 unit test source directory. If you want to run these tests yourself,
here are the command line options we used:
• -Xms1G -Xmx1G (prevent heap resizing during the test)
• -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin wait strategy
reduces some jitter.)
• classic mode: -Dlog4j2.enable.threadlocals=false -Dlog4j2.enable.direct.encoders=false
garbage-free mode: -Dlog4j2.enable.threadlocals=true -Dlog4j2.enable.direct.encoders=true
• XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
• -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime (to eyeball
GC and safepoint pauses)
The graph below compares response time latency of the ArrayBlockingQueue-based asynchronous
appenders in Logback 1.1.7, Log4j 1.2.17 to the various options for asynchronous logging that Log4j
2.6 offers. Under a workload of 128,000 messages per second, using 16 threads (each logging at a rate
of 8,000 messages per second), we see that Logback 1.1.7, Log4j 1.2.17 experience latency spikes
that are orders of magnitude larger than Log4j 2.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

237

The graph below zooms in on the Log4j 2 results for the same test. We see that the worst-case
response time is highest for the ArrayBlockingQueue-based Async Appender. Garbage-free async
loggers have the best response time behaviour.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

12 Async Loggers

238

12.1.6 Under The Hood

Asynchronous Loggers are implemented using the LMAX Disruptor inter-thread messaging library.
From the LMAX web site:
... using queues to pass data between stages of the system was introducing latency, so we focused
on optimising this area. The Disruptor is the result of our research and testing. We found that cache
misses at the CPU-level, and locks requiring kernel arbitration are both extremely costly, so we
created a framework which has "mechanical sympathy" for the hardware it's running on, and that's
lock-free.
LMAX Disruptor internal performance comparisons with
java.util.concurrent.ArrayBlockingQueue can be found here.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

239

13 Garbage-free Logging

.......................................................................................................................................
13.1 Garbage-free Steady State Logging
Garbage collection pauses are a common cause of latency spikes and for many systems significant
effort is spent on controlling these pauses.
Many logging libraries, including previous versions of Log4j, allocate temporary objects like log
event objects, Strings, char arrays, byte arrays and more during steady state logging. This contributes
to pressure on the garbage collector and increases the frequency with which GC pauses occur.
From version 2.6, Log4j runs in "garbage free" mode by default where objects and buffers are reused
and no temporary objects are allocated as much as possible. There is also a "low garbage" mode
which is not completely garbage free but does not use ThreadLocal fields. This is the default mode
when Log4j detects it is running in a web application. Finally, it is possible to switch off all garbagefree logic and run in "classic mode" instead. For details, see the Configuration section below.

13.1.1 A Contrived Example

To highlight the difference that garbage-free logging can make, we used Java Flight Recorder to
measure a simple application that does nothing but log a simple string as often as possible for about
12 seconds.
The application was configured to use Async Loggers, a RandomAccessFile appender and a "%d %p
%c{1.} [%t] %m %ex%n" pattern layout. (Async Loggers used the Yield WaitStrategy.)
Mission Control shows that with Log4j 2.5 this application allocates memory at a rate of about 809
MB/sec, resulting in 141 minor collections. Log4j 2.6 does not allocate temporary objects in this
configuration, and as a result the same application with Log4j 2.6 has a memory allocation rate of 1.6
MB/sec and was GC-free with 0 (zero) garbage collections.

With Log4j 2.5: memory allocation rate 809 MB/sec,
141 minor collections.

Log4j 2.6 did not allocate temporary objects: 0 (zero)
garbage collections.

13.1.2 Configuration

Garbage-free logging in Log4j 2.6 is partially implemented by reusing objects in ThreadLocal fields,
and partially by reusing buffers when converting text to bytes.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

240

ThreadLocal fields holding non-JDK classes can cause memory leaks in web applications when
the application server's thread pool continues to reference these fields after the web application is
undeployed. To avoid causing memory leaks, Log4j will not use these ThreadLocals when it detects
that it is used in a web application (when the javax.servlet.Servlet class is in the classpath, or
when system property log4j2.isWebapp is set to "true").
Some garbage-reducing functionality does not rely on ThreadLocals and is enabled by default for
all applications: in Log4j 2.6, converting log events to text and text to bytes can be done by directly
encoding text into a reused ByteBuffer without creating intermediary Strings, char arrays and byte
arrays. So while logging is not completely garbage-free for web applications yet, the pressure on the
garbage collector can still be significantly reduced.
Note 1: as of version 2.6, a Log4j configuration containing a  section will result in
temporary objects being created during steady-state logging.
Note 2: the Async Logger Timeout wait strategy (the default) and the Block wait strategy cause
java.util.concurrent.locks.AbstractQueuedSynchronizer$Node objects to be created.
The Yield and Sleep wait strategies are garbage-free. (See here and here.)

13.1.2.1 Disabling Garbage-free Logging

There are two separate system properties for manually controlling the mechanisms Log4j uses to
avoid creating temporary objects:
• log4j2.enableThreadlocals - if "true" (the default for non-web applications) objects are
stored in ThreadLocal fields and reused, otherwise new objects are created for each log event.
• log4j2.enableDirectEncoders - if "true" (the default) log events are converted to text and
this text is converted to bytes without creating temporary objects. Note: synchronous logging
performance may be worse for multi-threaded applications in this mode due to synchronization
on the shared buffer. If your application is multi-threaded and logging performance is important,
consider using Async Loggers.
• The ThreadContext map is not garbage-free by default, but from Log4j 2.7 it can be configured
to be garbage-free by setting system property log4j2.garbagefreeThreadContextMap to
"true".
Instead of system properties, the above properties can also be specified in a file named
log4j2.component.properties by including this file in the classpath of the application. See the
manual regarding system properties for more info.

13.1.2.2 Supported Appenders

The following appenders are garbage-free during steady-state logging:
• Console
• File
• RollingFile (some temporary objects are created during file rollover)
• RandomAccessFile
• RollingRandomAccessFile (some temporary objects are created during file rollover)
• MemoryMappedFile
Any other appenders not in the above list (including AsyncAppender) create temporary objects during
steady-state logging. Instead of AsyncAppender, use Async Loggers to log asynchronously in a
garbage-free manner.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

241

13.1.2.3 Supported Filters

The following filters are garbage-free during steady-state logging:
• CompositeFilter (adding and removing element filters creates temporary objects for thread
safety)
• DynamicThresholdFilter
• LevelRangeFilter (garbage free since 2.8)
• MapFilter (garbage free since 2.8)
• MarkerFilter (garbage free since 2.8)
• StructuredDataFilter (garbage free since 2.8)
• ThreadContextMapFilter (garbage free since 2.8)
• ThresholdFilter (garbage free since 2.8)
• TimeFilter (garbage free since 2.8)
Other filters like BurstFilter, RegexFilter and ScriptFilter are not trivial to make garbage free, and
there is currently no plan to change them.

13.1.2.4 Supported Layouts
13.GelfLayout

GelfLayout is garbage-free when used with compressionType="OFF", as long as no additional field
contains '${' (variable substitution).
13.PatternLayout

PatternLayout with the following limited set of conversion patterns is garbage-free. Format modifiers
to control such things as field width, padding, left and right justification will not generate garbage.
Conversion Pattern

Description

%c{precision}, %logger{precision}

Logger name

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

%d, %date

242

Note: Only the predefined date formats are garbagefree: (millisecond separator may be either a comma ','
or a period '.')

Pattern

Example

%d{DEFAULT}

2012-11-02 14:34:02,781

%d{ISO8601}

2012-11-02T14:34:02,781

%d{ISO8601_BASIC}

20121102T143402,781

%d{ABSOLUTE}

14:34:02,781

%d{DATE}

02 Nov 2012
14:34:02,781

%d{COMPACT}

20121102143402781

%d{HH:mm:ss,SSS}

14:34:02,781

%d{dd MMM yyyy
HH:mm:ss,SSS}

02 Nov 2012
14:34:02,781

%d{HH:mm:ss}{GMT+0}

18:34:02

%d{UNIX}

1351866842

%d{UNIX_MILLIS}

1351866842781

%enc{pattern}, %encode{pattern}

Encodes special characters such as '\n' and HTML
characters to help prevent log forging and some XSS
attacks that could occur when displaying logs in a web
browser - garbage-free since 2.8

%equals{pattern}{test}{substitution},
%equalsIgnoreCase{pattern}{test}{substitution}

Replaces occurrences of 'test', a string, with its
replacement 'substitution' in the string resulting from
evaluation of the pattern - garbage-free since 2.8

%highlight{pattern}{style}

Adds ANSI colors - garbage-free since 2.7 (unless
nested pattern is not garbage free)

K{key}, map{key}, MAP{key}

Outputs the entries in a MapMessage, if one is
present in the event - garbage-free since 2.8.

%m, %msg, %message

Log message (garbage-free unless message text
contains '${')

%marker

The full name of the marker (including parents) garbage-free since 2.8

%markerSimpleName

The simple name of the marker (not including parents)

%maxLen, %maxLength

Truncates another pattern to some max number of
characters - garbage-free since 2.8

%n

The platform dependent line separator

%N, %nano

System.nanoTime() when the event was logged

%notEmpty{pattern}, %varsNotEmpty{pattern},
%variablesNotEmpty{pattern}

Outputs the result of evaluating the pattern if and only
if all variables in the pattern are not empty - garbagefree since 2.8

%p, %level

The level of the logging event

%r, %relative

The number of milliseconds elapsed since the JVM
was started until the creation of the logging event garbage-free since 2.8

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

243

%sn, %sequenceNumber

A sequence number that will be incremented in every
event - garbage-free since 2.8

%style{pattern}{ANSI style}

Style the message - garbage-free since 2.7 (unless
nested pattern is not garbage free)

%T, %tid, %threadId

The ID of the thread that generated the logging event

%t, %tn, %thread, %threadName

The name of the thread that generated the logging
event

%tp

The priority of the thread that generated the logging
event

%X{key[,key2...]}, %mdc{key[,key2...]},
%MDC{key[,key2...]}

Outputs the Thread Context Map (also known as the
Mapped Diagnostic Context or MDC) associated with
the thread that generated the logging event - garbagefree since 2.8

literal text

Garbage-free unless literal contains '${' (variable
substitution)

Other PatternLayout conversion patterns, and other Layouts may be updated to avoid creating
temporary objects in future releases. (Patches welcome!)
Note: Logging exceptions and stack traces will create temporary objects with any layout. (However,
Layouts will only create these temporary objects when an exception actually occurs.) We haven't
figured out a way to log exceptions and stack traces without creating temporary objects. That is
unfortunate, but you probably still want to log them when they happen.
Note: patterns containing regular expressions and lookups for property substitution will result in temporary
objects being created during steady-state logging.

Including location information is done by walking the stacktrace of an exception, which creates
temporary objects, so the following patterns are not garbage-free:
• %C, %class - Class Name
• %F, %file - File Location
• %l, %location - Location
• %L, %line - Line Location
• %M, %method - Method Location
Also, the pattern converters for formatting Throwables are not garbage-free:
•
•
•
•

%ex, %exception, %throwable - The Throwable trace bound to the LoggingEvent
%rEx, %rException %rThrowable - Same as %ex but with wrapping exceptions
%xEx, %xException, %xThrowable - Same as %ex but with class packaging information
%u, %uuid - Creates a new random or time-based UUID while formatting

13.1.2.5 API Changes

Methods have been added to the Logger interface so that no vararg array objects are created when
logging messages with up to ten parameters.
Also, methods have been added to the Logger interface to log java.lang.CharSequence
messages. User-defined objects that implement the CharSequence interface can be logged without
creating temporary objects: Log4j will try to turn CharSequence messages, Object messages and

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

244

message parameters into text by appending them to a StringBuilder as a CharSequence. This avoids
calling toString() on these objects.
An alternative is to implement the
org.apache.logging.log4j.util.StringBuilderFormattable interface. If an object is
logged that implements this interface, its formatTo method is called instead of toString().

Log4j may call toString() on message and parameter objects when garbage-free logging is
disabled (when system property log4j2.enableThreadlocals is set to "false".)

13.1.2.6 Impact on Application Code: Autoboxing

We made an effort to make logging garbage-free without requiring code changes in existing
applications, but there is one area where this was not possible. When logging primitive values (i.e. int,
double, boolean, etc.) the JVM autoboxes these primitive values to their Object wrapper equivalents,
creating garbage.
Log4j provides an Unbox utility to prevent autoboxing of primitive parameters. This utility contains a
thread-local pool of reused StringBuilders. The Unbox.box(primitive) methods write directly
into a StringBuilder, and the resulting text will be copied into the final log message text without
creating temporary objects.
import static org.apache.logging.log4j.util.Unbox.box;
...
public void garbageFree() {
logger.debug("Prevent primitive autoboxing {} {}", box(10L), box(2.6d));
}

Note: not all logging is garbage free. Specifically:
• The ThreadContext map is not garbage-free by default, but can be configured to be garbage-free by
setting system property log4j2.garbagefreeThreadContextMap to "true".
• The ThreadContext stack is not garbage-free.
• Logging more than 10 parameters creates vararg arrays.
• Logging very large messages (more than 518 characters) when all loggers are Async Loggers will cause
the internal StringBuilder in the RingBuffer to be trimmed back to their max size.
• Logging messages containing '${': substituting a ${variable} creates temporary objects.
• Logging a lambda as a parameter ( logger.info("lambda value is {}", () ->
callExpensiveMethod())) creates a vararg array. Logging a lambda expression by itself is
garbage-free: logger.debug(() -> callExpensiveMethod()).
• The Logger.traceEntry and Logger.traceExit methods create temporary objects.

13.1.3 Performance

13.1.3.1 Response Time Latency

Response time is how long it takes to log a message under a certain load. What is often reported as
latency is actually service time: how long it took to perform the operation. This hides the fact that a

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

245

single spike in service time adds queueing delay for many of the subsequent operations. Service time
is easy to measure (and often looks good on paper) but is irrelevant for users since it omits the time
spent waiting for service. For this reason we report response time: service time plus wait time. See the
response time section of the performance page for more detail.
The response time test results below were all derived from running the ResponseTimeTest class
which can be found in the Log4j 2 unit test source directory. If you want to run these tests yourself,
here are the command line options we used:
• -Xms1G -Xmx1G (prevent heap resizing during the test)
• -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin wait strategy
reduces some jitter.)
• classic mode: -Dlog4j2.enable.threadlocals=false -Dlog4j2.enable.direct.encoders=false
garbage-free mode: -Dlog4j2.enable.threadlocals=true -Dlog4j2.enable.direct.encoders=true
• XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
• -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution
-XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime (to eyeball
GC and safepoint pauses)
13.1.3.2 Async Loggers

The graph below compares "classic" logging to garbage-free logging response time behaviour for
Log4j's Async Loggers. In the graph, "100k" means logging at a sustained load of 100,000 messages/
second, "800k" is a sustained load of 800,000 messages/second.

In classic mode we see numerous minor garbage collections which pause the application threads for
3 milliseconds or more. This quickly adds up to response time delays of almost 10 milliseconds. As
you can see in the graph, increasing the load shifts the curve to the left (there are more spikes). This
makes sense: logging more means more pressure on the garbage collector resulting in more minor GC

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

246

pauses. We experimented a little with reducing the load to 50,000 or even 5000 messages/second, but
this did not eliminate the 3 millisecond pauses, it just made them occur less frequently. Note that all
GC pauses in this test are minor GC pauses. We did not see any full garbage collections.
In garbage-free mode, maximum response time remains well below 1 millisecond under a wide range
of loads. (Max 780 us at 800,000 messages/sec, max 407 us at 600,000 messages/sec, with the 99%
around 5 us for all loads up to 800,000 messages/sec.) Increasing or decreasing the load does not
change the response time behaviour. We did not investigate the cause of the 200-300 microsecond
pauses we saw in these tests.
When we increased the load further we begin to see larger response time pauses for both classic and
garbage-free logging. At sustained loads of 1 million messages/second or more we start to approach
the maximum throughput of the underlying RandomAccessFile Appender (see the synchronous
logging throughput chart below). At these loads the ringbuffer starts to fill up and backpressure kicks
in: attempting to add another message when the ringbuffer is full will block until a free slot becomes
available. We start to see response times of tens of milliseconds or more; and attempting to increase
the load even more results in larger and larger response time spikes.
13.1.3.3 Synchronous File Logging

With synchronous file logging, garbage-free logging still performs better than classic logging, but the
difference is less pronounced.
At a workload of 100,000 messages/second, classic logging max response time was a little over
2 milliseconds where garbage-free logging was a little over 1 millisecond. When the workload is
increased to 300,000 messages/second, classic logging shows response time pauses of 6 milliseconds
where the garbage-free response times were less than 3 milliseconds. It may be possible to improve on
this, we did not investigate further yet.

The above results are obtained with the ResponseTimeTest class which can be found in the Log4j 2
unit test source directory, running on JDK 1.8.0_45 on RHEL 6.5 (Linux 2.6.32-573.1.1.el6.x86_64)
with 10-core Xeon CPU E5-2660 v3 @2.60GHz with hyperthreading switched on (20 virtual cores).

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

13 Garbage-free Logging

247

13.1.3.4 Classic Logging has Slightly Higher Throughput

Throughput is slightly worse for garbage-free logging, compared to classic logging. This is true for
both synchronous and asynchronous logging. The graph below compares the sustained throughput of
synchronous logging to a file with Log4j 2.6 in garbage-free mode, classic mode and Log4j 2.5.

The results above are obtained with the JMH Java benchmark harness. See the
FileAppenderBenchmark source code in the log4j-perf module.

13.1.4 Under the Hood

Custom Message implementations that implement
org.apache.logging.log4j.util.StringBuilderFormattable can be converted to text

by garbage-free Layouts without creating temporary objects. PatternLayout uses this mechanism and
other layouts that convert LogEvents to text will likely also look for this interface.
Custom Layouts that want to be garbage-free should implement the Encoder
interface. For custom Layouts that convert a LogEvent to a text representation, the
org.apache.logging.log4j.core.layout.StringBuilderEncoder class may be useful to
convert this text to bytes in a garbage-free manner.
Custom Appenders that want to be garbage-free should provide their Layout with a
ByteBufferDestination implementation that the Layout can directly write into.
AbstractOutputStreamAppender has been modified to make the ConsoleAppender,

(Rolling)FileAppender, (Rolling)RandomAccessFileAppender and MemoryMappedFileAppender
garbage-free. An effort has been made to minimize impact on custom Appenders that extend
AbstractOutputStreamAppender, but it is impossible to guarantee that changing
the superclass will not impact any and all subclasses. Custom Appenders that extend
AbstractOutputStreamAppender should verify that they still function correctly. In case there is a
problem, system property log4j2.enable.direct.encoders can be set to "false" to revert to the
pre-Log4j 2.6 behaviour.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

248

14 JMX

.......................................................................................................................................
14.1 JMX
Log4j 2 has built-in support for JMX. The StatusLogger, ContextSelector, and all LoggerContexts,
LoggerConfigs and Appenders are instrumented with MBeans and can be remotely monitored and
controlled.
Also included is a simple client GUI that can be used to monitor the StatusLogger output, as well as
to remotely reconfigure Log4j with a different configuration file, or to edit the current configuration
directly.

14.2 Enabling JMX
JMX support is enabled by default. When Log4j initializes, the StatusLogger, ContextSelector,
and all LoggerContexts, LoggerConfigs and Appenders are instrumented with MBeans. To
disable JMX completely, and prevent these MBeans from being created, specify system property
log4j2.disableJmx to true when you start the Java VM.
14.2.1 Local Monitoring and Management

To perform local monitoring you don't need to specify any system properties. The JConsole tool
that is included in the Java JDK can be used to monitor your application. Start JConsole by typing
$JAVA_HOME/bin/jconsole in a command shell. For more details, see Oracle's documentation on
how to use JConsole.
14.2.2 Remote Monitoring and Management

To enable monitoring and management from remote systems, set the following system property when
starting the Java VM.
com.sun.management.jmxremote.port=portNum

In the property above, portNum is the port number through which you want to enable JMX RMI
connections.
For more details, see Oracle's documentation on Remote Monitoring and Management.
14.2.3 RMI impact on Garbage Collection

Be aware that RMI by default triggers a full GC every hour. See the Oracle documentation for the
sun.rmi.dgc.server.gcInterval and sun.rmi.dgc.client.gcInterval properties. The
default value of both properties is 3600000 milliseconds (one hour). Before Java 6, it was one minute.
The two sun.rmi arguments reflect whether your JVM is running in server or client mode. If you want
to modify the GC interval time it may be best to specify both properties to ensure the argument is
picked up by the JVM.
An alternative may be to disable explicit calls to System.gc() altogether with XX:+DisableExplicitGC, or (if you are using the CMS or G1 collector) add -XX:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

249

+ExplicitGCInvokesConcurrent to ensure the full GCs are done concurrently in parallel with

your application instead of forcing a stop-the-world collection.

14.3 Log4j Instrumented Components
The best way to find out which methods and attributes of the various Log4j components are accessible
via JMX is to look at the Javadoc or by exploring directly in JConsole.
The screenshot below shows the Log4j MBeans in JConsole.

14.4 Client GUI
Log4j includes a basic client GUI that can be used to monitor the StatusLogger output and to remotely
modify the Log4j configuration. The client GUI can be run as a stand-alone application or as a
JConsole plug-in.
14.4.1 Running the Client GUI as a JConsole Plug-in

To run the Log4j JMX Client GUI as a JConsole Plug-in, start JConsole with the following command:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

250

$JAVA_HOME/bin/jconsole -pluginpath /path/to/log4j-api${Log4jReleaseVersion}.jar:/path/to/log4j-core-${Log4jReleaseVersion}.jar:/
path/to/log4j-jmx-gui-${Log4jReleaseVersion}.jar

or on Windows:
%JAVA_HOME%\bin\jconsole -pluginpath \path\to\log4j-api${Log4jReleaseVersion}.jar;\path\to\log4j-core-${Log4jReleaseVersion}.jar;
\path\to\log4j-jmx-gui-${Log4jReleaseVersion}.jar

If you execute the above command and connect to your application, you will see an extra "Log4j 2"
tab in the JConsole window. This tab contains the client GUI, with the StatusLogger selected. The
screenshot below shows the StatusLogger panel in JConsole.

14.4.2 Remotely Editing the Log4j Configuration

The client GUI also contains a simple editor that can be used to remotely change the Log4j
configuration.
The screenshot below shows the configuration edit panel in JConsole.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

251

The configuration edit panel provides two ways to modify the Log4j configuration: specifying a
different configuration location URI, or modifying the configuration XML directly in the editor panel.
If you specify a different configuration location URI and click the "Reconfigure from Location"
button, the specified file or resource must exist and be readable by the application, or an error will
occur and the configuration will not change. If an error occurred while processing the contents of
the specified resource, Log4j will keep its original configuration, but the editor panel will show the
contents of the file you specified.
The text area showing the contents of the configuration file is editable, and you can directly modify
the configuration in this editor panel. Clicking the "Reconfigure with XML below" button will send
the configuration text to the remote application where it will be used to reconfigure Log4j on the fly.
This will not overwrite any configuration file. Reconfiguring with text from the editor happens in
memory only and the text is not permanently stored anywhere.
14.4.3 Running the Client GUI as a Stand-alone Application

To run the Log4j JMX Client GUI as a stand-alone application, run the following command:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

252

$JAVA_HOME/bin/java -cp /path/to/log4j-api-${Log4jReleaseVersion}.jar:/
path/to/log4j-core-${Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui


or on Windows:
%JAVA_HOME%\bin\java -cp \path\to\log4j-api-${Log4jReleaseVersion}.jar;
\path\to\log4j-core-${Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui


Where options are one of the following:
• :
• service:jmx:rmi:///jndi/rmi://:/jmxrmi
• service:jmx:rmi://:/jndi/rmi://:/jmxrmi
The port number must be the same as the portNum specified when you started the application you
want to monitor.
For example, if you started your application with these options:
com.sun.management.jmxremote.port=33445
com.sun.management.jmxremote.authenticate=false
com.sun.management.jmxremote.ssl=false

(Note that this disables all security so this is not recommended for production environments.
Oracle's documentation on Remote Monitoring and Management provides details on how to
configure JMX more securely with password authentication and SSL.)
Then you can run the client with this command:
$JAVA_HOME/bin/java -cp /path/to/log4j-api-${Log4jReleaseVersion}.jar:/
path/to/log4j-core-${Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui
localhost:33445

or on Windows:
%JAVA_HOME%\bin\java -cp \path\to\log4j-api-${Log4jReleaseVersion}.jar;
\path\to\log4j-core-${Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui
localhost:33445

The screenshot below shows the StatusLogger panel of the client GUI when running as a stand-alone
application.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

253

The screenshot below shows the configuration editor panel of the client GUI when running as a standalone application.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

14 JMX

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

254

15 Logging Separation

255

15 Logging Separation

.......................................................................................................................................
15.1 Logging Separation
There are many well known use cases where applications may share an environment with other
applications and each has a need to have its own, separate logging environment. This purpose of this
section is to discuss some of these cases and ways to accomplish this.
15.1.1 Use Cases

This section describes some of the use cases where Log4j could be used and what its desired behavior
might be.
15.1.1.1 Standalone Application

Standalone applications are usually relatively simple. They typically have one bundled executable that
requires only a single logging configuration.
15.1.1.2 Web Applications

A typical web application will be packaged as a WAR file and will include all of its dependencies in
WEB-INF/lib and will have its configuration file located in the class path or in a location configured
in the web.xml. Be sure to follow the instructions to initialize Log4j 2 in a web application.
15.1.1.3 Java EE Applications

A Java EE application will consist of one or more WAR files and possible some EJBs, typically all
packaged in an EAR file. Usually, it is desirable to have a single configuration that applies to all the
components in the EAR. The logging classes will generally be placed in a location shared across all
the components and the configuration needs to also be shareable. Be sure to follow the instructions to
initialize Log4j 2 in a web application.
15.1.1.4 "Shared" Web Applications and REST Service Containers

In this scenario there are multiple WAR files deployed into a single container. Each of the
applications should use the same logging configuration and share the same logging implementation
across each of the web applications. When writing to files and streams each of the applications should
share them to avoid the issues that can occur when multiple components try to write to the same
file(s) through different File objects, channels, etc.
15.1.1.5 OSGi Applications

An OSGi container physically separates each JAR into its own ClassLoader, thus enforcing
modularity of JARs as well as providing standardized ways for JARs to share code based on version
numbers. Suffice to say, the OSGi framework is beyond the scope of this manual. There are some
differences when using Log4j in an OSGi container. By default, each JAR bundle is scanned for its
own Log4j configuration file. Similar to the web application paradigm, every bundle has its own
LoggerContext. As this may be undesirable when a global Log4j configuration is wanted, then the
ContextSelector should be overridden with BasicContextSelector or JndiContextSelector.
15.1.2 Approaches

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

15 Logging Separation

256

15.1.2.1 The Simple Approach

The simplest approach for separating logging within applications is to package each application
with its own copy of Log4j and to use the BasicContextSelector. While this works for standalone
applications and may work for web applications and possibly Java EE applications, it does not work
at all in the last case. However, when this approach does work it should be used as it is ultimately the
simplest and most straightforward way of implementing logging.
15.1.2.2 Using Context Selectors

There are a few patterns for achieving the desired state of logging separation using ContextSelectors:
1. Place the logging jars in the container's classpath and
set the system property log4j2.contextSelector to
org.apache.logging.log4j.core.selector.BasicContextSelector. This will create

a single LoggerContext using a single configuration that will be shared across all applications.
2. Place the logging jars in the container's classpath and use the default
ClassLoaderContextSelector. Follow the instructions to initialize Log4j 2 in a web application.
Each application can be configured to share the same configuration used at the container or can
be individually configured. If status logging is set to debug in the configuration there will be
output from when logging is initialized in the container and then again in each web application.
3. Follow the instructions to initialize Log4j 2 in a web application and set the
system property or servlet context parameter log4j2.contextSelector to
org.apache.logging.log4j.core.selector.JndiContextSelector. This will cause the
container to use JNDI to locate each web application's LoggerContext. Be sure to
set the isLog4jContextSelectorNamed context parameter to true and also set the
log4jContextName and log4jConfiguration context parameters.
The exact method for setting system properties depends on the container. For Tomcat, edit
$CATALINA_HOME/conf/catalina.properties. Consult the documentation for other web
containers.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

257

16 Extending Log4j

.......................................................................................................................................
16.1 Extending Log4j
Log4j 2 provides numerous ways that it can be manipulated and extended. This section includes an
overview of the various ways that are directly supported by the Log4j 2 implementation.
16.1.1 LoggerContextFactory

The LoggerContextFactory binds the Log4j API to its implementation. The Log4j LogManager
locates a LoggerContextFactory by using java.util.ServiceLoader to locate all instances of
org.apache.logging.log4j.spi.Provider. Each implementation must provide a class that
extends org.apache.logging.log4j.spi.Provider and should have a no-arg constructor
that delegates to Provider's constructor passing the Priority, the API versions it is compatible with,
and the class that implements org.apache.logging.log4j.spi.LoggerContextFactory.
Log4j will compare the current API version and if it is compatible the implementation will be
added to the list of providers. The API version in org.apache.logging.log4j.LogManager
is only changed when a feature is added to the API that implementations need to be aware
of. If more than one valid implementation is located the value for the Priority will be
used to identify the factory with the highest priority. Finally, the class that implements
org.apache.logging.log4j.spi.LoggerContextFactory will be instantiated and bound to
the LogManager. In Log4j 2 this is provided by Log4jContextFactory.
Applications may change the LoggerContextFactory that will be used by
1. Create a binding to the logging implementation.
a. Implement a new LoggerContextFactory.
b. Implement a class that extends org.apache.logging.spi.Provider. with a noarg constructor that calls super-class's constructor with the Priority, the API version(s),
LoggerContextFactory class, and optionally, a ThreadContextMap implementation
class.
c. Create a META-INF/services/org.apache.logging.spi.Provider file that
contains the name of the class that implements org.apache.logging.spi.Provider.
2. Setting the system property log4j2.loggerContextFactory to the name of the
LoggerContextFactory class to use.
3. Setting the property "log4j2.loggerContextFactory" in a properties file named
"log4j2.LogManager.properties" to the name of the LoggerContextFactory class to use. The
properties file must be on the classpath.
16.1.2 ContextSelector

ContextSelectors are called by the Log4j LoggerContext factory. They perform the actual
work of locating or creating a LoggerContext, which is the anchor for Loggers and their
configuration. ContextSelectors are free to implement any mechanism they desire to manage
LoggerContexts. The default Log4jContextFactory checks for the presence of a System Property
named "Log4jContextSelector". If found, the property is expected to contain the name of the Class
that implements the ContextSelector to be used.
Log4j provides five ContextSelectors:
BasicContextSelector
Uses either a LoggerContext that has been stored in a ThreadLocal or a common
LoggerContext.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

258

ClassLoaderContextSelector
Associates LoggerContexts with the ClassLoader that created the caller of the getLogger
call. This is the default ContextSelector.
JndiContextSelector
Locates the LoggerContext by querying JNDI.
AsyncLoggerContextSelector
Creates a LoggerContext that ensures that all loggers are AsyncLoggers.
BundleContextSelector
Associates LoggerContexts with the ClassLoader of the bundle that created the caller of the
getLogger call. This is enabled by default in OSGi environments.
16.1.3 ConfigurationFactory

Modifying the way in which logging can be configured is usually one of the areas with the most
interest. The primary method for doing that is by implementing or extending a ConfigurationFactory.
Log4j provides two ways of adding new ConfigurationFactories. The first is by defining the system
property named "log4j.configurationFactory" to the name of the class that should be searched first for
a configuration. The second method is by defining the ConfigurationFactory as a Plugin.
All the ConfigurationFactories are then processed in order. Each factory is called on its
getSupportedTypes method to determine the file extensions it supports. If a configuration file is
located with one of the specified file extensions then control is passed to that ConfigurationFactory to
load the configuration and create the Configuration object.
Most Configuration extend the BaseConfiguration class. This class expects that the subclass will
process the configuration file and create a hierarchy of Node objects. Each Node is fairly simple
in that it consists of the name of the node, the name/value pairs associated with the node, The
PluginType of the node and a List of all of its child Nodes. BaseConfiguration will then be passed the
Node tree and instantiate the configuration objects from that.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

259

@Plugin(name = "XMLConfigurationFactory", category = "ConfigurationFactory")
@Order(5)
public class XMLConfigurationFactory extends ConfigurationFactory {
/**
* Valid file extensions for XML files.
*/
public static final String[] SUFFIXES = new String[] {".xml", "*"};
/**

* Returns the Configuration.
* @param loggerContext The logger context.
* @param source The InputSource.
* @return The Configuration.
*/
@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source
return new XmlConfiguration(loggerContext, source);
}
/**
* Returns the file suffixes for XML files.
* @return An array of File extensions.
*/
public String[] getSupportedTypes() {
return SUFFIXES;
}
}

16.1.4 LoggerConfig

LoggerConfig objects are where Loggers created by applications tie into the configuration. The
Log4j implementation requires that all LoggerConfigs be based on the LoggerConfig class, so
applications wishing to make changes must do so by extending the LoggerConfig class. To declare
the new LoggerConfig, declare it as a Plugin of type "Core" and providing the name that applications
should specify as the element name in the configuration. The LoggerConfig should also define a
PluginFactory that will create an instance of the LoggerConfig.
The following example shows how the root LoggerConfig simply extends a generic LoggerConfig.
@Plugin(name = "root", category = "Core", printObject = true)
public static class RootLogger extends LoggerConfig {

@PluginFactory
public static LoggerConfig createLogger(@PluginAttribute(value = "additivity", defaultBooleanValue = true
@PluginAttribute(value = "level", defaultStringValue = "ERROR") L
@PluginElement("AppenderRef") AppenderRef[] refs,
@PluginElement("Filters") Filter filter) {
List appenderRefs = Arrays.asList(refs);
return new LoggerConfig(LogManager.ROOT_LOGGER_NAME, appenderRefs, filter, level, additivity);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

260

16.1.5 LogEventFactory

A LogEventFactory is used to generate LogEvents. Applications may replace the standard
LogEventFactory by setting the value of the system property Log4jLogEventFactory to the name of
the custom LogEventFactory class.
Note: When log4j is configured to have all loggers asynchronous, log events are pre-allocated in a
ring buffer and the LogEventFactory is not used.
16.1.6 MessageFactory

A MessageFactory is used to generate Message objects. Applications may replace the standard
ParameterizedMessageFactory (or ReusableMessageFactory in garbage-free mode) by setting the
value of the system property log4j2.messageFactory to the name of the custom MessageFactory class.
Flow messages for the Logger.entry() and Logger.exit() methods have a separate
FlowMessageFactory. Applications may replace the DefaultFlowMessageFactory by setting the value
of the system property log4j2.flowMessageFactory to the name of the custom FlowMessageFactory
class.
16.1.7 Lookups

Lookups are the means in which parameter substitution is performed. During Configuration
initialization an "Interpolator" is created that locates all the Lookups and registers them for use when
a variable needs to be resolved. The interpolator matches the "prefix" portion of the variable name to a
registered Lookup and passes control to it to resolve the variable.
A Lookup must be declared using a Plugin annotation with a type of "Lookup". The name specified
on the Plugin annotation will be used to match the prefix. Unlike other Plugins, Lookups do not use
a PluginFactory. Instead, they are required to provide a constructor that accepts no arguments. The
example below shows a Lookup that will return the value of a System Property.
The provided Lookups are documented here: Lookups
@Plugin(name = "sys", category = "Lookup")
public class SystemPropertiesLookup implements StrLookup {
/**
* Lookup the value for the key.
* @param key the key to be looked up, may be null
* @return The value for the key.
*/
public String lookup(String key) {
return System.getProperty(key);
}
/**
* Lookup the value for the key using the data in the LogEvent.
* @param event The current LogEvent.
* @param key the key to be looked up, may be null
* @return The value associated with the key.
*/
public String lookup(LogEvent event, String key) {
return System.getProperty(key);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

261

16.1.8 Filters

As might be expected, Filters are the used to reject or accept log events as they pass through the
logging system. A Filter is declared using a Plugin annotation of type "Core" and an elementType of
"filter". The name attribute on the Plugin annotation is used to specify the name of the element users
should use to enable the Filter. Specifying the printObject attribute with a value of "true" indicates
that a call to toString will format the arguments to the filter as the configuration is being processed.
The Filter must also specify a PluginFactory method that will be called to create the Filter.
The example below shows a Filter used to reject LogEvents based upon their logging level. Notice the
typical pattern where all the filter methods resolve to a single filter method.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

262

@Plugin(name = "ThresholdFilter", category = "Core", elementType = "filter", printObject = true)
public final class ThresholdFilter extends AbstractFilter {
private final Level level;
private ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
super(onMatch, onMismatch);
this.level = level;
}
public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
return filter(level);
}
public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
return filter(level);
}
public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
return filter(level);
}
@Override
public Result filter(LogEvent event) {
return filter(event.getLevel());
}
private Result filter(Level level) {
return level.isAtLeastAsSpecificAs(this.level) ? onMatch : onMismatch;
}
@Override
public String toString() {
return level.toString();
}

/**
* Create a ThresholdFilter.
* @param loggerLevel The log Level.
* @param match The action to take on a match.
* @param mismatch The action to take on a mismatch.
* @return The created ThresholdFilter.
*/
@PluginFactory
public static ThresholdFilter createFilter(@PluginAttribute(value = "level", defaultStringValue = "ERROR"
@PluginAttribute(value = "onMatch", defaultStringValue = "NEUT
@PluginAttribute(value = "onMismatch", defaultStringValue = "D
return new ThresholdFilter(level, onMatch, onMismatch);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

263

16.1.9 Appenders

Appenders are passed an event, (usually) invoke a Layout to format the event, and then "publish"
the event in whatever manner is desired. Appenders are declared as Plugins with a type of "Core"
and an elementType of "appender". The name attribute on the Plugin annotation specifies the name
of the element users must provide in their configuration to use the Appender. Appenders should
specify printObject as "true" if the toString method renders the values of the attributes passed to the
Appender.
Appenders must also declare a PluginFactory method that will create the appender. The example
below shows an Appender named "Stub" that can be used as an initial template.
Most Appenders use Managers. A manager actually "owns" the resources, such as an OutputStream
or socket. When a reconfiguration occurs a new Appender will be created. However, if nothing
significant in the previous Manager has changed, the new Appender will simply reference it instead
of creating a new one. This insures that events are not lost while a reconfiguration is taking place
without requiring that logging pause while the reconfiguration takes place.
@Plugin(name = "Stub", category = "Core", elementType = "appender", printObject = true)
public final class StubAppender extends OutputStreamAppender {
private StubAppender(String name, Layout layout, Filter filter, StubManager manager,
boolean ignoreExceptions) {
}
@PluginFactory
public static StubAppender createAppender(@PluginAttribute("name") String name,
@PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
@PluginElement("Layout") Layout layout,
@PluginElement("Filters") Filter filter) {
if (name == null) {
LOGGER.error("No name provided for StubAppender");
return null;
}
StubManager manager = StubManager.getStubManager(name);
if (manager == null) {
return null;
}
if (layout == null) {
layout = PatternLayout.createDefaultLayout();
}
return new StubAppender(name, layout, filter, manager, ignoreExceptions);
}
}

16.1.10 Layouts

Layouts perform the formatting of events into the printable text that is written by Appenders to some
destination. All Layouts must implement the Layout interface. Layouts that format the event into a
String should extend AbstractStringLayout, which will take care of converting the String into the
required byte array.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

264

Every Layout must declare itself as a plugin using the Plugin annotation. The type must be "Core",
and the elementType must be "layout". printObject should be set to true if the plugin's toString
method will provide a representation of the object and its parameters. The name of the plugin must
match the value users should use to specify it as an element in their Appender configuration. The
plugin also must provide a static method annotated as a PluginFactory and with each of the methods
parameters annotated with PluginAttr or PluginElement as appropriate.
@Plugin(name = "SampleLayout", category = "Core", elementType = "layout", printObject = true)
public class SampleLayout extends AbstractStringLayout {
protected SampleLayout(boolean locationInfo, boolean properties, boolean complete,
Charset charset) {
}

@PluginFactory
public static SampleLayout createLayout(@PluginAttribute("locationInfo") boolean locationInfo,
@PluginAttribute("properties") boolean properties,
@PluginAttribute("complete") boolean complete,
@PluginAttribute(value = "charset", defaultStringValue = "UTF-8")
return new SampleLayout(locationInfo, properties, complete, charset);
}
}

16.1.11 PatternConverters

PatternConverters are used by the PatternLayout to format the log event into a printable String. Each
Converter is responsible for a single kind of manipulation, however Converters are free to format the
event in complex ways. For example, there are several converters that manipulate Throwables and
format them in various ways.
A PatternConverter must first declare itself as a Plugin using the standard Plugin annotation but must
specify value of "Converter" on the type attribute. Furthermore, the Converter must also specify the
ConverterKeys attribute to define the tokens that can be specified in the pattern (preceded by a '%'
character) to identify the Converter.
Unlike most other Plugins, Converters do not use a PluginFactory. Instead, each Converter is required
to provide a static newInstance method that accepts an array of Strings as the only parameter. The
String array are the values that are specified within the curly braces that can follow the converter key.
The following shows the skeleton of a Converter plugin.
@Plugin(name = "query", category = "Converter")
@ConverterKeys({"q", "query"})
public final class QueryConverter extends LogEventPatternConverter {
public QueryConverter(String[] options) {
}
public static QueryConverter newInstance(final String[] options) {
return new QueryConverter(options);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

265

16.1.12 Plugin Builders

Some plugins take a lot of optional configuration options. When a plugin takes many options, it is
more maintainable to use a builder class rather than a factory method (see Item 2: Consider a builder
when faced with many constructor parameters in Effective Java by Joshua Bloch). There are some
other advantages to using an annotated builder class over an annotated factory method:
• Attribute names don't need to be specified if they match the field name.
• Default values can be specified in code rather than through an annotation (also allowing a
runtime-calculated default value which isn't allowed in annotations).
• Adding new optional parameters doesn't require existing programmatic configuration to be
refactored.
• Easier to write unit tests using builders rather than factory methods with optional parameters.
• Default values are specified via code rather than relying on reflection and injection, so they work
programmatically as well as in a configuration file.
Here is an example of a plugin factory from ListAppender:
@PluginFactory
public static ListAppender createAppender(
@PluginAttribute("name") @Required(message = "No name provided for ListAppender") final String name,
@PluginAttribute("entryPerNewLine") final boolean newLine,
@PluginAttribute("raw") final boolean raw,
@PluginElement("Layout") final Layout layout,
@PluginElement("Filter") final Filter filter) {
return new ListAppender(name, filter, layout, newLine, raw);
}

Here is that same factory using a builder pattern instead:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

266

@PluginBuilderFactory
public static Builder newBuilder() {
return new Builder();
}
public static class Builder implements org.apache.logging.log4j.core.util.Builder {
@PluginBuilderAttribute
@Required(message = "No name provided for ListAppender")
private String name;
@PluginBuilderAttribute
private boolean entryPerNewLine;
@PluginBuilderAttribute
private boolean raw;
@PluginElement("Layout")
private Layout layout;
@PluginElement("Filter")
private Filter filter;
public Builder setName(final String name) {
this.name = name;
return this;
}
public Builder setEntryPerNewLine(final boolean entryPerNewLine) {
this.entryPerNewLine = entryPerNewLine;
return this;
}
public Builder setRaw(final boolean raw) {
this.raw = raw;
return this;
}
public Builder setLayout(final Layout layout) {
this.layout = layout;
return this;
}
public Builder setFilter(final Filter filter) {
this.filter = filter;
return this;
}
@Override
public ListAppender build() {
return new ListAppender(name, filter, layout, entryPerNewLine, raw);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

16 Extending Log4j

267

The only difference in annotations is using @PluginBuilderAttribute instead of
@PluginAttribute so that default values and reflection can be used instead of specifying them
in the annotation. Either annotation can be used in a builder, but the former is better suited for field
injection while the latter is better suited for parameter injection. Otherwise, the same annotations
( @PluginConfiguration, @PluginElement, @PluginNode, and @PluginValue) are all
supported on fields. Note that a factory method is still required to supply a builder, and this factory
method should be annotated with @PluginBuilderFactory.
When plugins are being constructed after a configuration has been parsed, a plugin builder will be
used if available, otherwise a plugin factory method will be used as a fallback. If a plugin contains
neither factory, then it cannot be used from a configuration file (it can still be used programmatically
of course).
Here is an example of using a plugin factory versus a plugin builder programmatically:
ListAppender list1 = ListAppender.createAppender("List1", true, false, null, null);
ListAppender list2 = ListAppender.newBuilder().setName("List1").setEntryPerNewLine(true).build();

16.1.13 Custom ContextDataInjector

The ContextDataInjector (introduced in Log4j 2.7) is responsible for populating the LogEvent's
context data with key-value pairs or replacing it completely. The default implementation is
ThreadContextDataInjector, which obtains context attributes from the ThreadContext.
Applications may replace the default ContextDataInjector by setting the value of the system property
log4j2.contextDataInjector to the name of the custom ContextDataInjector class.
Implementors should be aware there are some subtleties related to thread-safety and implementing a
context data injector in a garbage-free manner. See the ContextDataInjector javadoc for detail.
16.1.14 Custom ThreadContextMap implementations

A garbage-free StringMap-based context map can be installed by setting system property
log4j2.garbagefreeThreadContextMap to true. (Log4j must be enabled to use ThreadLocals.)
Any custom ThreadContextMap implementation can be installed by setting system property
log4j2.threadContextMap to the fully qualified class name of the class implementing the
ThreadContextMap interface. By also implementing the ReadOnlyThreadContextMap interface,
your custom ThreadContextMap implementation will be accessible to applications via the
ThreadContext::getThreadContextMap method.
16.1.15 Custom Plugins

See the Plugins section of the manual.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

268

17 Programmatic Log4j Configuration

.......................................................................................................................................
17.1 Programmatic Configuration
Log4j 2 provides a few ways for applications to create their own programmatic configuration:
•
•
•
•

Specify a custom ConfigurationFactory to start Log4j with a programmatic configuration
Use the Configurator to replace the configuration after Log4j started
Initialize Log4j with a combination of a configuration file and programmatic configuration
Modify the current Configuration after initialization

17.1.1 The ConfigurationBuilder API

Starting with release 2.4, Log4j provides a ConfigurationBuilder and a set of component builders that
allow a Configuration to be created fairly easily. Actual configuration objects like LoggerConfig or
Appender can be unwieldy; they require a lot of knowledge about Log4j internals which makes them
difficult to work with if all you want is to create a Configuration.
The new ConfigurationBuilder API (in the
org.apache.logging.log4j.core.config.builder.api package) allows users to create

Configurations in code by constructing component definitions. There is no need to work directly
with actual configuration objects. Component definitions are added to the ConfigurationBuilder, and
once all the definitions have been collected all the actual configuration objects (like Loggers and
Appenders) are constructed.
ConfigurationBuilder has convenience methods for the base components that can be configured such
as Loggers, Appenders, Filter, Properties, etc. However, Log4j 2's plugin mechanism means that users
can create any number of custom components. As a trade-off, the ConfigurationBuilder API provides
only a limited number of "strongly typed" convenience methods like newLogger(), newLayout()
etc. The generic builder.newComponent() method can be used if no convenience method exists
for the component you want to configure.
For example, the builder does not know what sub-components can be configured on specific
components such as the RollingFileAppender vs. the RoutingAppender. To specify a triggering policy
on a RollingFileAppender you would use builder.newComponent().
Examples of using the ConfigurationBuilder API are in the sections that follow.

17.1.2 Understanding ConfigurationFactory

During initialization, Log4j 2 will search for available ConfigurationFactories and then select the one
to use. The selected ConfigurationFactory creates the Configuration that Log4j will use. Here is how
Log4j finds the available ConfigurationFactories:
1. A system property named log4j2.configurationFactory can be set with the name of the
ConfigurationFactory to be used.
2. ConfigurationFactory.setConfigurationFactory(ConfigurationFactory) can be
called with the instance of the ConfigurationFactory to be used. This must be called before any
other calls to Log4j.
3. A ConfigurationFactory implementation can be added to the classpath and configured as a plugin
in the "ConfigurationFactory" category. The Order annotation can be used to specify the relative
priority when multiple applicable ConfigurationFactories are found.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

ConfigurationFactories have the concept of "supported types", which basically maps to the file
extension of the configuration file that the ConfigurationFactory can handle. If a configuration
file location is specified, ConfigurationFactories whose supported type does not include "*" or the
matching file extension will not be used.

17.1.3 Initialize Log4j Using ConfigurationBuilder with a Custom ConfigurationFactory

One way to programmatically configure Log4j 2 is to create a custom ConfigurationFactory
that uses the ConfigurationBuilder to create a Configuration. The below example overrides the
getConfiguration() method to return a Configuration created by the ConfigurationBuilder.
This will cause the Configuration to automatically be hooked into Log4j when the LoggerContext
is created. In the example below, because it specifies a supported type of "*" it will override any
configuration files provided.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

269

17 Programmatic Log4j Configuration

270

@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY)
@Order(50)
public class CustomConfigurationFactory extends ConfigurationFactory {

static Configuration createConfiguration(final String name, ConfigurationBuilder buil
builder.setConfigurationName(name);
builder.setStatusLevel(Level.ERROR);
builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).
addAttribute("level", Level.DEBUG));
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").
addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout").
addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY,
Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
builder.add(appenderBuilder);
builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
add(builder.newAppenderRef("Stdout")).
addAttribute("additivity", false));
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
return builder.build();
}

@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final ConfigurationSource source
return getConfiguration(loggerContext, source.toString(), null);
}

@Override
public Configuration getConfiguration(final LoggerContext loggerContext, final String name, final URI con
ConfigurationBuilder builder = newConfigurationBuilder();
return createConfiguration(name, builder);
}
@Override
protected String[] getSupportedTypes() {
return new String[] {"*"};
}
}

As of version 2.7, the ConfigurationFactory.getConfiguration() methods take an
additional LoggerContext parameter.

17.1.4 Reconfigure Log4j Using ConfigurationBuilder with the Configurator

An alternative to a custom ConfigurationFactory is to configure with the Configurator.
Once a Configuration object has been constructed, it can be passed to one of the
Configurator.initialize methods to set up the Log4j configuration.
Using the Configurator in this manner allows the application control over when Log4j is initialized.
However, should any logging be attempted before Configurator.initialize() is called then the default
configuration will be used for those log events.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

271

ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel(Level.ERROR);
builder.setConfigurationName("BuilderTest");
builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL)
.addAttribute("level", Level.DEBUG));
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL)
.addAttribute("marker", "FLOW"));
builder.add(appenderBuilder);
builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG)
.add(builder.newAppenderRef("Stdout")).addAttribute("additivity", false));
builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
ctx = Configurator.initialize(builder.build());

This example shows how to create a configuration that includes a RollingFileAppender.
ConfigurationBuilder< BuiltConfiguration > builder = ConfigurationBuilderFactory.newConfigurationBuilder();
builder.setStatusLevel( Level.ERROR);
builder.setConfigurationName("RollingBuilder");
// create a console appender
AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
ConsoleAppender.Target.SYSTEM_OUT);
appenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
builder.add( appenderBuilder );
// create a rolling file appender
LayoutComponentBuilder layoutBuilder = builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d [%t] %-5level: %msg%n");
ComponentBuilder triggeringPolicy = builder.newComponent("Policies")
.addComponent(builder.newComponent("CronTriggeringPolicy").addAttribute("schedule", "0 0 0 * * ?"))
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "100M"));
appenderBuilder = builder.newAppender("rolling", "RollingFile")
.addAttribute("fileName", "target/rolling.log")
.addAttribute("filePattern", "target/archive/rolling-%d{MM-dd-yy}.log.gz")
.add(layoutBuilder)
.addComponent(triggeringPolicy);
builder.add(appenderBuilder);
// create the new logger
builder.add( builder.newLogger( "TestLogger", Level.DEBUG )
.add( builder.newAppenderRef( "rolling" ) )
.addAttribute( "additivity", false ) );
builder.add( builder.newRootLogger( Level.DEBUG )
.add( builder.newAppenderRef( "rolling" ) ) );
LoggerContext ctx = Configurator.initialize(builder.build());

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

272

17.1.5 Initialize Log4j by Combining Configuration File with Programmatic Configuration

Sometimes you want to configure with a configuration file but do some additional programmatic
configuration. A possible use case might be that you want to allow for a flexible configuration using
XML but at the same time make sure there are a few configuration elements that are always present
that can't be removed.
The easiest way to achieve this is to extend one of the standard Configuration classes
(XMLConfiguration, JSONConfiguration) and then create a new ConfigurationFactory for the
extended class. After the standard configuration completes the custom configuration can be added to
it.
The example below shows how to extend XMLConfiguration to manually add an Appender and a
LoggerConfig to the configuration.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

273

@Plugin(name = "MyXMLConfigurationFactory", category = "ConfigurationFactory")
@Order(10)
public class MyXMLConfigurationFactory extends ConfigurationFactory {
/**
* Valid file extensions for XML files.
*/
public static final String[] SUFFIXES = new String[] {".xml", "*"};
/**
* Return the Configuration.
* @param source The InputSource.
* @return The Configuration.
*/
public Configuration getConfiguration(InputSource source) {
return new MyXMLConfiguration(source, configFile);
}
/**
* Returns the file suffixes for XML files.
* @return An array of File extensions.
*/
public String[] getSupportedTypes() {
return SUFFIXES;
}
}
public class MyXMLConfiguration extends XMLConfiguration {
public MyXMLConfiguration(final ConfigurationFactory.ConfigurationSource configSource) {
super(configSource);
}

@Override
protected void doConfigure() {
super.doConfigure();
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, nul
null,null, null);
final Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "t
"false", "false", "4000", layout, null, "false", null, config);
appender.start();
addAppender(appender);
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j",
"true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
addLogger("org.apache.logging.log4j", loggerConfig);
}
}

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

274

17.1.6 Programmatically Modifying the Current Configuration after Initialization

Applications sometimes have the need to customize logging separate from the actual configuration.
Log4j allows this although it suffers from a few limitations:
1. If the configuration file is changed the configuration will be reloaded and the manual changes
will be lost.
2. Modification to the running configuration requires that all the methods being called
(addAppender and addLogger) be synchronized.
As such, the recommended approach for customizing a configuration is to extend one of the standard
Configuration classes, override the setup method to first do super.setup() and then add the custom
Appenders, Filters and LoggerConfigs to the configuration before it is registered for use.
The following example adds an Appender and a new LoggerConfig using that Appender to the current
configuration.
final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
final Configuration config = ctx.getConfiguration();
Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null,
null,null, null);
Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true",
"false", "false", "4000", layout, null, "false", null, config);
appender.start();
config.addAppender(appender);
AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
AppenderRef[] refs = new AppenderRef[] {ref};
LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j",
"true", refs, null, config, null );
loggerConfig.addAppender(appender, null, null);
config.addLogger("org.apache.logging.log4j", loggerConfig);
ctx.updateLoggers();
}

17.1.7 Appending Log Events to Writers and OutputStreams Programmatically

Log4j 2.5 provides facilities to append log events to Writers and OutputStreams. For example,
this provides simple integration for JDBC Driver implementors that use Log4j internally and
still want to support the JDBC APIs CommonDataSource.setLogWriter(PrintWriter),
java.sql.DriverManager.setLogWriter(PrintWriter), and
java.sql.DriverManager.setLogStream(PrintStream).
Given any Writer, like a PrintWriter, you tell Log4j to append events to that writer by creating a
WriterAppender and updating the Log4j configuration:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

17 Programmatic Log4j Configuration

275

void addAppender(final Writer writer, final String writerName) {
final LoggerContext context = LoggerContext.getContext(false);
final Configuration config = context.getConfiguration();
final PatternLayout layout = PatternLayout.createDefaultLayout(config);
final Appender appender = WriterAppender.createAppender(layout, null, writer, writerName, false, true);
appender.start();
config.addAppender(appender);
updateLoggers(appender, config);
}
private void updateLoggers(final Appender appender, final Configuration config) {
final Level level = null;
final Filter filter = null;
for (final LoggerConfig loggerConfig : config.getLoggers().values()) {
loggerConfig.addAppender(appender, level, filter);
}
config.getRootLogger().addAppender(appender, level, filter);
}

You can achieve the same effect with an OutputStream, like a PrintStream:

void addAppender(final OutputStream outputStream, final String outputStreamName) {
final LoggerContext context = LoggerContext.getContext(false);
final Configuration config = context.getConfiguration();
final PatternLayout layout = PatternLayout.createDefaultLayout(config);
final Appender appender = OutputStreamAppender.createAppender(layout, null, outputStream, outputStreamNam
appender.start();
config.addAppender(appender);
updateLoggers(appender, config);
}

The difference is the use of OutputStreamAppender instead of WriterAppender.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

276

18 Custom Log Levels

.......................................................................................................................................

18.1 Custom Log Levels

18.1.1 Defining Custom Log Levels in Code

Log4J 2 supports custom log levels. Custom log levels can be defined in code or in configuration. To
define a custom log level in code, use the Level.forName() method. This method creates a new
level for the specified name. After a log level is defined you can log messages at this level by calling
the Logger.log() method and passing the custom log level:
// This creates the "VERBOSE" level if it does not exist yet.
final Level VERBOSE = Level.forName("VERBOSE", 550);
final Logger logger = LogManager.getLogger();
logger.log(VERBOSE, "a verbose message"); // use the custom VERBOSE level
// Create and use a new custom level "DIAG".
logger.log(Level.forName("DIAG", 350), "a diagnostic message");
// Use (don't create) the "DIAG" custom level.
// Only do this *after* the custom level is created!
logger.log(Level.getLevel("DIAG"), "another diagnostic message");
// Using an undefined level results in an error: Level.getLevel() returns null,
// and logger.log(null, "message") throws an exception.
logger.log(Level.getLevel("FORGOT_TO_DEFINE"), "some message"); // throws exception!

When defining a custom log level, the intLevel parameter (550 and 350 in the example above)
determines where the custom level exists in relation to the standard levels built-in to Log4J 2. For
reference, the table below shows the intLevel of the built-in log levels.
Standard Level

intLevel

OFF

0

FATAL

100

ERROR

200

WARN

300

INFO

400

DEBUG

500

TRACE

600

ALL

Integer.MAX_VALUE

Standard log levels built-in to Log4J

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

277

18.1.2 Defining Custom Log Levels in Configuration

Custom log levels can also be defined in configuration. This is convenient for using a custom level
in a logger filter or an appender filter. Similar to defining log levels in code, a custom level must be
defined first, before it can be used. If a logger or appender is configured with an undefined level, that
logger or appender will be invalid and will not process any log events.
The CustomLevel configuration element creates a custom level. Internally it calls the same
Level.forName() method discussed above.
Parameter Name

Type

Description

name

String

The name of the custom level. Note
that level names are case sensitive.
The convention is to use all uppercase names.

intLevel

integer

Determines where the custom level
exists in relation to the standard
levels built-in to Log4J 2 (see the
table above).

CustomLevel Parameters
The following example shows a configuration that defines some custom log levels and uses a custom
log level to filter log events sent to the console.

























©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

278

18.1.3 Convenience Methods for the Built-in Log Levels

The built-in log levels have a set of convenience methods on the Logger interface that makes them
easier to use. For example, the Logger interface has 24 debug() methods that support the DEBUG
level:
// convenience methods for the built-in DEBUG level
debug(Marker, Message)
debug(Marker, Message, Throwable)
debug(Marker, Object)
debug(Marker, Object, Throwable)
debug(Marker, String)
debug(Marker, String, Object...)
debug(Marker, String, Throwable)
debug(Message)
debug(Message, Throwable)
debug(Object)
debug(Object, Throwable)
debug(String)
debug(String, Object...)
debug(String, Throwable)
// lambda support methods added in 2.4
debug(Marker, MessageSupplier)
debug(Marker, MessageSupplier, Throwable)
debug(Marker, String, Supplier...)
debug(Marker, Supplier)
debug(Marker, Supplier, Throwable)
debug(MessageSupplier)
debug(MessageSupplier, Throwable)
debug(String, Supplier...)
debug(Supplier)
debug(Supplier, Throwable)

Similar methods exist for the other built-in levels. Custom levels, in contrast, need to pass in the log
level as an extra parameter.
// need to pass the custom level as a parameter
logger.log(VERBOSE, "a verbose message");
logger.log(Level.forName("DIAG", 350), "another message");

It would be nice to have the same ease of use with custom levels, so that after declaring the custom
VERBOSE/DIAG levels, we could use code like this:
// nice to have: descriptive methods and no need to pass the level as a parameter
logger.verbose("a verbose message");
logger.diag("another message");
logger.diag("java 8 lambda expression: {}", () -> someMethod());

The standard Logger interface cannot provide convenience methods for custom levels, but the next
few sections introduce a code generation tool to create loggers that aim to make custom levels as easy
to use as built-in levels.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

279

18.1.4 Adding or Replacing Log Levels

We assume that most users want to add custom level methods to the Logger interface, in addition to
the existing trace(), debug(), info(), ... methods for the built-in log levels.
There is another use case, Domain Specific Language loggers, where we want to replace the existing
trace(), debug(), info(), ... methods with all-custom methods.
For example, for medical devices we could have only critical(), warning(), and advisory()
methods. Another example could be a game that has only defcon1(), defcon2(), and defcon3()
levels.
If it were possible to hide existing log levels, users could customize the Logger interface to match
their requirements. Some people may not want to have a FATAL or a TRACE level, for example.
They would like to be able to create a custom Logger that only has debug(), info(), warn() and error()
methods.

18.1.5 Generating Source Code for a Custom Logger Wrapper

Common Log4J usage is to get an instance of the Logger interface from the LogManager and call
the methods on this interface. However, the custom log Levels are not known in advance, so Log4J
cannot provide an interface with convenience methods for these custom log Levels.
To solve this, Log4J ships with a tool that generates source code for a Logger wrapper. The generated
wrapper class has convenience methods for each custom log level, making custom levels just as easy
to use as the built-in levels.
There are two flavors of wrappers: ones that extend the Logger API (adding methods to the built-in
levels) and ones that customize the Logger API (replacing the built-in methods).
When generating the source code for a wrapper class, you need to specify:
• the fully qualified name of the class to generate
• the list of custom levels to support and their intLevel relative strength
• whether to extend Logger (and keep the existing built-in methods) or have only methods for the
custom log levels
You would then include the generated source code in the project where you want to use custom log
levels.

18.1.6 Example Usage of a Generated Logger Wrapper

Here is an example of how one would use a generated logger wrapper with custom levels DIAG,
NOTICE and VERBOSE:

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

280

// ExtLogger is a generated logger wrapper
import com.mycompany.myproject.ExtLogger;
public class MyService {
// instead of Logger logger = LogManager.getLogger(MyService.class):
private static final ExtLogger logger = ExtLogger.create(MyService.class);
public void demoExtendedLogger() {
// ...
logger.trace("the built-in TRACE level");

logger.verbose("a custom level: a VERBOSE message");
logger.debug("the built-in DEBUG level");
logger.notice("a custom level: a NOTICE message");
logger.info("the built-in INFO level");
logger.diag("a custom level: a DIAG message");
logger.warn("the built-in WARN level");
logger.error("the built-in ERROR level");
logger.fatal("the built-in FATAL level");
logger.notice("java 8 lambda expression only executed if NOTICE is enabled: {}", () -> someMethod());
// ...
}
...
}

18.1.7 Generating Extended Loggers

Use the following command to generate a logger wrapper that adds methods to the built-in ones:
java -cp log4j-core-${Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator \
com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 > com/mycomp/ExtLogger.java

This will generate source code for a logger wrapper that has the convenience methods for the built-in
levels as well as the specified custom levels. The tool prints the generated source code to the console.
By appending " > filename" the output can be redirected to a file.
NOTE: Prior to log4j-2.9, this tool was an inner class Generate$ExtendedLogger.
Under the bash shell on Unix/Mac/Linux the dollar character $ needs to be escaped, so the class name
should be between single quotes 'org.apache.logging.log4j.core.tools.Generate$ExtendedLogger’.
18.1.8 Generating Custom Loggers

Use the following command to generate a logger wrapper that hides the built-in levels and has only
custom levels:
java -cp log4j-core-${Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.CustomLoggerGenerator \
com.mycomp.MyLogger DEFCON1=350 DEFCON2=450 DEFCON3=550 > com/mycomp/MyLogger.java

This will generate source code for a logger wrapper that only has convenience methods for the
specified custom levels, not for the built-in levels. The tool prints the generated source code to the
console. By appending " > filename" the output can be redirected to a file.
NOTE: Prior to log4j-2.9, this tool was an inner class Generate$ExtendedLogger.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.

18 Custom Log Levels

281

Under the bash shell on Unix/Mac/Linux the dollar character $ needs to be escaped, so the class name
should be between single quotes 'org.apache.logging.log4j.core.tools.Generate$CustomLogger’.

©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.



Source Exif Data:
File Type                       : PDF
File Type Extension             : pdf
MIME Type                       : application/pdf
Linearized                      : No
Page Count                      : 285
Profile CMM Type                : Linotronic
Profile Version                 : 2.1.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 1998:02:09 06:49:00
Profile File Signature          : acsp
Primary Platform                : Microsoft Corporation
CMM Flags                       : Not Embedded, Independent
Device Manufacturer             : Hewlett-Packard
Device Model                    : sRGB
Device Attributes               : Reflective, Glossy, Positive, Color
Rendering Intent                : Perceptual
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : Hewlett-Packard
Profile ID                      : 0
Profile Copyright               : Copyright (c) 1998 Hewlett-Packard Company
Profile Description             : sRGB IEC61966-2.1
Media White Point               : 0.95045 1 1.08905
Media Black Point               : 0 0 0
Red Matrix Column               : 0.43607 0.22249 0.01392
Green Matrix Column             : 0.38515 0.71687 0.09708
Blue Matrix Column              : 0.14307 0.06061 0.7141
Device Mfg Desc                 : IEC http://www.iec.ch
Device Model Desc               : IEC 61966-2.1 Default RGB colour space - sRGB
Viewing Cond Desc               : Reference Viewing Condition in IEC61966-2.1
Viewing Cond Illuminant         : 19.6445 20.3718 16.8089
Viewing Cond Surround           : 3.92889 4.07439 3.36179
Viewing Cond Illuminant Type    : D50
Luminance                       : 76.03647 80 87.12462
Measurement Observer            : CIE 1931
Measurement Backing             : 0 0 0
Measurement Geometry            : Unknown
Measurement Flare               : 0.999%
Measurement Illuminant          : D65
Technology                      : Cathode Ray Tube Display
Red Tone Reproduction Curve     : (Binary data 2060 bytes, use -b option to extract)
Green Tone Reproduction Curve   : (Binary data 2060 bytes, use -b option to extract)
Blue Tone Reproduction Curve    : (Binary data 2060 bytes, use -b option to extract)
Title                           : Apache Log4j 2
Creator                         : The Apache Logging Project
Date                            : 2018:03:17 16:05:46-07:00
PDF Version                     : 1.4
Producer                        : Maven PDF Plugin v. 1.2, 'fo' implementation.
Create Date                     : 2018:03:17 16:05:46-07:00
Creator Tool                    : rgoers
Page Mode                       : UseOutlines
Author                          : The Apache Logging Project
EXIF Metadata provided by EXIF.tools

Navigation menu