Apache Log4j 2 Users Guide
log4j-users-guide
log4j-users-guide
User Manual:
Open the PDF directly: View PDF .
Page Count: 285 [warning: Documents this large are best viewed by clicking the View PDF Link!]
......................................................................................................................................
Apache Log4j 2
v. 2.11.0
User's Guide
......................................................................................................................................
The Apache Software Foundation 2018-03-17
Table of Contents i
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
Table of Contents
.......................................................................................................................................
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
Table of Contents ii
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
1 Introduction 1
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
1 Introduction 2
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
2 Architecture 3
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
2 Architecture 4
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
2 Architecture 5
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
2 Architecture 6
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
2 Architecture 7
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
2 Architecture 8
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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, A-
xyz1 Appenders in
"x.y.z", "x" and root.
2 Architecture 9
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
3 Log4j 1.x Migration 10
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
3 Log4j 1.x Migration 11
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="info" />
</category>
<Root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>
Log4j 2 XML configuration
3 Log4j 1.x Migration 12
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="info"/>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
3.1.3.2 Sample 2 - Simple configuration using a File Appender, XMLLayout and SimpleLayout
Log4j 1.x XML configuration
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.FileAppender">
<param name="File" value="A1.log" />
<param name="Append" value="false" />
<layout class="org.apache.log4j.xml.XMLLayout" />
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.SimpleLayout" />
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug" />
<appender-ref ref="A1" />
</category>
<root>
<priority value ="debug" />
<appender-ref ref="STDOUT" />
</Root>
</log4j:configuration>
Log4j 2 XML configuration
3 Log4j 1.x Migration 13
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<File name="A1" fileName="A1.log" append="false">
<Log4j1XmlLayout />
</File>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%level - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
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.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="A1" class="org.apache.log4j.net.SocketAppender">
<param name="RemoteHost" value="localhost"/>
<param name="Port" value="5000"/>
<param name="LocationInfo" value="true"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
</layout>
</appender>
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<category name="org.apache.log4j.xml">
<priority value="debug"/>
<appender-ref ref="A1"/>
</category>
<root>
<priority value="debug"/>
<appender-ref ref="STDOUT"/>
</Root>
</log4j:configuration>
Log4j 2 XML configuration
3 Log4j 1.x Migration 14
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Socket name="A1" host="localHost" port="5000">
<PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
</Socket>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="org.apache.log4j.xml" level="debug">
<AppenderRef ref="A1"/>
</Logger>
<Root level="debug">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
3.1.3.4 Sample 4 - AsyncAppender and TTCCLayout
Log4j 1.x XML configuration using the AsyncAppender.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.TTCCLayout">
<param name="ThreadPrinting" value="true"/>
<param name="CategoryPrefixing" value="true"/>
<param name="ContextPrinting" value="true"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>
Log4j 2 XML configuration.
3 Log4j 1.x Migration 15
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%r [%t] %p %c %notEmpty{%ndc }- %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>
3.1.3.5 Sample 5 - AsyncAppender with Console and File
Log4j 1.x XML configuration using the AsyncAppender.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
<appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
<appender-ref ref="TEMP"/>
<appender-ref ref="CONSOLE"/>
</appender>
<appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<appender name="TEMP" class="org.apache.log4j.FileAppender">
<param name="File" value="temp"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</layout>
</appender>
<root>
<priority value="debug"/>
<appender-ref ref="ASYNC"/>
</Root>
</log4j:configuration>
Log4j 2 XML configuration. Note that the Async Appender should be configured after the appenders
it references. This will allow it to shutdown properly.
3 Log4j 1.x Migration 16
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</Console>
<File name="TEMP" fileName="temp">
<PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
</File>
<Async name="ASYNC">
<AppenderRef ref="TEMP"/>
<AppenderRef ref="CONSOLE"/>
</Async>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="ASYNC"/>
</Root>
</Loggers>
</Configuration>
4 A P I 17
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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:
4 A P I 18
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=1995,MONTH=4,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=23,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
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.getBirthdayCalendar());
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
4 A P I 19
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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();
}
5 Configuration 20
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 log4j2-
test.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.
5 Configuration 21
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 22
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
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 [main] TRACE MyApp - Entering application.
17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] TRACE com.foo.Bar - exit with (false)
17:13:01.540 [main] ERROR MyApp - Didn't do it.
17:13:01.540 [main] TRACE 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:
<Logger name="com.foo.Bar" level="TRACE"/>
<Root level="ERROR">
<AppenderRef ref="STDOUT">
</Root>
With this configuration all log events from com.foo.Bar will be recorded while only error events
will be recorded from all other components.
5 Configuration 23
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.foo.Bar" level="trace">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
would result in
17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] TRACE com.foo.Bar - entry
17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
17:13:01.540 [main] ERROR 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:
5 Configuration 24
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="com.foo.Bar" level="trace" additivity="false">
<AppenderRef ref="Console"/>
</Logger>
<Root level="error">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
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.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration monitorInterval="30">
...
</Configuration>
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.
5 Configuration 25
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 locally-
running 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.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration advertiser="multicastdns">
...
</Configuration>
<Appenders>
<File name="File1" fileName="output.log" bufferedIO="false" advertiseURI="file://path/to/output.log" advertise="true">
...
</File>
</Appenders>
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
5 Configuration 26
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 27
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
<PatternLayout pattern="%m%n"/>
and
<PatternLayout>
<Pattern>%m%n</Pattern>
</PatternLayout>
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.
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<
filter ... />
<Appenders>
<
appender ... >
<
filter ... />
</
appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<
filter ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
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,
5 Configuration 28
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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".
<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
<Properties>
<Property name="name1">value</property>
<Property name="name2" value="value2"/>
</Properties>
<Filter type="type" ... />
<Appenders>
<Appender type="type" name="name">
<Filter type="type" ... />
</Appender>
...
</Appenders>
<Loggers>
<Logger name="name1">
<Filter type="type" ... />
</Logger>
...
<Root level="level">
<AppenderRef ref="name"/>
</Root>
</Loggers>
</Configuration>
Below is a sample configuration using the strict format.
5 Configuration 29
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" strict="true" name="XMLConfigTest"
packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<Filter type="ThresholdFilter" level="trace"/>
<Appenders>
<Appender type="Console" name="STDOUT">
<Layout type="PatternLayout" pattern="%m MDC%X%n"/>
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
</Filters>
</Appender>
<Appender type="Console" name="FLOW">
<Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
<Filters>
<Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</Filters>
</Appender>
<Appender type="File" name="File" fileName="${filename}">
<Layout type="PatternLayout">
<Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
</Layout>
</Appender>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<Filter type="ThreadContextMapFilter">
<KeyValuePair key="test" value="123"/>
</Filter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<AppenderRef ref="File"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
5 Configuration 30
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 31
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
{ "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": { "level": "debug" }},
{ "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:
5 Configuration 32
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 33
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 34
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/test.log</Property>
</Properties>
<ThresholdFilter level="trace"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m MDC%X%n"/>
</Console>
<Console name="FLOW">
<!-- this pattern outputs class name and line number -->
<PatternLayout pattern="%C{1}.%M %m %ex%n"/>
<filters>
<MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
<MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
</filters>
</Console>
<File name="File" fileName="${filename}">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<Property name="user">${sys:user.name}</Property>
<AppenderRef ref="File">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123"/>
</ThreadContextMapFilter>
</AppenderRef>
<AppenderRef ref="STDOUT" level="error"/>
</Logger>
<Root level="trace">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
5 Configuration 35
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 36
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
5 Configuration 37
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest" packages="org.apache.logging.log4j.test">
<Properties>
<Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property>
</Properties>
<ThresholdFilter level="debug"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n"/>
<ThresholdFilter level="debug"/>
</Console>
<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</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
</Route>
<Route ref="STDOUT" key="Audit"/>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="Routing"/>
</Logger>
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
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}.
5 Configuration 38
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 pre-
populated 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:
5 Configuration 39
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Properties>
<Property name="type">Audit</property>
</Properties>
...
</Configuration>
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 <script>, <scriptFile>, or <scriptRef>
element to be configured on them. The script element contains a name for the script, the language
of the script, and the script text. The scriptFile element contains the name of the script, its location,
its language, its charset, and whether the file should be watched for changes. The scriptRef element
contains the name of the script that is defined in the <scripts> configuration element. The name of
the script is used to store the script, along with its ScriptEngine, so it can quickly be located each
time the script needs to be run. While the name is not required, providing it will help in debugging
problems when the script is running. The language must be provided on the script element and must
specify one of the language names that appear in the Configuration status log as described in the next
section. If the language is not specified on the scriptFile element the language will be determined by
the file extension of the script path. If file monitoring is requested it will only be enabled if a non-
zero monitorInterval is specified on the configuration element. That interval will be used to check for
changes in the file.
5 Configuration 40
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest">
<Scripts>
<Script name="selector" language="javascript"><![CDATA[
var result;
if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
result = "NoLocation";
} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
result = "Flow";
}
result;
]]></Script>
<ScriptFile name="groovy.filter" path="scripts/filter.groovy"/>
</Scripts>
<Appenders>
<Console name="STDOUT">
<ScriptPatternSelector defaultPattern="%d %p %m%n">
<ScriptRef ref="selector"/>
<PatternMatch key="NoLocation" pattern="[%-5level] %c{1.} %msg%n"/>
<PatternMatch key="Flow" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/>
</ScriptPatternSelector>
<PatternLayout pattern="%m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info" additivity="false">
<ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
<Script name="GroovyFilter" language="groovy"><![CDATA[
if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
return true;
} else if (logEvent.getContextMap().containsKey("UserId")) {
return true;
}
return false;
]]>
</Script>
</ScriptFilter>
<AppenderRef ref="STDOUT"/>
</Logger>
<Root level="error">
<ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
<ScriptRef ref="groovy.filter"/>
</ScriptFilter>
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
5 Configuration 41
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 Thread Safe,
Compile: false, Names: {AppleScriptEngine, AppleScript, OSA}
2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED,
Compile: true, Names: {groovy, Groovy}
2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED,
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, Threading: MULTITHREADED,
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.<init>(ScriptManager.java:125)
at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94)
5 Configuration 42
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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:
<?xml version="1.0" encoding="UTF-8"?>
<configuration xmlns:xi="http://www.w3.org/2001/XInclude"
status="warn" name="XIncludeDemo">
<properties>
<property name="filename">xinclude-demo.log</property>
</properties>
<ThresholdFilter level="debug"/>
<xi:include href="log4j-xinclude-appenders.xml" />
<xi:include href="log4j-xinclude-loggers.xml" />
</configuration>
log4j-xinclude-appenders.xml:
<?xml version="1.0" encoding="UTF-8"?>
<appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n" />
</Console>
<File name="File" fileName="${filename}" bufferedIO="true" immediateFlush="true">
<PatternLayout>
<pattern>%d %p %C{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
</appenders>
log4j-xinclude-loggers.xml:
<?xml version="1.0" encoding="UTF-8"?>
<loggers>
<logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
<ThreadContextMapFilter>
<KeyValuePair key="test" value="123" />
</ThreadContextMapFilter>
<AppenderRef ref="STDOUT" />
</logger>
<logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
<AppenderRef ref="File" />
</logger>
<root level="error">
<AppenderRef ref="STDOUT" />
</root>
</loggers>
5 Configuration 43
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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: <Configuration status="trace">.
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
5 Configuration 44
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
attribute are "trace", "debug", "info", "warn", "error" and "fatal". The following configuration has the
status attribute set to debug.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug" name="RoutingTest">
<Properties>
<Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property>
</Properties>
<ThresholdFilter level="debug"/>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%m%n"/>
<ThresholdFilter level="debug"/>
</Console>
<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</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
</Route>
<Route ref="STDOUT" key="Audit"/>
</Routes>
</Routing>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="Routing"/>
</Logger>
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
During startup this configuration produces:
5 Configuration 45
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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")
5 Configuration 46
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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:
<logger name="EventLogger" level="info" additivity="false">
<AppenderRef ref="Routng"/>
</logger>
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);
5 Configuration 47
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 log4j-
core 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<LogEvent> 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
5 Configuration 48
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
Environment Variables -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
file 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.
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..
5 Configuration 49
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.contextSelector
( Log4jContextSelector) LOG4J_CONTEXT_SELECTORClassLoaderContextSelectorCreates 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.async .AsyncLoggerContextSelector
- makes all loggers
asynchronous.
org.apache.logging.log4j.core.selector .BasicContextSelector
- creates a single shared
LoggerContext.
org.apache.logging.log4j.core.selector .ClassLoaderContextSelector
- separate
LoggerContexts for each
web application.
org.apache.logging.log4j.core.selector .JndiContextSelector
- use JNDI to locate
each web application's
LoggerContext.
org.apache.logging.log4j.core.osgi .BundleContextSelector
- separate
LoggerContexts for each
OSGi bundle.
log4j2.logEventFactory
( Log4jLogEventFactory) LOG4J_LOG_EVENT_FACTORYorg.apache.logging.log4j.core.impl .DefaultLogEventFactoryFactory class used by
LoggerConfig to create
LogEvent instances.
(Ignored when the
AsyncLoggerContextSelector
is used.)
log4j2.loggerContextFactory
(
log4j2.loggerContextFactory)
LOG4J_LOGGER_CONTEXT_FACTORYorg.apache.logging.log4j.simple .SimpleLoggerContextFactoryFactory class used
by LogManager to
bootstrap the logging
implementation. The
core jar provides
org.apache.logging.log4j.core .impl.Log4jContextFactory.
log4j2.configurationFactory
(
log4j.configurationFactory)
LOG4J_CONFIGURATION_FACTORY Fully specified class
name of a class extending
org.apache.logging.log4j.core .config.ConfigurationFactory.
If specified, an instance
of this class is added to
the list of configuration
factories.
5 Configuration 50
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.shutdownHookEnabled
(
log4j.shutdownHookEnabled)
LOG4J_SHUTDOWN_HOOK_ENABLEDtrue 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.shutdownCallbackRegistry)
LOG4J_SHUTDOWN_CALLBACK_REGISTRYorg.apache.logging.log4j.core.util .DefaultShutdownCallbackRegistryFully specified class name
of a class implementing
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.util.Clock
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
(
org.apache.logging.log4j.level)
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.disableThreadContext
(disableThreadContext) LOG4J_DISABLE_THREAD_CONTEXTfalse If true, the
ThreadContext stack and
map are disabled. (May
be ignored if a custom
ThreadContext map is
specified.)
log4j2.disableThreadContextStack
(disableThreadContextStack)
LOG4J_DISABLE_THREAD_CONTEXT_STACKfalse If true, the
ThreadContext stack is
disabled.
5 Configuration 51
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.disableThreadContextMap
(disableThreadContextMap)LOG4J_DISABLE_THREAD_CONTEXT_MAPfalse If true, the
ThreadContext map
is disabled. (May be
ignored if a custom
ThreadContext map is
specified.)
log4j2.threadContextMap
(log4j2.threadContextMap) LOG4J_THREAD_CONTEXT_MAP Fully specified class
name of a custom
ThreadContextMap
implementation class.
log4j2.isThreadContextMapInheritable
(isThreadContextMapInheritable)
LOG4J_IS_THREAD_CONTEXT_MAP_INHERITABLEfalse If true use a
InheritableThreadLocal
to implement the
ThreadContext map.
Otherwise, use a plain
ThreadLocal. (May
be ignored if a custom
ThreadContext map is
specified.)
log4j2.contextDataInjector
(
log4j2.ContextDataInjector)
LOG4J_CONTEXT_DATA_INJECTOR Fully specified class
name of a custom
ContextDataInjector
implementation class.
log4j2.garbagefreeThreadContextMap
(
log4j2.garbagefree.threadContextMap)
LOG4J_GARBAGEFREE_THREAD_CONTEXT_MAPfalse Specify "true" to make
the ThreadContext map
garbage-free.
log4j2.disableJmx
( log4j2.disable.jmx) LOG4J_DISABLE_JMX false 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_ASYNCfalse for web apps, true
otherwise 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 If true, the
ConsoleAppender will not
try to use the Jansi output
stream on Windows.
5 Configuration 52
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.ignoreTCL
( log4j.ignoreTCL) 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
(
org.apache.logging.log4j.uuidSequence)
LOG4J_UUID_SEQUENCE 0 System property that may
be used to seed the UUID
generation with an integer
value.
log4j2.simplelogShowContextMap
(
org.apache.logging.log4j .simplelog.showContextMap)
LOG4J_SIMPLELOG_SHOW_CONTEXT_MAPfalse If true, the full
ThreadContext map
is included in each
SimpleLogger log
message.
log4j2.simplelogShowlogname
(
org.apache.logging.log4j .simplelog.showlogname)
LOG4J_SIMPLELOG_SHOWLOGNAMEfalse If true, the logger
name is included in
each SimpleLogger log
message.
log4j2.simplelogShowShortLogname
(
org.apache.logging.log4j .simplelog.showShortLogname)
LOG4J_SIMPLELOG_SHOW_SHORT_LOGNAMEtrue 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
(
org.apache.logging.log4j .simplelog.showdatetime)
LOG4J_SIMPLELOG_SHOWDATETIMEfalse If true, SimpleLogger
log messages contain
timestamp information.
log4j2.simplelogDateTimeFormat
(
org.apache.logging.log4j .simplelog.dateTimeFormat)
LOG4J_SIMPLELOG_DATE_TIME_FORMAT"yyyy/MM/dd
HH:mm:ss:SSS zzz" Date-time format
to use. Ignored if
org.apache.logging.log4j .simplelog.showdatetime
is false.
log4j2.simplelogLogFile
(
org.apache.logging.log4j .simplelog.logFile)
LOG4J_SIMPLELOG_LOG_FILEsystem.err "system.err" (case-
insensitive) logs
to System.err,
"system.out" (case-
insensitive) logs to
System.out, any other
value is interpreted
as a file name to save
SimpleLogger messages
to.
log4j2.simplelogLevel
(
org.apache.logging.log4j .simplelog.level)
LOG4J_SIMPLELOG_LEVELERROR Default level for new
SimpleLogger instances.
log4j2.simplelog.<loggerName>.level
(
org.apache.logging.log4j .simplelog.<loggerName>.level)
LOG4J_SIMPLELOG_<LOGGER_NAME>_LEVELSimpleLogger default log
level Log level for a the
SimpleLogger instance
with the specified name.
5 Configuration 53
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.simplelogStatusLoggerLevel
(
org.apache.logging.log4j.simplelog .StatusLogger.level)
LOG4J_SIMPLELOG_STATUS_LOGGER_LEVELERROR This property is used
to control the initial
StatusLogger level,
and can be overridden
in code by calling
StatusLogger.getLogger() .setLevel(someLevel).
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_LEVELERROR 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.
5 Configuration 54
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.statusLoggerLevel
(
log4j2.StatusLogger.level)
LOG4J_STATUS_LOGGER_LEVELWARN 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
<Configuration
status="trace">,
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().getLevel()
(see property
org.apache.logging.log4j.simplelog .StatusLogger.level).
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().
5 Configuration 55
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.statusLoggerDateformat
(
log4j2.StatusLogger.DateFormat)
LOG4J_STATUS_LOGGER_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
(
AsyncLogger.ExceptionHandler)
LOG4J_ASYNC_LOGGER_EXCEPTION_HANDLERdefault handler See Async Logger
System Properties for
details.
log4j2.asyncLoggerRingBufferSize
(
AsyncLogger.RingBufferSize)
LOG4J_ASYNC_LOGGER_RING_BUFFER_SIZE256 * 1024 See Async Logger
System Properties for
details.
log4j2.asyncLoggerWaitStrategy
(
AsyncLogger.WaitStrategy)
LOG4J_ASYNC_LOGGER_WAIT_STRATEGYTimeout See Async Logger
System Properties for
details.
log4j2.asyncLoggerThreadNameStrategy
(
AsyncLogger.ThreadNameStrategy)
LOG4J_ASYNC_LOGGER_THREAD_NAME_STRATEGYCACHED See Async Logger
System Properties for
details.
log4j2.asyncLoggerConfigExceptionHandler
(
AsyncLoggerConfig.ExceptionHandler)
LOG4J_ASYNC_LOGGER_CONFIG_EXCEPTION_HANDLERdefault handler See Mixed Async/
Synchronous Logger
System Properties for
details.
log4j2.asyncLoggerConfigRingBufferSize
(
AsyncLoggerConfig.RingBufferSize)
LOG4J_ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE256 * 1024 See Mixed Async/
Synchronous Logger
System Properties for
details.
log4j2.asyncLoggerConfigWaitStrategy
(
AsyncLoggerConfig.WaitStrategy)
LOG4J_ASYNC_LOGGER_CONFIG_WAIT_STRATEGYTimeout See Mixed Async/
Synchronous Logger
System Properties for
details.
log4j2.julLoggerAdapter
( log4j.jul.LoggerAdapter) LOG4J_JUL_LOGGER_ADAPTERorg.apache.logging.log4j .jul.ApiLoggerAdapterDefault LoggerAdapter to
use in the JUL adapter.
By default, if log4j-core is
available, then the class
org.apache.logging.log4j.jul .CoreLoggerAdapter
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_ASYNCfalse 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
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.asyncQueueFullPolicy
(
log4j2.AsyncQueueFullPolicy)
LOG4J_ASYNC_QUEUE_FULL_POLICY 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_THRESHOLDINFO 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_FACTORYorg.apache.logging.log4j.message.
ParameterizedMessageFactory
or
org.apache.logging.log4j.message.
ReusableMessageFactory
in garbage-free mode
Default message factory
used by Loggers if no
factory was specified.
log4j2.flowMessageFactory
(
log4j2.flowMessageFactory)
LOG4J_FLOW_MESSAGE_FACTORYorg.apache.logging.log4j.message.
DefaultFlowMessageFactoryDefault flow message
factory used by Loggers.
log4j2.isWebapp
( log4j2.is.webapp) LOG4J_IS_WEBAPP true if Servlet class on
class path 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
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.enableThreadlocals
(
log4j2.enable.threadlocals)
LOG4J_ENABLE_THREADLOCALStrue 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.enableDirectEncoders
(
log4j2.enable.direct.encoders)
LOG4J_ENABLE_DIRECT_ENCODERStrue This property can be
used to force garbage-
aware 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.initialReusableMsgSize)
LOG4J_INITIAL_REUSABLE_MSG_SIZE128 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.maxReusableMsgSize
(
log4j.maxReusableMsgSize)
LOG4J_MAX_REUSABLE_MSG_SIZE518 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.layoutStringBuilder.maxSize)
LOG4J_LAYOUT_STRING_BUILDER_MAX_SIZE2048 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.
5 Configuration 58
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
log4j2.unboxRingbufferSize
(
log4j.unbox.ringbuffer.size)
LOG4J_UNBOX_RINGBUFFER_SIZE32 The
org.apache.logging.log4j.util.Unbox
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.LoggerContext.stacktrace.on.start)
LOG4J_LOGGER_CONTEXT_STACKTRACE_ON_STARTfalse Prints a stacktrace to
the status logger at
DEBUG level when the
LoggerContext is started.
For debug purposes.
log4j2.formatMsgNoLookups
(
log4j2.formatMsgNoLookups)
FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPSfalse Disables message pattern
lookups globally when
set to true. This is
equivalent to defining all
message patterns using
%m{nolookups}.
Log4j 2 global configuration properties
6 Web Applications and JSPs 59
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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 <web-app> 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
6 Web Applications and JSPs 60
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
<context-param>
<param-name>isLog4jAutoInitializationDisabled</param-name>
<param-value>true</param-value>
</context-param>
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 <web-app> 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:
6 Web Applications and JSPs 61
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<listener>
<listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
</listener>
<filter>
<filter-name>log4jServletFilter</filter-name>
<filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log4jServletFilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>ERROR</dispatcher>
<dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
</filter-mapping>
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.
6.1.4 Context Parameters
By default, Log4j 2 uses the ServletContext's context name as the LoggerContext name
and uses the standard pattern for locating the Log4j configuration file. There are three context
parameters that you can use to control this behavior. The first, isLog4jContextSelectorNamed,
specifies whether the context should be selected using the JndiContextSelector. If
isLog4jContextSelectorNamed is not specified or is anything other than true, it is assumed to
be false.
If isLog4jContextSelectorNamed is true, log4jContextName must be specified or
display-name must be specified in web.xml; otherwise, the application will fail to start with an
exception. log4jConfiguration should also be specified in this case, and must be a valid URI for
the configuration file; however, this parameter is not required.
If isLog4jContextSelectorNamed is not true, log4jConfiguration may optionally be
specified and must be a valid URI or path to a configuration file or start with "classpath:" to denote
a configuration file that can be found on the classpath. Without this parameter, Log4j will use the
standard mechanisms for locating the configuration file.
When specifying these context parameters, you must specify them in the deployment descriptor (
web.xml) even in a Servlet 3.0 or never application. If you add them to the ServletContext within
a listener, Log4j will initialize before the context parameters are available and they will have no
effect. Here are some sample uses of these context parameters.
6.1.4.1 Set the Logging Context Name to "myApplication"
<context-param>
<param-name>log4jContextName</param-name>
<param-value>myApplication</param-value>
</context-param>
6 Web Applications and JSPs 62
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
6.1.4.2 Set the Configuration Path/File/URI to "/etc/myApp/myLogging.xml"
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///etc/myApp/myLogging.xml</param-value>
</context-param>
6.1.4.3 Use the JndiContextSelector
<context-param>
<param-name>isLog4jContextSelectorNamed</param-name>
<param-value>true</param-value>
</context-param>
<context-param>
<param-name>log4jContextName</param-name>
<param-value>appWithJndiSelector</param-value>
</context-param>
<context-param>
<param-name>log4jConfiguration</param-name>
<param-value>file:///D:/conf/myLogging.xml</param-value>
</context-param>
Note that in this case you must also set the "Log4jContextSelector" system property to
"org.apache.logging.log4j.core.selector.JndiContextSelector".
6.1.5 Using Web Application Information During the Configuration
You may want to use information about the web application during configuration. For example,
you could embed the web application's context path in the name of a Rolling File Appender. See
WebLookup in Lookups for more information.
6.1.6 JavaServer Pages Logging
You may use Log4j 2 within JSPs just as you would within any other Java code. Simple obtain
a Logger and call its methods to log events. However, this requires you to use Java code within
your JSPs, and some development teams rightly are not comfortable with doing this. If you have a
dedicated user interface development team that is not familiar with using Java, you may even have
Java code disabled in your JSPs.
For this reason, Log4j 2 provides a JSP Tag Library that enables you to log events without using any
Java code. To read more about using this tag library, read the Log4j Tag Library documentation.
Important Note! As noted above, containers often ignore certain JARs known not to contain TLDs
and do not scan them for TLD files. Importantly, Tomcat 7 <7.0.43 ignores all JAR files named
log4j*.jar, which prevents the JSP tag library from being automatically discovered. This does not
affect Tomcat 6.x and 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
property. You may need to do something similar on other containers if they skip scanning Log4j JAR
files.
6.1.7 Asynchronous Requests and Threads
6 Web Applications and JSPs 63
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
The handling of asynchronous requests is tricky, and regardless of Servlet container version or
configuration Log4j cannot handle everything automatically. When standard requests, forwards,
includes, and error resources are processed, the Log4jServletFilter binds the LoggerContext
to the thread handling the request. After request processing completes, the filter unbinds the
LoggerContext from the thread.
Similarly, when an internal request is dispatched using a javax.servlet.AsyncContext, the
Log4jServletFilter also binds the LoggerContext to the thread handling the request and
unbinds it when request processing completes. However, this only happens for requests dispatched
through the AsyncContext. There are other asynchronous activities that can take place other than
internal dispatched requests.
For example, after starting an AsyncContext you could start up a separate thread to process the
request in the background, possibly writing the response with the ServletOutputStream. Filters
cannot intercept the execution of this thread. Filters also cannot intercept threads that you start in the
background during non-asynchronous requests. This is true whether you use a brand new thread or a
thread borrowed from a thread pool. So what can you do for these special threads?
You may not need to do anything. If you didn't use the isLog4jContextSelectorNamed
context parameter, there is no need to bind the LoggerContext to the thread. Log4j can safely
locate the LoggerContext on its own. In these cases, the filter provides only very modest
performance gains, and only when creating new Loggers. However, if you did specify the
isLog4jContextSelectorNamed context parameter with the value "true", you will need to
manually bind the LoggerContext to asynchronous threads. Otherwise, Log4j will not be able to
locate it.
Thankfully, Log4j provides a simple mechanism for binding the LoggerContext to asynchronous
threads in these special circumstances. The simplest way to do this is to wrap the Runnable instance
that is passed to the AsyncContext.start() method.
6 Web Applications and JSPs 64
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.WebLoggerContextUtils;
public class TestAsyncServlet extends HttpServlet {
@Override
protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
final AsyncContext asyncContext = req.startAsync();
asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), new Runnable() {
@Override
public void run() {
final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
logger.info("Hello, servlet!");
}
}));
}
@Override
protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
final AsyncContext asyncContext = req.startAsync();
asyncContext.start(new Runnable() {
@Override
public void run() {
final Log4jWebSupport webSupport =
WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
webSupport.setLoggerContext();
// do stuff
webSupport.clearLoggerContext();
}
});
}
}
This can be slightly more convenient when using Java 1.8 and lambda functions as demonstrated
below.
6 Web Applications and JSPs 65
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.WebLoggerContextUtils;
public class TestAsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final AsyncContext asyncContext = req.startAsync();
asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), () -> {
final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
logger.info("Hello, servlet!");
}));
}
}
Alternatively, you can obtain the Log4jWebLifeCycle instance from the ServletContext
attributes, call its setLoggerContext method as the very first line of code in your asynchronous
thread, and call its clearLoggerContext method as the very last line of code in your asynchronous
thread. The following code demonstrates this. It uses the container thread pool to execute
asynchronous request processing, passing an anonymous inner Runnable to the start method.
6 Web Applications and JSPs 66
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
import java.io.IOException;
import javax.servlet.AsyncContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.web.Log4jWebLifeCycle;
import org.apache.logging.log4j.web.WebLoggerContextUtils;
public class TestAsyncServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
final AsyncContext asyncContext = req.startAsync();
asyncContext.start(new Runnable() {
@Override
public void run() {
final Log4jWebLifeCycle webLifeCycle =
WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
webLifeCycle.setLoggerContext();
try {
final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
logger.info("Hello, servlet!");
} finally {
webLifeCycle.clearLoggerContext();
}
}
});
}
}
Note that you must call clearLoggerContext once your thread is finished processing. Failing
to do so will result in memory leaks. If using a thread pool, it can even disrupt the logging of other
web applications in your container. For that reason, the example here shows clearing the context in a
finally block, which will always execute.
6.1.8 Using the Servlet Appender
Log4j provides a Servlet Appender that uses the servlet context as the log target. For example:
6 Web Applications and JSPs 67
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<Configuration status="WARN" name="ServletTest">
<Appenders>
<Servlet name="Servlet">
<PatternLayout pattern="%m%n%ex{none}"/>
</Servlet>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Servlet"/>
</Root>
</Loggers>
</Configuration>
To avoid double logging of exceptions to the servlet context, you must use %ex{none} in your
PatternLayout as shown in the example. The exception will be omitted from the message text but
it is passed to the servlet context as the actual Throwable object.
7 Plugins 68
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
7 Plugins
.......................................................................................................................................
7.1 Plugins
7.1.1 Introduction
Log4j 1.x allowed for extension by requiring class attributes on most of the configuration
declarations. In the case of some elements, notably the PatternLayout, the only way to add new
pattern converters was to extend the PatternLayout class and add them via code. One goal of Log4j 2
is to make extending it extremely easy through the use of plugins.
In Log4j 2 a plugin is declared by adding a @Plugin annotation to the class declaration. During
initialization the Configuration will invoke the PluginManager to load the built-in Log4j plugins as
well as any custom plugins. The PluginManager locates plugins by looking in five places:
1. Serialized plugin listing files on the classpath. These files are generated automatically during the
build (more details below).
2. (OSGi only) Serialized plugin listing files in each active OSGi bundle. A BundleListener is
added on activation to continue checking new bundles after log4j-core has started.
3. A comma-separated list of packages specified by the log4j.plugin.packages system
property.
4. Packages passed to the static PluginManager.addPackages method (before Log4j
configuration occurs).
5. The packages declared in your log4j2 configuration file.
If multiple Plugins specify the same (case-insensitive) name, then the load order above determines
which one will be used. For example, to override the File plugin which is provided by the built-
in FileAppender class, you would need to place your plugin in a JAR file in the CLASSPATH
ahead of log4j-core.jar. This is not recommended; plugin name collisions will cause a warning
to be emitted. Note that in an OSGi environment, the order that bundles are scanned for plugins
generally follows the same order that bundles were installed into the framework. See getBundles()
and SynchronousBundleListener. In short, name collisions are even more unpredictable in an OSGi
environment.
Serialized plugin listing files are generated by an annotation processor contained in the log4j-
core artifact which will automatically scan your code for Log4j 2 plugins and output a metadata
file in your processed classes. There is nothing extra that needs to be done to enable this; the
Java compiler will automatically pick up the annotation processor on the class path unless you
explicitly disable it. In that case, it would be important to add another compiler pass to your build
process that only handles annotation processing using the Log4j 2 annotation processor class,
org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor. To
do this using Apache Maven, add the following execution to your maven-compiler-plugin (version 2.2
or higher) build plugin:
7 Plugins 69
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<executions>
<execution>
<id>log4j-plugin-processor</id>
<goals>
<goal>compile</goal>
</goals>
<phase>process-classes</phase>
<configuration>
<proc>only</proc>
<annotationProcessors>
<annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
</annotationProcessors>
</configuration>
</execution>
</executions>
</plugin>
As the configuration is processed the appropriate plugins will be automatically configured and
initialized. Log4j 2 utilizes a few different categories of plugins which are described in the following
sections.
7.1.2 Core
Core plugins are those that are directly represented by an element in a configuration file, such as an
Appender, Layout, Logger or Filter. Custom plugins that conform to the rules laid out in the next
paragraph may simply be referenced in the configuration, provided they are appropriate configured to
be loaded by the PluginManager.
Every Core plugin must declare a static method annotated with @PluginFactory or
@PluginBuilderFactory. The former is used for static factory methods that provide all options
as method parameters, and the latter is used to construct a new Builder<T> class whose fields
are used for injecting attributes and child nodes. To allow the Configuration to pass the correct
parameters to the method, every parameter to the method must be annotated as one of the following
attribute types. Each attribute or element annotation must include the name that must be present in the
configuration in order to match the configuration item to its respective parameter. For plugin builders,
the names of the fields will be used by default if no name is specified in the annotation. There are
dozens of plugins in Log4j Core that can be used as examples for more complex scenarios including
hierarchical builder classes (e.g., see FileAppender). See Extending Log4j with Plugin Builders for
more details.
7.1.2.1 Attribute Types
PluginAttribute
The parameter must be convertible from a String using a TypeConverter. Most built-in
types are already supported, but custom TypeConverter plugins may also be provided
for more type support. Note that PluginBuilderAttribute can be used in builder class
fields as an easier way to provide default values.
7 Plugins 70
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
PluginElement
The parameter may represent a complex object that itself has parameters that can be
configured. This also supports injecting an array of elements.
PluginConfiguration
The current Configuration object will be passed to the plugin as a parameter.
PluginNode
The current Node being parsed will be passed to the plugin as a parameter.
PluginValue
The value of the current Node or its attribute named value.
7.1.2.2 Constraint Validators
Plugin factory fields and parameters can be automatically validated at runtime using constraint
validators inspired by the Bean Validation spec. The following annotations are bundled in Log4j, but
custom ConstraintValidators can be created as well.
Required
This annotation validates that a value is non-empty. This covers a check for null as well as
several other scenarios: empty CharSequence objects, empty arrays, empty Collection
instances, and empty Map instances.
ValidHost
This annotation validates that a value corresponds to a valid hostname. This uses the same
validation as InetAddress::getByName.
ValidPort
This annotation validates that a value corresponds to a valid port number between 0 and
65535.
7.1.3 Converters
Converters are used by PatternLayout to render the elements identified by the conversion pattern.
Every converter must specify its category as "Converter" on the @Plugin annotation, have a static
newInstance method that accepts an array of Strings as its only parameter and returns an instance
of the Converter, and must have a @ConverterKeys annotation present that contains the array of
converter patterns that will cause the Converter to be selected. Converters that are meant to handle
LogEvents must extend the LogEventPatternConverter class and must implement a format method
that accepts a LogEvent and a StringBuilder as arguments. The Converter should append the
result of its operation to the StringBuilder.
A second type of Converter is the FileConverter - which must have "FileConverter" specified in the
category attribute of the @Plugin annotation. While similar to a LogEventPatternConverter,
instead of a single format method these Converters will have two variations; one that takes an Object
and one that takes an array of Objects instead of the LogEvent. Both append to the provided
StringBuilder in the same fashion as a LogEventPatternConverter. These Converters are
typically used by the RollingFileAppender to construct the name of the file to log to.
If multiple Converters specify the same ConverterKeys, then the load order above determines
which one will be used. For example, to override the %date converter which is provided by the
built-in DatePatternConverter class, you would need to place your plugin in a JAR file in
7 Plugins 71
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
the CLASSPATH ahead of log4j-core.jar. This is not recommended; pattern ConverterKeys
collisions will cause a warning to be emitted. Try to use unique ConverterKeys for your custom
pattern converters.
7.1.4 KeyProviders
Some components within Log4j may provide the ability to perform data encryption. These
components require a secret key to perform the encryption. Applications may provide the key by
creating a class that implements the SecretKeyProvider interface.
7.1.5 Lookups
Lookups are perhaps the simplest plugins of all. They must declare their type as "Lookup" on the
plugin annotation and must implement the StrLookup interface. They will have two methods; a
lookup method that accepts a String key and returns a String value and a second lookup method
that accepts both a LogEvent and a String key and returns a String. Lookups may be referenced by
specifying ${name:key} where name is the name specified in the Plugin annotation and key is the
name of the item to locate.
7.1.6 TypeConverters
TypeConverters are a sort of meta-plugin used for converting strings into other types in a plugin
factory method parameter. Other plugins can already be injected via the @PluginElement
annotation; now, any type supported by the type conversion system can be used in a
@PluginAttribute parameter. Conversion of enum types are supported on demand and do
not require custom TypeConverter classes. A large number of built-in Java classes are already
supported; see TypeConverters for a more exhaustive listing.
Unlike other plugins, the plugin name of a TypeConverter is purely cosmetic. Appropriate type
converters are looked up via the Type interface rather than via Class<?> objects only. Do note that
TypeConverter plugins must have a default constructor.
7.2 Developer Notes
If a plugin class implements Collection or Map, then no factory method is used. Instead, the class
is instantiated using the default constructor, and all child configuration nodes are added to the
Collection or Map.
8 Lookups 72
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
8 Lookups
.......................................................................................................................................
8.1 Lookups
Lookups provide a way to add values to the Log4j configuration at arbitrary places. They are a
particular type of Plugin that implements the StrLookup interface. Information on how to use
Lookups in configuration files can be found in the Property Substitution section of the Configuration
page.
8.1.1 Context Map Lookup
The ContextMapLookup allows applications to store data in the Log4j ThreadContext Map and then
retrieve the values in the Log4j configuration. In the example below, the application would store the
current user's login id in the ThreadContext Map with the key "loginId". During initial configuration
processing the first '$' will be removed. The PatternLayout supports interpolation with Lookups and
will then resolve the variable for each event. Note that the pattern "%X{loginId}" would achieve the
same result.
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${ctx:loginId} %m%n</pattern>
</PatternLayout>
</File>
8.1.2 Date Lookup
The DateLookup is somewhat unusual from the other lookups as it doesn't use the key to locate an
item. Instead, the key can be used to specify a date format string that is valid for SimpleDateFormat.
The current date, or the date associated with the current log event will be formatted as specified.
<RollingFile name="Rolling-${map:type}" fileName="${filename}" filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
8.1.3 Environment Lookup
The EnvironmentLookup allows systems to configure environment variables, either in global files
such as /etc/profile or in the startup scripts for applications, and then retrieve those variables from
within the logging configuration. The example below includes the name of the currently logged in
user in the application log.
8 Lookups 73
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${env:USER} %m%n</pattern>
</PatternLayout>
</File>
This lookup also supports default value syntax. In the sample below, when the USER environment
variable is undefined, the default value jdoe is used:
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${env:USER:-jdoe} %m%n</pattern>
</PatternLayout>
</File>
8.1.4 Java Lookup
The JavaLookup allows Java environment information to be retrieved in convenient preformatted
strings using the java: prefix.
Key Description
version The short Java version, like:
Java version 1.7.0_67
runtime The Java runtime version, like:
Java(TM) SE Runtime Environment
(build 1.7.0_67-b01) from Oracle
Corporation
vm The Java VM version, like:
Java HotSpot(TM) 64-Bit Server VM
(build 24.65-b04, mixed mode)
os The OS version, like:
Windows 7 6.1 Service Pack 1,
architecture: amd64-64
locale Hardware information, like:
default locale: en_US, platform
encoding: Cp1252
hw Hardware information, like:
processors: 4, architecture:
amd64-64, instruction sets: amd64
For example:
8 Lookups 74
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<File name="Application" fileName="application.log">
<PatternLayout header="${java:runtime} - ${java:vm} - ${java:os}">
<Pattern>%d %m%n</Pattern>
</PatternLayout>
</File>
8.1.5 Jndi Lookup
The JndiLookup allows variables to be retrieved via JNDI. By default the key will be prefixed with
java:comp/env/, however if the key contains a ":" no prefix will be added.
<File name="Application" fileName="application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n</pattern>
</PatternLayout>
</File>
Java's JNDI module is not available on Android.
8.1.6 JVM Input Arguments Lookup (JMX)
Maps JVM input arguments -- but not main arguments -- using JMX to acquire the JVM arguments.
Use the prefix jvmrunargs to access JVM arguments.
See the Javadocs for java.lang.management.RuntimeMXBean.getInputArguments() .
Java's JMX module is not available on Android or on Google App Engine.
8.1.7 Log4j Configuration Location Lookup
Log4j configuration properties. The expressions ${log4j:configLocation} and
${log4j:configParentLocation} respectively provide the absolute path to the log4j
configuration file and its parent folder.
The example below uses this lookup to place log files in a directory relative to the log4j configuration
file.
<File name="Application" fileName="${log4j:configParentLocation}/logs/application.log">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
</File>
8.1.8 Main Arguments Lookup (Application)
This lookup requires that you manually provide the main arguments of the application to Log4j:
8 Lookups 75
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
import org.apache.logging.log4j.core.lookup.MainMapLookup;
public static void main(String args[]) {
MainMapLookup.setMainArguments(args);
...
}
If the main arguments have been set, this lookup allows applications to retrieve these main argument
values from within the logging configuration. The key that follows the main: prefix can either be a
0-based index into the argument list, or a string, where ${main:myString} is substituted with the
value that follows myString in the main argument list.
For example, suppose the static void main String[] arguments are:
--file foo.txt --verbose -x bar
Then the following substitutions are possible:
Expression Result
${main:0} --file
${main:1} foo.txt
${main:2} --verbose
${main:3} -x
${main:4} bar
${main:--file} foo.txt
${main:-x} bar
${main:bar} null
Example usage:
<File name="Application" fileName="application.log">
<PatternLayout header="File: ${main:--file}">
<Pattern>%d %m%n</Pattern>
</PatternLayout>
</File>
8.1.9 Map Lookup
The MapLookup serves several purposes.
1. Provide the base for Properties declared in the configuration file.
2. Retrieve values from MapMessages in LogEvents.
3. Retrieve values set with MapLookup.setMainArguments(String[])
The first item simply means that the MapLookup is used to substitute properties that are defined in the
configuration file. These variables are specified without a prefix - e.g. ${name}. The second usage
allows a value from the current MapMessage, if one is part of the current log event, to be substituted.
In the example below the RoutingAppender will use a different RollingFileAppender for each unique
value of the key named "type" in the MapMessage. Note that when used this way a value for "type"
should be declared in the properties declaration to provide a default value in case the message is not a
8 Lookups 76
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
MapMessage or the MapMessage does not contain the key. See the Property Substitution section of
the Configuration page for information on how to set the default values.
<Routing name="Routing">
<Routes pattern="$${map:type}">
<Route>
<RollingFile name="Rolling-${map:type}" fileName="${filename}"
filePattern="target/rolling1/test1-${map:type}.%i.log.gz">
<PatternLayout>
<pattern>%d %p %c{1.} [%t] %m%n</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
</Route>
</Routes>
</Routing>
8.1.10 Marker Lookup
The marker lookup allows you to use markers in interesting configurations like a routing appender.
Consider the following YAML configuration and code that logs to different files based on markers:
8 Lookups 77
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
Configuration:
status: debug
Appenders:
Console:
RandomAccessFile:
- name: SQL_APPENDER
fileName: logs/sql.log
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
- name: PAYLOAD_APPENDER
fileName: logs/payload.log
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
- name: PERFORMANCE_APPENDER
fileName: logs/performance.log
PatternLayout:
Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
Routing:
name: ROUTING_APPENDER
Routes:
pattern: "$${marker:}"
Route:
- key: PERFORMANCE
ref: PERFORMANCE_APPENDER
- key: PAYLOAD
ref: PAYLOAD_APPENDER
- key: SQL
ref: SQL_APPENDER
Loggers:
Root:
level: trace
AppenderRef:
- ref: ROUTING_APPENDER
public static final Marker SQL = MarkerFactory.getMarker("SQL");
public static final Marker PAYLOAD = MarkerFactory.getMarker("PAYLOAD");
public static final Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
logger.info(SQL, "Message in Sql.log");
logger.info(PAYLOAD, "Message in Payload.log");
logger.info(PERFORMANCE, "Message in Performance.log");
Note the key part of the configuration is pattern: "$${marker:}". This will produce three log
files, each with a log event for a specific marker. Log4j will route the log event with the SQL marker
to sql.log, the log event with the PAYLOAD marker to payload.log, and so on.
You can use the notation "${marker:name}" and "$${marker:name}" to check for the existence
of a marker where name is the marker name. If the marker exists, the expression returns the name,
otherwise null.
8 Lookups 78
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
8.1.11 Structured Data Lookup
The StructuredDataLookup is very similar to the MapLookup in that it will retrieve values from
StructuredDataMessages. In addition to the Map values it will also return the name portion of
the id (not including the enterprise number) and the type field. The main difference between
the example below and the example for MapMessage is that the "type" is an attribute of the
StructuredDataMessage while "type" would have to be an item in the Map in a MapMessage.
<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</pattern>
</PatternLayout>
<SizeBasedTriggeringPolicy size="500" />
</RollingFile>
</Route>
</Routes>
</Routing>
8.1.12 System Properties Lookup
As it is quite common to define values inside and outside the application by using System Properties,
it is only natural that they should be accessible via a Lookup. As system properties are often defined
outside the application it would be quite common to see something like:
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath}/app.log"/>
</Appenders>
This lookup also supports default value syntax. In the sample below, when the logPath system
property is undefined, the default value /var/logs is used:
<Appenders>
<File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
</Appenders>
8.1.13 Web Lookup
The WebLookup allows applications to retrieve variables that are associated with the ServletContext.
In addition to being able to retrieve various fields in the ServletContext, WebLookup supports looking
up values stored as attributes or configured as initialization parameters. The following table lists
various keys that can be retrieved:
Key Description
8 Lookups 79
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
attr. name Returns the ServletContext attribute with the specified
name
contextPath The context path of the web application
effectiveMajorVersion Gets the major version of the Servlet specification that
the application represented by this ServletContext is
based on.
effectiveMinorVersion Gets the minor version of the Servlet specification that
the application represented by this ServletContext is
based on.
initParam. name Returns the ServletContext initialization parameter
with the specified name
majorVersion Returns the major version of the Servlet API that this
servlet container supports.
minorVersion Returns the minor version of the Servlet API that this
servlet container supports.
rootDir Returns the result of calling getRealPath with a value
of "/".
serverInfo Returns the name and version of the servlet container
on which the servlet is running.
servletContextName Returns the name of the web application as defined
in the display-name element of the deployment
descriptor
Any other key names specified will first be checked to see if a ServletContext attribute exists with that
name and then will be checked to see if an initialization parameter of that name exists. If the key is
located then the corresponding value will be returned.
<Appenders>
<File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
</Appenders>
9 Appenders 80
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
9 Appenders
.......................................................................................................................................
9.1 Appenders
Appenders are responsible for delivering LogEvents to their destination. Every Appender must
implement the Appender interface. Most Appenders will extend AbstractAppender which
adds Lifecycle and Filterable support. Lifecycle allows components to finish initialization after
configuration has completed and to perform cleanup during shutdown. Filterable allows the
component to have Filters attached to it which are evaluated during event processing.
Appenders usually are only responsible for writing the event data to the target destination. In most
cases they delegate responsibility for formatting the event to a layout. Some appenders wrap other
appenders so that they can modify the LogEvent, handle a failure in an Appender, route the event to a
subordinate Appender based on advanced Filter criteria or provide similar functionality that does not
directly format the event for viewing.
Appenders always have a name so that they can be referenced from Loggers.
In the tables below, the "Type" column corresponds to the Java type expected. For non-JDK classes,
these should usually be in Log4j Core unless otherwise noted.
9.1.1 AsyncAppender
The AsyncAppender accepts references to other Appenders and causes LogEvents to be written to
them on a separate Thread. Note that exceptions while writing to those Appenders will be hidden from
the application. The AsyncAppender should be configured after the appenders it references to allow it
to shut down properly.
By default, AsyncAppender uses java.util.concurrent.ArrayBlockingQueue which does not require
any external libraries. Note that multi-threaded applications should exercise care when using
this appender as such: the blocking queue is susceptible to lock contention and our tests showed
performance may become worse when more threads are logging concurrently. Consider using lock-
free Async Loggers for optimal performance.
Parameter Name Type Description
AppenderRef String The name of the Appenders to
invoke asynchronously. Multiple
AppenderRef elements can be
configured.
blocking boolean If true, the appender will wait until
there are free slots in the queue. If
false, the event will be written to the
error appender if the queue is full.
The default is true.
shutdownTimeout integer How many milliseconds the
Appender should wait to flush
outstanding log events in the queue
on shutdown. The default is zero
which means to wait forever.
9 Appenders 81
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
bufferSize integer Specifies the maximum number
of events that can be queued.
The default is 1024. Note that
when using a disruptor-style
BlockingQueue, this buffer size
must be a power of 2.
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.
errorRef String The name of the Appender to
invoke if none of the appenders can
be called, either due to errors in the
appenders or because the queue is
full. If not specified then errors will
be ignored.
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.
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.
includeLocation boolean Extracting location is an expensive
operation (it can make logging 5
- 20 times slower). To improve
performance, location is not
included by default when adding
a log event to the queue. You
can change this by setting
includeLocation="true".
BlockingQueueFactory BlockingQueueFactory This element overrides what type
of BlockingQueue to use. See
below documentation for more
details.
AsyncAppender Parameters
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.
A typical AsyncAppender configuration might look like:
9 Appenders 82
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
<Async name="Async">
<AppenderRef ref="MyFile"/>
</Async>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Async"/>
</Root>
</Loggers>
</Configuration>
Starting in Log4j 2.7, a custom implementation of BlockingQueue or TransferQueue can be
specified using a BlockingQueueFactory plugin. To override the default BlockingQueueFactory,
specify the plugin inside an <Async/> element like so:
<Configuration name="LinkedTransferQueueExample">
<Appenders>
<List name="List"/>
<Async name="Async" bufferSize="262144">
<AppenderRef ref="List"/>
<LinkedTransferQueue/>
</Async>
</Appenders>
<Loggers>
<Root>
<AppenderRef ref="Async"/>
</Root>
</Loggers>
</Configuration>
Log4j ships with the following implementations:
Plugin Name Description
ArrayBlockingQueue This is the default implementation that uses
ArrayBlockingQueue.
DisruptorBlockingQueue This uses the Conversant Disruptor implementation of
BlockingQueue. This plugin takes a single optional
attribute, spinPolicy, which corresponds to
JCToolsBlockingQueue This uses JCTools, specifically the MPSC bounded
lock-free queue.
9 Appenders 83
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
LinkedTransferQueue This uses the new in Java 7 implementation
LinkedTransferQueue. Note that this queue does not
use the bufferSize configuration attribute from
AsyncAppender as LinkedTransferQueue does
not support a maximum capacity.
BlockingQueueFactory Implementations
9.1.2 CassandraAppender
The CassandraAppender writes its output to an Apache Cassandra database.
A keyspace and table must be configured ahead of time, and the columns of
that table are mapped in a configuration file. Each column can specify either a
StringLayout (e.g., a PatternLayout) along with an optional conversion type, or only
a conversion type for org.apache.logging.log4j.spi.ThreadContextMap or
org.apache.logging.log4j.spi.ThreadContextStack to store the MDC or NDC in a map
or list column respectively. A conversion type compatible with java.util.Date will use the log
event timestamp converted to that type (e.g., use java.util.Date to fill a timestamp column type
in Cassandra).
Parameter Name Type Description
batched boolean Whether or not to use batch
statements to write log messages
to Cassandra. By default, this is
false.
batchType BatchStatement.Type The batch type to use when using
batched writes. By default, this is
LOGGED.
bufferSize int The number of log messages to
buffer or batch before writing. By
default, no buffering is done.
clusterName String The name of the Cassandra cluster
to connect to.
9 Appenders 84
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
columns ColumnMapping[] A list of column mapping
configurations. Each column must
specify a column name. Each
column can have a conversion type
specified by its fully qualified class
name. By default, the conversion
type is String. If the configured
type is assignment-compatible
with ReadOnlyStringMap
/ ThreadContextMap or
ThreadContextStack, then that
column will be populated with
the MDC or NDC respectively.
If the configured type is
assignment-compatible with
java.util.Date, then the
log timestamp will be converted
to that configured date type. If
a literal attribute is given,
then its value will be used as is in
the INSERT query without any
escaping. Otherwise, the layout or
pattern specified will be converted
into the configured type and stored
in that column.
contactPoints SocketAddress[] A list of hosts and ports of
Cassandra nodes to connect to.
These must be valid hostnames or
IP addresses. By default, if a port is
not specified for a host or it is set to
0, then the default Cassandra port
of 9042 will be used. By default,
localhost:9042 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.
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.
keyspace String The name of the keyspace
containing the table that log
messages will be written to.
name String The name of the Appender.
password String The password to use (along with
the username) to connect to
Cassandra.
9 Appenders 85
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
table String The name of the table to write log
messages to.
useClockForTimestampGenerator boolean Whether or not to
use the configured
org.apache.logging.log4j.core.util.Clock
as a TimestampGenerator. By
default, this is false.
username String The username to use to connect
to Cassandra. By default, no
username or password is used.
useTls boolean Whether or not to use TLS/SSL
to connect to Cassandra. This is
false by default.
CassandraAppender Parameters
Here is an example CassandraAppender configuration:
<Configuration name="CassandraAppenderTest">
<Appenders>
<Cassandra name="Cassandra" clusterName="Test Cluster" keyspace="test" table="logs" bufferSize="10" batched="true">
<SocketAddress host="localhost" port="9042"/>
<ColumnMapping name="id" pattern="%uuid{TIME}" type="java.util.UUID"/>
<ColumnMapping name="timeid" literal="now()"/>
<ColumnMapping name="message" pattern="%message"/>
<ColumnMapping name="level" pattern="%level"/>
<ColumnMapping name="marker" pattern="%marker"/>
<ColumnMapping name="logger" pattern="%logger"/>
<ColumnMapping name="timestamp" type="java.util.Date"/>
<ColumnMapping name="mdc" type="org.apache.logging.log4j.spi.ThreadContextMap"/>
<ColumnMapping name="ndc" type="org.apache.logging.log4j.spi.ThreadContextStack"/>
</Cassandra>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.cassandra" level="DEBUG">
<AppenderRef ref="Cassandra"/>
</Logger>
<Root level="ERROR"/>
</Loggers>
</Configuration>
This example configuration uses the following table schema:
9 Appenders 86
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
CREATE TABLE logs (
id timeuuid PRIMARY KEY,
timeid timeuuid,
message text,
level text,
marker text,
logger text,
timestamp timestamp,
mdc map<text,text>,
ndc list<text>
);
9.1.3 ConsoleAppender
As one might expect, the ConsoleAppender writes its output to either System.out or System.err with
System.out being the default target. A Layout must be provided to format the LogEvent.
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.
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.
follow boolean Identifies whether the appender
honors reassignments of
System.out or System.err via
System.setOut or System.setErr
made after configuration. Note that
the follow attribute cannot be used
with Jansi on Windows. Cannot be
used with direct.
9 Appenders 87
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
direct boolean Write directly to
java.io.FileDescriptor
and bypass
java.lang.System.out/.err.
Can give up to 10x performance
boost when the output is
redirected to file or other process.
Cannot be used with Jansi on
Windows. Cannot be used with
follow. Output will not respect
java.lang.System.setOut()/.setErr()
and may get intertwined
with other output to
java.lang.System.out/.err
in a multi-threaded application.
New since 2.6.2. Be aware that this
is a new addition, and it has only
been tested with Oracle JVM on
Linux and Windows so far.
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.
target String Either "SYSTEM_OUT" or
"SYSTEM_ERR". The default is
"SYSTEM_OUT".
ConsoleAppender Parameters
A typical Console configuration might look like:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
9.1.4 FailoverAppender
The FailoverAppender wraps a set of appenders. If the primary Appender fails the secondary
appenders will be tried in order until one succeeds or there are no more secondaries to try.
9 Appenders 88
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
primary String The name of the primary Appender
to use.
failovers String[] The names of the secondary
Appenders to use.
name String The name of the Appender.
retryIntervalSeconds integer The number of seconds that should
pass before retrying the primary
Appender. The default is 60.
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.
target String Either "SYSTEM_OUT" or
"SYSTEM_ERR". The default is
"SYSTEM_ERR".
FailoverAppender Parameters
A Failover configuration might look like:
9 Appenders 89
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
<Console name="STDOUT" target="SYSTEM_OUT" ignoreExceptions="false">
<PatternLayout pattern="%m%n"/>
</Console>
<Failover name="Failover" primary="RollingFile">
<Failovers>
<AppenderRef ref="Console"/>
</Failovers>
</Failover>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Failover"/>
</Root>
</Loggers>
</Configuration>
9.1.5 FileAppender
The FileAppender is an OutputStreamAppender that writes to the File named in the fileName
parameter. The FileAppender uses a FileManager (which extends OutputStreamManager) to
actually perform the file I/O. While FileAppenders from different Configurations cannot be shared,
the FileManagers 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.
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.
9 Appenders 90
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
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.
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.
locking boolean When set to true, I/O operations
will occur only while the file lock
is held allowing FileAppenders
in multiple JVMs and potentially
multiple hosts to write to the
same file simultaneously. This will
significantly impact performance
so should be used carefully.
Furthermore, on many systems
the file lock is "advisory" meaning
that other applications can perform
operations on the file without
acquiring a lock. The default value
is false.
name String The name of the Appender.
9 Appenders 91
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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-rw-
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.
fileGroup String File group to define whenever
the file is created.
Underlying files system shall
support POSIX file attribute
view.
FileAppender Parameters
Here is a sample File configuration:
9 Appenders 92
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<File name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
9.1.6 FlumeAppender
This is an optional component supplied in a separate jar.
Apache Flume is a distributed, reliable, and available system for efficiently collecting, aggregating,
and moving large amounts of log data from many different sources to a centralized data store. The
FlumeAppender takes LogEvents and sends them to a Flume agent as serialized Avro events for
consumption.
The Flume Appender supports three modes of operation.
1. It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent
configured with an Avro Source.
2. It can act as an embedded Flume Agent where Flume events pass directly into Flume for
processing.
3. It can persist events to a local BerkeleyDB data store and then asynchronously send the events to
Flume, similar to the embedded Flume Agent but without most of the Flume dependencies.
Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and
then control will be immediately returned to the application. All interaction with remote agents will
occur asynchronously. Setting the "type" attribute to "Embedded" will force the use of the embedded
agent. In addition, configuring agent properties in the appender configuration will also cause the
embedded agent to be used.
Parameter Name Type Description
agents Agent[] An array of Agents to which the
logging events should be sent. If
more than one agent is specified
the first Agent will be the primary
and subsequent Agents will be
used in the order specified as
secondaries should the primary
Agent fail. Each Agent definition
supplies the Agents host and port.
The specification of agents and
properties are mutually exclusive.
If both are configured an error will
result.
9 Appenders 93
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
agentRetries integer The number of times the agent
should be retried before failing to
a secondary. This parameter is
ignored when type="persistent" is
specified (agents are tried once
before failing to the next).
batchSize integer Specifies the number of events
that should be sent as a batch. The
default is 1. This parameter only
applies to the Flume Appender.
compress boolean When set to true the message body
will be compressed using gzip
connectTimeoutMillis integer The number of milliseconds Flume
will wait before timing out the
connection.
dataDir String Directory where the Flume write
ahead log should be written. Valid
only when embedded is set to
true and Agent elements are used
instead of Property elements.
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.
eventPrefix String The character string to prepend
to each event attribute in order to
distinguish it from MDC attributes.
The default is an empty string.
flumeEventFactory FlumeEventFactory Factory that generates the
Flume events from Log4j
events. The default factory is the
FlumeAvroAppender itself.
layout Layout The Layout to use to format the
LogEvent. If no layout is specified
RFC5424Layout will be used.
lockTimeoutRetries integer The number of times to retry if a
LockConflictException occurs while
writing to Berkeley DB. The default
is 5.
maxDelayMillis integer The maximum number of
milliseconds to wait for batchSize
events before publishing the batch.
mdcExcludes String A comma separated list of mdc
keys that should be excluded from
the FlumeEvent. This is mutually
exclusive with the mdcIncludes
attribute.
9 Appenders 94
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
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.
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:".
name String The name of the Appender.
properties Property[] One or more Property elements
that are used to configure the
Flume Agent. The properties
must be configured without
the agent name (the appender
name is used for this) and no
sources can be configured.
Interceptors can be specified for
the source using "sources.log4j-
source.interceptors". All other
Flume configuration properties
are allowed. Specifying both
Agent and Property elements
will result in an error.
When used to configure in
Persistent mode the valid
properties are:
1. "keyProvider" to specify the
name of the plugin to provide
the secret key for encryption.
requestTimeoutMillis integer The number of milliseconds Flume
will wait before timing out the
request.
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.
9 Appenders 95
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
type enumeration One of "Avro", "Embedded", or
"Persistent" to indicate which
variation of the Appender is
desired.
FlumeAppender Parameters
A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
compresses the body, and formats the body using the RFC5424Layout:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" compress="true">
<Agent host="192.168.10.101" port="8800"/>
<Agent host="192.168.10.102" port="8800"/>
<RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
</Flume>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="eventLogger"/>
</Root>
</Loggers>
</Configuration>
A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to
disk:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" compress="true" type="persistent" dataDir="./logData">
<Agent host="192.168.10.101" port="8800"/>
<Agent host="192.168.10.102" port="8800"/>
<RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
<Property name="keyProvider">MySecretProvider</Property>
</Flume>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="eventLogger"/>
</Root>
</Loggers>
</Configuration>
A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
compresses the body, formats the body using RFC5424Layout and passes the events to an embedded
Flume Agent.
9 Appenders 96
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" compress="true" type="Embedded">
<Agent host="192.168.10.101" port="8800"/>
<Agent host="192.168.10.102" port="8800"/>
<RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
</Flume>
<Console name="STDOUT">
<PatternLayout pattern="%d [%p] %c %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info">
<AppenderRef ref="eventLogger"/>
</Logger>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
A sample FlumeAppender configuration that is configured with a primary and a secondary agent
using Flume configuration properties, compresses the body, formats the body using RFC5424Layout
and passes the events to an embedded Flume Agent.
9 Appenders 97
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" name="MyApp" packages="">
<Appenders>
<Flume name="eventLogger" compress="true" type="Embedded">
<Property name="channels">file</Property>
<Property name="channels.file.type">file</Property>
<Property name="channels.file.checkpointDir">target/file-channel/checkpoint</Property>
<Property name="channels.file.dataDirs">target/file-channel/data</Property>
<Property name="sinks">agent1 agent2</Property>
<Property name="sinks.agent1.channel">file</Property>
<Property name="sinks.agent1.type">avro</Property>
<Property name="sinks.agent1.hostname">192.168.10.101</Property>
<Property name="sinks.agent1.port">8800</Property>
<Property name="sinks.agent1.batch-size">100</Property>
<Property name="sinks.agent2.channel">file</Property>
<Property name="sinks.agent2.type">avro</Property>
<Property name="sinks.agent2.hostname">192.168.10.102</Property>
<Property name="sinks.agent2.port">8800</Property>
<Property name="sinks.agent2.batch-size">100</Property>
<Property name="sinkgroups">group1</Property>
<Property name="sinkgroups.group1.sinks">agent1 agent2</Property>
<Property name="sinkgroups.group1.processor.type">failover</Property>
<Property name="sinkgroups.group1.processor.priority.agent1">10</Property>
<Property name="sinkgroups.group1.processor.priority.agent2">5</Property>
<RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
</Flume>
<Console name="STDOUT">
<PatternLayout pattern="%d [%p] %c %m%n"/>
</Console>
</Appenders>
<Loggers>
<Logger name="EventLogger" level="info">
<AppenderRef ref="eventLogger"/>
</Logger>
<Root level="warn">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
9.1.7 JDBCAppender
The JDBCAppender writes log events to a relational database table using standard JDBC. It
can be configured to obtain JDBC connections using a JNDI DataSource or a custom factory
method. Whichever approach you take, it must be backed by a connection pool. Otherwise, logging
performance will suffer greatly. If batch statements are supported by the configured JDBC driver
and a bufferSize is configured to be a positive number, then log events will be batched. Note
that as of Log4j 2.8, there are two ways to configure log event to column mappings: the original
ColumnConfig style that only allows strings and timestamps, and the new ColumnMapping plugin
that uses Log4j's built-in type conversion to allow for more data types (this is the same plugin as in
the Cassandra Appender).
9 Appenders 98
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
To get off the ground quickly during development, an alternative to using a connection source based
on JNDI is to use the non-pooling DriverManager connection source. This connection source uses a
JDBC connection string, a user name, and a password. Optionally, you can also use properties.
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.
connectionSource ConnectionSource Required. The connections source
from which database connections
should be retrieved.
tableName String Required. The name of the
database table to insert log events
into.
columnConfigs ColumnConfig[] Required (and/or
columnMappings). Information
about the columns that log event
data should be inserted into
and how to insert that data. This
is represented with multiple
<Column> elements.
9 Appenders 99
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
columnMappings ColumnMapping[] Required (and/or columnConfigs).
A list of column mapping
configurations. Each column must
specify a column name. Each
column can have a conversion type
specified by its fully qualified class
name. By default, the conversion
type is String. If the configured
type is assignment-compatible
with ReadOnlyStringMap
/ ThreadContextMap or
ThreadContextStack, then that
column will be populated with
the MDC or NDC respectively
(this is database-specific how
they handle inserting a Map or
List value). If the configured
type is assignment-compatible with
java.util.Date, then the
log timestamp will be converted
to that configured date type. If the
configured type is assignment-
compatible with java.sql.Clob
or java.sql.NClob, then the
formatted event will be set as a
Clob or NClob respectively (similar
to the traditional ColumnConfig
plugin). If a literal attribute is
given, then its value will be used as
is in the INSERT query without any
escaping. Otherwise, the layout or
pattern specified will be converted
into the configured type and stored
in that column.
JDBCAppender Parameters
When configuring the JDBCAppender, you must specify a ConnectionSource implementation
from which the Appender gets JDBC connections. You must use exactly one of the following nested
elements:
•<DataSource>: Uses JNDI.
•<ConnectionFactory>: Points to a class-method pair to provide JDBC connections.
•<DriverManager>: A quick and dirty way to get off the ground, no connection pooling.
•<PoolingDriver>: Uses Apache Commons DBCP to provide connection pooling.
Parameter Name Type Description
9 Appenders 100
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
jndiName String Required. The full, prefixed
JNDI name that the
javax.sql.DataSource
is bound to, such as java:/
comp/env/jdbc/
LoggingDatabase. The
DataSource must be backed
by a connection pool; otherwise,
logging will be very slow.
DataSource Parameters
Parameter Name Type Description
class Class Required. The fully qualified name
of a class containing a static
factory method for obtaining JDBC
connections.
method Method Required. The name of a static
factory method for obtaining
JDBC connections. This method
must have no parameters and
its return type must be either
java.sql.Connection or
DataSource. If the method
returns Connections, it must
obtain them from a connection
pool (and they will be returned to
the pool when Log4j is done with
them); otherwise, logging will be
very slow. If the method returns a
DataSource, the DataSource
will only be retrieved once, and it
must be backed by a connection
pool for the same reasons.
ConnectionFactory Parameters
Parameter Name Type Description
connectionString String Required. The driver-specific JDBC
connection string.
userName String The database user name. You
cannot specify both properties and
a user name or password.
password String The database password. You
cannot specify both properties and
a user name or password.
driverClassName String The JDBC driver class name.
Some old JDBC Driver can only
be discovered by explicitly loading
them by class name.
9 Appenders 101
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
properties Property[] A list of properties. You cannot
specify both properties and a user
name or password.
DriverManager Parameters
Parameter Name Type Description
DriverManager parameters DriverManager parameters This connection source inherits all
parameter from the DriverManager
connection source.
poolName String The pool name used to pool
JDBC Connections. Defaults
to example. You can use the
JDBC connection string prefix
jdbc:apache:commons:dbcp:
followed by the pool name if you
want to use a pooled connection
elsewhere. For example:
jdbc:apache:commons:dbcp:example.
PoolingDriver Parameters (Apache Commons DBCP)
When configuring the JDBCAppender, use the nested <Column> elements to specify which columns
in the table should be written to and how to write to them. The JDBCAppender uses this information
to formulate a PreparedStatement to insert records without SQL injection vulnerability.
Parameter Name Type Description
name String Required. The name of the
database column.
pattern String Use this attribute to insert a value
or values from the log event in this
column using a PatternLayout
pattern. Simply specify any legal
pattern in this attribute. Either
this attribute, literal, or
isEventTimestamp="true"
must be specified, but not more
than one of these.
9 Appenders 102
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
literal String Use this attribute to insert a
literal value in this column. The
value will be included directly
in the insert SQL, without any
quoting (which means that if
you want this to be a string,
your value should contain
single quotes around it like
this: literal="'Literal
String'"). This is especially
useful for databases that don't
support identity columns.
For example, if you are using
Oracle you could specify
literal="NAME_OF_YOUR_SEQUENCE.NEXTVAL"
to insert a unique ID in
an ID column. Either this
attribute, pattern, or
isEventTimestamp="true"
must be specified, but not more
than one of these.
parameter String Use this attribute to insert an
expression with a parameter
marker '?' in this column. The
value will be included directly
in the insert SQL, without any
quoting (which means that if
you want this to be a string,
your value should contain
single quotes around it like this:
<ColumnMapping
name="instant"
parameter="TIMESTAMPADD('MILLISECOND', ?,
TIMESTAMP
'1970-01-01')"/>
You can only specify one of
literal or parameter.
isEventTimestamp boolean Use this attribute to insert the
event timestamp in this column,
which should be a SQL datetime.
The value will be inserted as a
java.sql.Types.TIMESTAMP.
Either this attribute (equal
to true), pattern, or
isEventTimestamp must be
specified, but not more than one of
these.
9 Appenders 103
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
isUnicode boolean This attribute is ignored unless
pattern is specified. If
true or omitted (default),
the value will be inserted as
unicode ( setNString or
setNClob). Otherwise, the value
will be inserted non-unicode (
setString or setClob).
isClob boolean This attribute is ignored unless
pattern is specified. Use this
attribute to indicate that the column
stores Character Large Objects
(CLOBs). If true, the value will be
inserted as a CLOB ( setClob or
setNClob). If false or omitted
(default), the value will be inserted
as a VARCHAR or NVARCHAR (
setString or setNString).
Column Parameters
Parameter Name Type Description
name String Required. The name of the
database column.
pattern String Use this attribute to insert a value
or values from the log event in this
column using a PatternLayout
pattern. Simply specify any legal
pattern in this attribute. Either
this attribute, literal, or
isEventTimestamp="true"
must be specified, but not more
than one of these.
literal String Use this attribute to insert a literal
value in this column. The value
will be included directly in the
insert SQL, without any quoting
(which means that if you want this
to be a string, your value should
contain single quotes around it
like this: literal="'Literal
String'"). This is especially
useful for databases that don't
support identity columns. For
example, if you are using
Oracle you could specify
literal="NAME_OF_YOUR_SEQUENCE.NEXTVAL"
to insert a unique ID in
an ID column. Either this
attribute, pattern, or
isEventTimestamp="true"
must be specified, but not more
than one of these.
layout Layout The Layout to format the LogEvent.
9 Appenders 104
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
type String Conversion type name, a fully-
qualified class name.
ColumnMapping Parameters
Here are a couple sample configurations for the JDBCAppender, as well as a sample factory
implementation that uses Commons Pooling and Commons DBCP to pool database connections:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JDBC name="databaseAppender" tableName="dbo.application_log">
<DataSource jndiName="java:/comp/env/jdbc/LoggingDataSource" />
<Column name="eventDate" isEventTimestamp="true" />
<Column name="level" pattern="%level" />
<Column name="logger" pattern="%logger" />
<Column name="message" pattern="%message" />
<Column name="exception" pattern="%ex{full}" />
</JDBC>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JDBC name="databaseAppender" tableName="LOGGING.APPLICATION_LOG">
<ConnectionFactory class="net.example.db.ConnectionFactory" method="getDatabaseConnection" />
<Column name="EVENT_ID" literal="LOGGING.APPLICATION_LOG_SEQUENCE.NEXTVAL" />
<Column name="EVENT_DATE" isEventTimestamp="true" />
<Column name="LEVEL" pattern="%level" />
<Column name="LOGGER" pattern="%logger" />
<Column name="MESSAGE" pattern="%message" />
<Column name="THROWABLE" pattern="%ex{full}" />
</JDBC>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
9 Appenders 105
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
package net.example.db;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.DriverManagerConnectionFactory;
import org.apache.commons.dbcp.PoolableConnection;
import org.apache.commons.dbcp.PoolableConnectionFactory;
import org.apache.commons.dbcp.PoolingDataSource;
import org.apache.commons.pool.impl.GenericObjectPool;
public class ConnectionFactory {
private static interface Singleton {
final ConnectionFactory INSTANCE = new ConnectionFactory();
}
private final DataSource dataSource;
private ConnectionFactory() {
Properties properties = new Properties();
properties.setProperty("user", "logging");
properties.setProperty("password", "abc123"); // or get properties from some configuration file
GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>();
DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
"jdbc:mysql://example.org:3306/exampleDb", properties
);
new PoolableConnectionFactory(
connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED
);
this.dataSource = new PoolingDataSource(pool);
}
public static Connection getDatabaseConnection() throws SQLException {
return Singleton.INSTANCE.dataSource.getConnection();
}
}
This appender is MapMessage-aware.
The following configuration uses a MessageLayout to indicate that the Appender should match the
keys of a MapMessage to the names of ColumnMappings when setting the values of the Appender's
SQL INSERT statement. This let you insert rows for custom values in a database table based on a
Log4j MapMessage instead of values from LogEvents.
9 Appenders 106
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<Configuration status="debug">
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="%C{1.} %m %level MDC%X%n"/>
</Console>
<Jdbc name="databaseAppender" tableName="dsLogEntry" ignoreExceptions="false">
<DataSource jndiName="java:/comp/env/jdbc/TestDataSourceAppender" />
<ColumnMapping name="Id" />
<ColumnMapping name="ColumnA" />
<ColumnMapping name="ColumnB" />
<MessageLayout />
</Jdbc>
</Appenders>
<Loggers>
<Logger name="org.apache.logging.log4j.core.appender.db" level="debug" additivity="false">
<AppenderRef ref="databaseAppender" />
</Logger>
<Root level="fatal">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
9.1.8 JMS Appender
The JMS Appender sends the formatted log event to a JMS Destination.
Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender.
Starting in Log4j 2.1, these appenders were combined into the JMS Appender which makes no
distinction between queues and topics. However, configurations written for 2.0 which use the
<JMSQueue/> or <JMSTopic/> elements will continue to work with the new <JMS/> configuration
element.
Parameter Name Type Default Description
factoryBindingName String Required The name to locate in
the Context that provides
the ConnectionFactory.
This can be any
subinterface of
ConnectionFactory
as well.
9 Appenders 107
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
factoryName String Required The fully qualified
class name that should
be used to define
the Initial Context
Factory as defined in
INITIAL_CONTEXT_FACTORY.
If a factoryName is
specified without a
providerURL a warning
message will be logged
as this is likely to cause
problems.
filter Filter null A Filter to determine
if the event should be
handled by this Appender.
More than one Filter
may be used by using a
CompositeFilter.
layout Layout Required The Layout to use to
format the LogEvent. New
since 2.9, in previous
versions SerializedLayout
was default.
name String Required The name of the
Appender.
password String null The password to use
to create the JMS
connection.
providerURL String Required The URL of the provider
to use as defined by
PROVIDER_URL.
destinationBindingName String Required The name to use to
locate the Destination.
This can be a Queue
or Topic, and as such,
the attribute names
queueBindingName
and
topicBindingName
are aliases to maintain
compatibility with the
Log4j 2.0 JMS appenders.
securityPrincipalName String null The name of the
identity of the Principal
as specified by
SECURITY_PRINCIPAL.
If a securityPrincipalName
is specified without
securityCredentials a
warning message will be
logged as this is likely to
cause problems.
9 Appenders 108
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
securityCredentials String null The security credentials
for the principal
as specified by
SECURITY_CREDENTIALS.
ignoreExceptions boolean true When true, exceptions
caught while appending
events are internally
logged and then ignored.
When false exceptions
are propagated to the
caller. You must set
this to false when
wrapping this Appender in
a FailoverAppender.
immediateFail boolean false When set to true, log
events will not wait to
try to reconnect and will
fail immediately if the
JMS resources are not
available. New in 2.9.
reconnectIntervalMillis long 5000 If set to a value greater
than 0, after an error, the
JMSManager will attempt
to reconnect to the broker
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). New in
2.9.
urlPkgPrefixes String null A colon-separated list
of package prefixes for
the class name of the
factory class that will
create a URL context
factory as defined by
URL_PKG_PREFIXES.
userName String null The user id used to create
the JMS connection.
JMS Appender Parameters
Here is a sample JMS Appender configuration:
9 Appenders 109
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
<Appenders>
<JMS name="jmsQueue" destinationBindingName="MyQueue"
factoryBindingName="MyQueueConnectionFactory">
<JsonLayout properties="true"/>
</JMS>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="jmsQueue"/>
</Root>
</Loggers>
</Configuration>
To map your Log4j MapMessages to JMS javax.jms.MapMessages, set the layout of the appender
to MessageLayout with <MessageLayout /> (Since 2.9.):
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
<Appenders>
<JMS name="jmsQueue" destinationBindingName="MyQueue"
factoryBindingName="MyQueueConnectionFactory">
<MessageLayout />
</JMS>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="jmsQueue"/>
</Root>
</Loggers>
</Configuration>
9.1.9 JPAAppender
As of Log4j 2.11.0, JPA support has moved from the existing module logj-core to the new module
log4j-jpa.
The JPAAppender writes log events to a relational database table using the Java Persistence
API 2.1. It requires the API and a provider implementation be on the classpath. It also requires
a decorated entity configured to persist to the table desired. The entity should either extend
org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity
(if you mostly want to use the default mappings) and provide at least an @Id property, or
org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity
(if you want to significantly customize the mappings). See the Javadoc for these two classes for
more information. You can also consult the source code of these two classes as an example of how to
implement the entity.
Parameter Name Type Description
name String Required. The name of the
Appender.
9 Appenders 110
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
entityClassName String Required. The fully qualified
name of the concrete
LogEventWrapperEntity
implementation that has JPA
annotations mapping it to a
database table.
persistenceUnitName String Required. The name of the JPA
persistence unit that should be
used for persisting log events.
JPAAppender Parameters
Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j
configuration file, the second is the persistence.xml file. EclipseLink is assumed here, but
any JPA 2.1 or higher provider will do. You should always create a separate persistence unit
for logging, for two reasons. First, <shared-cache-mode> must be set to "NONE," which is
usually not desired in normal JPA usage. Also, for performance reasons the logging entity should
be isolated in its own persistence unit away from all other entities and you should use a non-JTA
data source. Note that your persistence unit must also contain <class> elements for all of the
org.apache.logging.log4j.core.appender.db.jpa.converter converter classes.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<JPA name="databaseAppender" persistenceUnitName="loggingPersistenceUnit"
entityClassName="com.example.logging.JpaLogEntity" />
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
9 Appenders 111
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
version="2.1">
<persistence-unit name="loggingPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter</class>
<class>org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter</class>
<class>com.example.logging.JpaLogEntity</class>
<non-jta-data-source>jdbc/LoggingDataSource</non-jta-data-source>
<shared-cache-mode>NONE</shared-cache-mode>
</persistence-unit>
</persistence>
package com.example.logging;
...
@Entity
@Table(name="application_log", schema="dbo")
public class JpaLogEntity extends BasicLogEventEntity {
private static final long serialVersionUID = 1L;
private long id = 0L;
public TestEntity() {
super(null);
}
public TestEntity(LogEvent wrappedEvent) {
super(wrappedEvent);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id")
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
// If you want to override the mapping of any properties mapped in BasicLogEventEntity,
// just override the getters and re-specify the annotations.
}
9 Appenders 112
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
package com.example.logging;
...
@Entity
@Table(name="application_log", schema="dbo")
public class JpaLogEntity extends AbstractLogEventWrapperEntity {
private static final long serialVersionUID = 1L;
private long id = 0L;
public TestEntity() {
super(null);
}
public TestEntity(LogEvent wrappedEvent) {
super(wrappedEvent);
}
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "logEventId")
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
@Override
@Enumerated(EnumType.STRING)
@Column(name = "level")
public Level getLevel() {
return this.getWrappedEvent().getLevel();
}
@Override
@Column(name = "logger")
public String getLoggerName() {
return this.getWrappedEvent().getLoggerName();
}
@Override
@Column(name = "message")
@Convert(converter = MyMessageConverter.class)
public Message getMessage() {
return this.getWrappedEvent().getMessage();
}
...
}
9.1.10 HttpAppender
The HttpAppender sends log events over HTTP. A Layout must be provided to format the LogEvent.
9 Appenders 113
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
Will set the Content-Type header according to the layout. Additional headers can be specified with
embedded Property elements.
Will wait for response from server, and throw error if no 2xx response is received.
Implemented with HttpURLConnection.
Parameter Name Type Description
name String The name of the Appender.
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.
layout Layout The Layout to use to format the
LogEvent.
Ssl SslConfiguration Contains the configuration for
the KeyStore and TrustStore for
https. Optional, uses Java runtime
defaults if not specified. See SSL
verifyHostname boolean Whether to verify server hostname
against certificate. Only valid for
https. Optional, defaults to true
url string The URL to use. The URL scheme
must be "http" or "https".
method string The HTTP method to use. Optional,
default is "POST".
connectTimeoutMillis integer The connect timeout in
milliseconds. Optional, default is 0
(infinite timeout).
readTimeoutMillis integer The socket read timeout in
milliseconds. Optional, default is 0
(infinite timeout).
headers Property[] Additional HTTP headers to use.
The values support lookups.
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.
HttpAppender Parameters
Here is a sample HttpAppender configuration snippet:
9 Appenders 114
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
...
<Appenders>
<Http name="Http" url="https://localhost:9200/test/log4j/">
<Property name="X-Java-Runtime" value="$${java:runtime}" />
<JsonLayout properties="true"/>
<SSL>
<KeyStore location="log4j2-keystore.jks" passwordEnvironmentVariable="KEYSTORE_PASSWORD"/>
<TrustStore location="truststore.jks" passwordFile="${sys:user.home}/truststore.pwd"/>
</SSL>
</Http>
</Appenders>
9.1.11 KafkaAppender
The KafkaAppender logs events to an Apache Kafka topic. Each log event is sent as a Kafka record.
Parameter Name Type Description
topic String The Kafka topic to use. Required.
key String The key that will be sent to Kafka
with every message. Optional value
defaulting to null. Any of the
Lookups) can be included.
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.
layout Layout The Layout to use to format the
LogEvent. Required, there is
no default. New since 2.9, in
previous versions <PatternLayout
pattern="%m"/> was default.
name String The name of the Appender.
Required.
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.
9 Appenders 115
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
syncSend boolean The default is true, causing
sends to block until the record
has been acknowledged by the
Kafka server. When set to false
sends return immediately, allowing
for lower latency and significantly
higher throughput. New since
2.8. Be aware that this is a new
addition, and it has not been
extensively tested. Any failure
sending to Kafka will be reported
as error to StatusLogger and the
log event will be dropped (the
ignoreExceptions parameter will not
be effective). Log events may arrive
out of order to the Kafka server.
properties Property[] You can set properties in Kafka
producer properties. You need to
set the bootstrap.servers
property, there are sensible default
values for the others. Do not set
the value.serializer nor
key.serializer properties.
KafkaAppender Parameters
Here is a sample KafkaAppender configuration snippet:
<?xml version="1.0" encoding="UTF-8"?>
...
<Appenders>
<Kafka name="Kafka" topic="log-test">
<PatternLayout pattern="%date %message"/>
<Property name="bootstrap.servers">localhost:9092</Property>
</Kafka>
</Appenders>
This appender is synchronous by default and will block until the record has been acknowledged by
the Kafka server, timeout for this can be set with the timeout.ms property (defaults to 30 seconds).
Wrap with Async appender and/or set syncSend to false to log asynchronously.
This appender requires the Kafka client library. Note that you need to use a version of the Kafka
client library matching the Kafka server used.
Note:Make sure to not let org.apache.kafka log to a Kafka appender on DEBUG level, since that
will cause recursive logging:
<?xml version="1.0" encoding="UTF-8"?>
...
<Loggers>
<Root level="DEBUG">
<AppenderRef ref="Kafka"/>
</Root>
<Logger name="org.apache.kafka" level="INFO" /> <!-- avoid recursive logging -->
</Loggers>
9 Appenders 116
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 117
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
immediateFlush 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
9 Appenders 118
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
Here is a sample MemoryMappedFile configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<MemoryMappedFile name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</MemoryMappedFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
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<C extends
NoSQLConnection<W, T extends
NoSQLObject<W>>>
Required. The NoSQL provider that
provides connections to the chosen
NoSQL database.
NoSQLAppender Parameters
9 Appenders 119
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
You specify which NoSQL provider to use by specifying the appropriate configuration element within
the <NoSql> element. The types currently supported are <MongoDb> and <CouchDb>. 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:
9 Appenders 120
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
{
"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", "fileName": "PreparedStatement.java", "lineNumber": 1049 },
{ "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
{ "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
{ "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
],
"cause": {
"type": "java.io.IOException",
"message": "Connection lost.",
"stackTrace": [
{ "className": "java.nio.channels.SocketChannel", "methodName": "write", "fileName": null, "lineNumber": -1 },
{ "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "fileName": "PreparedStatement.java", "lineNumber": 1032 },
{ "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
{ "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
{ "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
]
}
},
"contextMap": {
"ID": "86c3a497-4e67-4eed-9d6a-2e5797324d7b",
"username": "JohnDoe"
},
"contextStack": [
"topItem",
"anotherItem",
"bottomItem"
]
}
9 Appenders 121
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 122
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
MongoDB2 Provider Parameters
This appender is MapMessage-aware.
Here are a few sample configurations for the NoSQLAppender and MongoDB2 provider:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<NoSql name="databaseAppender">
<MongoDb2 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
username="loggingUser" password="abc123" />
</NoSql>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
9 Appenders 123
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<NoSql name="databaseAppender">
<MongoDb2 collectionName="applicationLog" factoryClassName="org.example.db.ConnectionFactory"
factoryMethodName="getNewMongoClient" />
</NoSql>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
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).
9 Appenders 124
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.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.
9 Appenders 125
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
MongoDB3 Provider Parameters
This appender is MapMessage-aware.
Here are a few sample configurations for the NoSQLAppender and MongoDB3 provider:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<NoSql name="databaseAppender">
<MongoDb3 databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
username="loggingUser" password="abc123" />
</NoSql>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<NoSql name="databaseAppender">
<MongoDb3 collectionName="applicationLog" factoryClassName="org.example.db.ConnectionFactory"
factoryMethodName="getNewMongoClient" />
</NoSql>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
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
9 Appenders 126
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
factoryClassName 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:
9 Appenders 127
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error">
<Appenders>
<NoSql name="databaseAppender">
<CouchDb databaseName="applicationDb" protocol="https" server="couch.example.org"
username="loggingUser" password="abc123" />
</NoSql>
</Appenders>
<Loggers>
<Root level="warn">
<AppenderRef ref="databaseAppender"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 128
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
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:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RandomAccessFile name="MyFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
</RandomAccessFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyFile"/>
</Root>
</Loggers>
</Configuration>
9 Appenders 129
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.:
9 Appenders 130
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
<Rewrite name="rewrite">
<AppenderRef ref="STDOUT"/>
<MapRewritePolicy mode="Add">
<KeyValuePair key="product" value="TestProduct"/>
</MapRewritePolicy>
</Rewrite>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Rewrite"/>
</Root>
</Loggers>
</Configuration>
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:
9 Appenders 131
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
<Rewrite name="rewrite">
<AppenderRef ref="STDOUT"/>
<PropertiesRewritePolicy>
<Property name="user">${sys:user.name}</Property>
<Property name="env">${sys:environment}</Property>
</PropertiesRewritePolicy>
</Rewrite>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Rewrite"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 132
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp">
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%m%n"/>
</Console>
<Rewrite name="rewrite">
<AppenderRef ref="STDOUT"/>
<LoggerNameLevelRewritePolicy logger="com.foo.bar">
<KeyValuePair key="INFO" value="DEBUG"/>
<KeyValuePair key="WARN" value="INFO"/>
</LoggerNameLevelRewritePolicy>
</Rewrite>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="Rewrite"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 133
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 134
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
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-rw-
rw- etc...
9 Appenders 135
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
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.
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="20 MB" />
<TimeBasedTriggeringPolicy />
</Policies>
9.Cron Triggering Policy
The CronTriggeringPolicy triggers rollover based on a cron expression.
Parameter Name Type Description
9 Appenders 136
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
9 Appenders 137
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 138
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 139
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
4 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
9 Appenders 140
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
This second example shows a rollover strategy that will keep up to 20 files before removing them.
9 Appenders 141
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
<DefaultRolloverStrategy max="20"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="6" modulate="true"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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:
9 Appenders 142
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<CronTriggeringPolicy schedule="0 0 * * * ?"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
This sample configuration is the same as the previous but limits the number of files saved each hour
to 10:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Appenders>
<RollingFile name="RollingFile" filePattern="logs/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout>
<Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
</PatternLayout>
<Policies>
<CronTriggeringPolicy schedule="0 0 * * * ?"/>
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
<DirectWriteRolloverStrategy maxFiles="10"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 143
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 144
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
pathConditions 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).
9 Appenders 145
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
scriptCondition 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
9 Appenders 146
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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
9 Appenders 147
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Properties>
<Property name="baseDir">logs</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd}.log.gz">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="*/app-*.log.gz" />
<IfLastModified age="60d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 148
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn" name="MyApp" packages="">
<Properties>
<Property name="baseDir">logs</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="250 MB"/>
</Policies>
<DefaultRolloverStrategy max="100">
<!--
Nested conditions: the inner condition is only evaluated on files
for which the outer conditions are true.
-->
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="*/app-*.log.gz">
<IfLastModified age="30d">
<IfAny>
<IfAccumulatedFileSize exceeds="100 GB" />
<IfAccumulatedFileCount exceeds="10" />
</IfAny>
</IfLastModified>
</IfFileName>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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
9 Appenders 149
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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.
9 Appenders 150
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
<Properties>
<Property name="baseDir">logs</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyyMMdd}.log.gz">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="2">
<ScriptCondition>
<Script name="superstitious" language="groovy"><![CDATA[
import java.nio.file.*;
def result = [];
def pattern = ~/\d*\/app-(\d*)\.log\.gz/;
pathList.each { pathWithAttributes ->
def relative = basePath.relativize pathWithAttributes.path
statusLogger.trace 'SCRIPT: relative path=' + relative + " (base=$basePath)";
// remove files dated Friday the 13th
def matcher = pattern.matcher(relative.toString());
if (matcher.find()) {
def dateString = matcher.group(1);
def calendar = Date.parse("yyyyMMdd", dateString).toCalendar();
def friday13th = calendar.get(Calendar.DAY_OF_MONTH) == 13 \
&& calendar.get(Calendar.DAY_OF_WEEK) == Calendar.FRIDAY;
if (friday13th) {
result.add pathWithAttributes;
statusLogger.trace 'SCRIPT: deleting path ' + pathWithAttributes;
}
}
}
statusLogger.trace 'SCRIPT: returning ' + result;
result;
]] >
</Script>
</ScriptCondition>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
9 Appenders 151
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
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-rw-
rw- 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.
9 Appenders 152
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
fileGroup 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.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="trace" name="MyApp" packages="">
<Properties>
<Property name="baseDir">logs</Property>
</Properties>
<Appenders>
<RollingFile name="RollingFile" fileName="${baseDir}/app.log"
filePattern="${baseDir}/$${date:yyyy-MM}/app-%d{yyyyMMdd}.log.gz"
filePermissions="rw-------">
<PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
<CronTriggeringPolicy schedule="0 0 0 * * ?"/>
<DefaultRolloverStrategy stopCustomActionsOnError="true">
<PosixViewAttribute basePath="${baseDir}/$${date:yyyy-MM}" filePermissions="r--r--r--">
<IfFileName glob="*.gz" />
</PosixViewAttribute>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
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.
9 Appenders 153
©2018, The Apache Software Foundation • ALL RIGHTS RESERVED.
A RollingRandomAccessFileAppender requires a TriggeringPolicy and a