This is an automated email from the ASF dual-hosted git repository.
github-bot pushed a commit to branch main-site-stg-out
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/main-site-stg-out by this push:
new 0fb22e5ed3 Add website content generated from
`1659e1c7d6240acfc5c2956c0f3cc177b7290c96`
0fb22e5ed3 is described below
commit 0fb22e5ed324edcc00c82c92aecf5281641cda4b
Author: ASF Logging Services RM <[email protected]>
AuthorDate: Tue May 28 13:49:53 2024 +0000
Add website content generated from
`1659e1c7d6240acfc5c2956c0f3cc177b7290c96`
---
manual/async.html | 830 ++++++++++++++++++++++++++++++++++--------------
manual/performance.html | 6 +-
plugin-reference.html | 7 +-
sitemap.xml | 92 +++---
4 files changed, 651 insertions(+), 284 deletions(-)
diff --git a/manual/async.html b/manual/async.html
index efccc6c756..e280cc8fd5 100644
--- a/manual/async.html
+++ b/manual/async.html
@@ -267,88 +267,132 @@
<div id="preamble">
<div class="sectionbody">
<div class="paragraph">
-<p>Asynchronous logging can improve your application’s performance by
executing the I/O operations in a separate thread.
-Log4j 2 makes a number of improvements in this area.</p>
+<p>Asynchronous logging is a technique to improve application logging
performance by executing all I/O operations in a separate thread.</p>
</div>
-<div class="ulist">
-<ul>
-<li>
-<p><strong>Asynchronous Loggers</strong> are a new addition in Log4j 2. Their
aim is to return from the call to Logger.log to the application as soon as
possible.
-You can choose between making all Loggers asynchronous or using a mixture of
synchronous and asynchronous Loggers.
-Making all Loggers asynchronous will give the best performance, while mixing
gives you more flexibility.</p>
-</li>
-<li>
-<p><strong>LMAX Disruptor technology</strong>.
-Asynchronous Loggers internally use the
-<a href="#UnderTheHood">Disruptor</a>, a lock-free inter-thread communication
library, instead of queues, resulting in higher throughput and lower
latency.</p>
-</li>
-<li>
-<p>As part of the work for Async Loggers, <strong>Asynchronous
Appenders</strong> have been enhanced to flush to disk at the end of a batch
(when the queue is empty).
-This produces the same result as configuring "immediateFlush=true", that is,
all received log events are always available on disk, but is more efficient
because it does not need to touch the disk on each and every log event.
-(Async Appenders use ArrayBlockingQueue internally and do not need the
disruptor jar on the classpath.)</p>
-</li>
-</ul>
+<div class="paragraph">
+<p>Log4j offers out-of-the-box two different asynchronous logging
solutions:</p>
+</div>
+<div class="dlist">
+<dl>
+<dt class="hdlist1">Asynchronous appender</dt>
+<dd>
+<p>A classical queue-based asynchronous appender, which is available since
Log4j 1.</p>
+<div class="paragraph">
+<p>See <a href="appenders.html#AsyncAppender" class="xref page">Asynchronous
appender</a> for more details.</p>
+</div>
+</dd>
+<dt class="hdlist1">Asynchronous loggers</dt>
+<dd>
+<p>Asynchronous loggers are a new feature available since Log4j 2.
+They are based on
+<a href="https://lmax-exchange.github.io/disruptor">LMAX Disruptor</a>,
+a lock-free inter-thread communication library, instead of queues, resulting
in higher throughput and lower latency.</p>
+<div class="paragraph">
+<p>The rest of this chapter is dedicated to this new component.</p>
+</div>
+</dd>
+</dl>
+</div>
+<div class="admonitionblock caution">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-caution" title="Caution"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>Logging performance depends greatly on the architecture of your application
and the way you use logging.
+The solutions offered by this chapter should be evaluated using benchmarks
against your own application.
+If benchmarks and profiling don’t show a statistically significant
difference between asynchronous and synchronous logging solutions, the latter
one is recommended, since it is the simplest one.</p>
+</div>
+</td>
+</tr>
+</table>
</div>
</div>
</div>
<div class="sect1">
-<h2 id="Trade-offs"><a class="anchor" href="#Trade-offs"></a>Trade-offs</h2>
+<h2 id="trade-offs"><a class="anchor" href="#trade-offs"></a><a
id="Trade-offs"></a>Trade-offs</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>Although asynchronous logging can give significant performance benefits,
there are situations where you may want to choose synchronous logging.
-This section describes some of the trade-offs of asynchronous logging.</p>
+<p>There are certain trade-offs associated with asynchronous logging:</p>
</div>
<div class="sect2">
-<h3 id="_benefits"><a class="anchor" href="#_benefits"></a>Benefits</h3>
-<div class="ulist">
-<ul>
-<li>
-<p>Higher peak performance throughput.
-With an asynchronous logger your application can log messages at 6 - 68 times
the rate of a synchronous logger.</p>
-<div class="paragraph">
-<p>This is especially interesting for applications that occasionally need to
log bursts of messages.
-Async logging can help prevent or dampen latency spikes by shortening the wait
time until the next message can be logged.
-If the queue size is configured large enough to handle the burst, asynchronous
logging will help prevent your application from falling behind (as much) during
a sudden increase of activity.</p>
-</div>
-</li>
-<li>
-<p>Lower logging response time <a href="#Latency">latency</a>.
-Response time latency is the time it takes for a call to Logger.log to return
under a given workload.
-Asynchronous Loggers have consistently lower latency than synchronous loggers
or even queue-based asynchronous appenders.</p>
-</li>
-</ul>
+<h3 id="async-benefits"><a class="anchor"
href="#async-benefits"></a>Benefits</h3>
+<div class="dlist">
+<dl>
+<dt class="hdlist1">Higher peak throughput</dt>
+<dd>
+<p>Applications that occasionally need to log bursts of messages, can take
advantage of asynchronous logging.
+It can prevent or dampen latency spikes by shortening the wait time until the
next message can be logged.
+If the queue size is large enough to handle the burst, asynchronous logging
will prevent your application from falling behind during a sudden increase of
activity.</p>
+</dd>
+<dt class="hdlist1">Lower logging latency</dt>
+<dd>
+<p><a
href="../javadoc/log4j-api/org/apache/logging/log4j/Logger.html">Logger</a>
+method calls return faster, since most of the work is done on the I/O
thread.</p>
+</dd>
+</dl>
</div>
</div>
<div class="sect2">
-<h3 id="_drawbacks"><a class="anchor" href="#_drawbacks"></a>Drawbacks</h3>
-<div class="paragraph">
-<p>There are certain drawbacks associated with asynchronous logging:</p>
-</div>
+<h3 id="async-drawbacks"><a class="anchor"
href="#async-drawbacks"></a>Drawbacks</h3>
<div class="dlist">
<dl>
+<dt class="hdlist1">Lower sustainable throughput</dt>
+<dd>
+<p>If the <em>sustained rate</em> at which your application is logging
messages is faster than the maximum sustained throughput of the underlying
appender, the queue will fill up and the application will end up logging at the
speed of the slowest appender.
+If this happens, consider selecting a faster appender, or logging less.
+If neither of these is an option, you may get better throughput and fewer
latency spikes by logging synchronously.</p>
+</dd>
<dt class="hdlist1">Error handling</dt>
<dd>
<p>If a problem happens during the logging process and an exception is thrown,
it is less easy for an asynchronous setting to signal this problem to the
application.
This can partly be alleviated by configuring an exception handler, but this
may still not cover all cases.</p>
+<div class="admonitionblock caution">
+<table>
+<tr>
+<td class="icon">
+<i class="fa icon-caution" title="Caution"></i>
+</td>
+<td class="content">
+<div class="paragraph">
+<p>If logging is part of your business logic, e.g. you are using Log4j as an
audit logging framework, we would recommend to synchronously log those audit
messages.</p>
+</div>
+<div class="paragraph">
+<p>See
+<a href="#MixedSync-Async">mixed synchronous/asynchronous loggers</a> on how
to log some messages synchronously.</p>
+</div>
+</td>
+</tr>
+</table>
+</div>
</dd>
<dt class="hdlist1">Stateful messages</dt>
<dd>
-<p>In some rare cases, care must be taken with mutable messages.
-Most of the time you don’t need to worry about this.
-Log4 will ensure that log messages like <code>logger.debug("My object is {}",
myObject)</code> will use the state of the <code>myObject</code> parameter at
the time of the call to <code>logger.debug()</code>.
-The log message will not change even if <code>myObject</code> is modified
later.
-It is safe to asynchronously log mutable objects because most <a
href="https://logging.apache.org/log4j/2.x/manual/messages.adoc">built-in
<code>Message</code> implementations</a> take a snapshot of the parameters.
-There are some exceptions however: <a
href="https://logging.apache.org/log4j/2.x/manual/messages.adoc#MapMessage"><code>MapMessage</code></a>
and <a
href="https://logging.apache.org/log4j/2.x/manual/messages.adoc#StructuredDataMessage"><code>StructuredDataMessage</code></a>
are mutable by design, fields can be added to these messages after the message
object was created.
-These messages should not be modified after they are logged with asynchronous
loggers or asynchronous appenders; you may or may not see the modifications in
the resulting log output.
-Similarly, custom <code>Message</code> implementations should be designed with
asynchronous use in mind, and either take a snapshot of their parameters at
construction time, or document their thread-safety characteristics.</p>
+<p>Most
+<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html"><code>Message</code></a>
+implementations take a snapshot of the formatted message on the calling thread
(cf.
+<a href="systemproperties.html#log4j.async.formatMessagesInBackground"
class="xref page"><code>log4j.async.formatMessagesInBackground</code></a>).
+The log message will not change even if the arguments of the logging call are
modified later.</p>
+<div class="paragraph">
+<p>There are some exceptions to this rule.
+<a
href="https://logging.apache.org/log4j/2.x/manual/messages.html#MapMessage"><code>MapMessage</code></a>
+and
+<a
href="https://logging.apache.org/log4j/2.x/manual/messages.html#StructuredDataMessage"><code>StructuredDataMessage</code></a>
+for example are mutable by design: fields can be added to these messages after
the message object was created.
+These messages should not be modified after they are logged with asynchronous
loggers or asynchronous appenders.</p>
+</div>
+<div class="paragraph">
+<p>Similarly, custom
+<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html"><code>Message</code></a>
+implementations should be designed with asynchronous use in mind, and either
take a snapshot of their parameters at construction time, or document their
thread-safety characteristics (see
+<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/AsynchronouslyFormattable.html"><code>AsynchronouslyFormattable</code></a>).</p>
+</div>
</dd>
<dt class="hdlist1">Computational overhead</dt>
<dd>
-<p>If your application is running in an environment where CPU resources are
scarce, like a machine with one CPU with a single core, starting another thread
is not likely to give better performance.</p>
-</dd>
-<dt class="hdlist1">Appender performance</dt>
-<dd>
-<p>If the sustained rate at which your application is logging messages is
faster than the maximum sustained throughput of the underlying appender, the
queue will fill up and the application will end up logging at the speed of the
slowest appender. If this happens, consider selecting a faster appender, or
logging less. If neither of these is an option, you may get better throughput
and fewer latency spikes by logging synchronously.</p>
+<p>If your application is running in an environment where CPU resources are
scarce, like a VM with a single vCPU, starting another thread is not likely to
give better performance.</p>
</dd>
</dl>
</div>
@@ -356,156 +400,414 @@ Similarly, custom <code>Message</code> implementations
should be designed with a
</div>
</div>
<div class="sect1">
-<h2 id="AllAsync"><a class="anchor" href="#AllAsync"></a>Making All Loggers
Asynchronous</h2>
+<h2 id="installation"><a class="anchor"
href="#installation"></a>Installation</h2>
<div class="sectionbody">
-<div class="admonitionblock note">
+<div class="paragraph">
+<p>In order to use async loggers, you need to add
<code>log4j-async-logger</code> to you application’s dependencies, by
adding the
+following dependency to your build tool:</p>
+</div>
+<div id="_tabs_1" class="openblock tabs is-loading">
+<div class="content">
+<div class="ulist tablist">
+<ul>
+<li id="_tabs_1_maven" class="tab">
+<p>Maven</p>
+</li>
+<li id="_tabs_1_gradle" class="tab">
+<p>Gradle</p>
+</li>
+</ul>
+</div>
+<div id="_tabs_1_maven--panel" class="tabpanel"
aria-labelledby="_tabs_1_maven">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-xml hljs"
data-lang="xml"><dependency>
+ <groupId>org.apache.logging.log4j</groupId>
+ <artifactId>log4j-async-logger</artifactId>
+ <scope>runtime</scope>
+</dependency></code></pre>
+</div>
+</div>
+</div>
+<div id="_tabs_1_gradle--panel" class="tabpanel"
aria-labelledby="_tabs_1_gradle">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-groovy hljs"
data-lang="groovy">runtimeOnly
'org.apache.logging.log4j:log4j-async-logger'</code></pre>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="configuration"><a class="anchor"
href="#configuration"></a>Configuration</h2>
+<div class="sectionbody">
+<div class="paragraph">
+<p>There are two ways asynchronous loggers can be used in Log4j.
+You can:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p><a href="#AllAsync">Making all loggers asynchronous</a>, which gives a
better performance,</p>
+</li>
+<li>
+<p><a href="#MixedSync-Async">Mixing synchronous and asynchronous loggers</a>,
which gives more flexibility.</p>
+</li>
+</ul>
+</div>
+<div class="paragraph">
+<p>Under the hood these methods use different Log4j plugins, but also share a
+<a href="#common-configuration-properties">set of common configuration
properties</a>.</p>
+</div>
+<div class="sect2">
+<h3 id="AllAsync"><a class="anchor" href="#AllAsync"></a>Making all loggers
asynchronous</h3>
+<div class="paragraph">
+<p>This is the simplest to configure and gives the best performance: to make
all logger asynchronous, <strong>all</strong> you need to set the
+<a href="systemproperties.html#log4j.loggerContext.selector" class="xref
page"><code>log4j.loggerContext.selector</code></a>
+property to one of the asynchronous logger context selectors:</p>
+</div>
+<div class="dlist">
+<dl>
+<dt class="hdlist1"><a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/BasicAsyncLoggerContextSelector">org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector</a></dt>
+<dd>
+<p>This will create a single logger context and disruptor for all the classes
in the JVM,</p>
+</dd>
+<dt class="hdlist1"><a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector">org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</a></dt>
+<dd>
+<p>This will create a different logger context and disruptor for each
classloader in the JVM.</p>
+</dd>
+</dl>
+</div>
+<div class="admonitionblock important">
<table>
<tr>
<td class="icon">
-<i class="fa icon-note" title="Note"></i>
+<i class="fa icon-important" title="Important"></i>
</td>
<td class="content">
-<em>Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the
classpath.
-Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.</em>
+<div class="paragraph">
+<p>When using an asynchronous logger context you should use only
<code>Root</code> and <code>Logger</code> elements (cf.
+<a href="configuration.html#configuring-loggers" class="xref page">Logger
configuration</a>).</p>
+</div>
+<div class="paragraph">
+<p>If you use <code>AsyncRoot</code> and <code>AsyncLogger</code>
configuration elements, two asynchronous barriers will be created instead of
one, which will impair performance.</p>
+</div>
</td>
</tr>
</table>
</div>
+</div>
+<div class="sect2">
+<h3 id="MixedSync-Async"><a class="anchor" href="#MixedSync-Async"></a>Mixing
synchronous and asynchronous loggers</h3>
<div class="paragraph">
-<p>This is simplest to configure and gives the best performance.
-To make all loggers asynchronous, add the disruptor jar to the classpath and
set the system property <code>log4j2.contextSelector</code> to
-<code>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</code> or
-<code>org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector</code>.</p>
+<p>Synchronous and asynchronous loggers can be combined in a single
configuration.
+This gives you more flexibility at the cost of a slight loss in performance
(compared to making all loggers asynchronous).</p>
</div>
<div class="paragraph">
-<p>By default, <a href="#Location">location</a> is not passed to the I/O
thread by asynchronous loggers.
-If one of your layouts or custom filters needs location information, you need
to set "includeLocation=true" in the configuration of all relevant loggers,
including the root logger.</p>
+<p>In order to use this configuration, you need to keep the
+<a href="systemproperties.html#log4j.loggerContext.selector" class="xref
page"><code>log4j.loggerContext.selector</code></a>
+at its default value and use one of the
+<code>AsyncRoot</code> and <code>AsyncLogger</code> configuration elements to
designate the loggers that you want to be asynchronous.</p>
</div>
<div class="paragraph">
-<p>A configuration that does not require location might look like:</p>
+<p>A configuration that mixes asynchronous loggers might look like:</p>
</div>
+<div id="_tabs_2" class="openblock tabs is-loading">
+<div class="content">
+<div class="ulist tablist">
+<ul>
+<li id="_tabs_2_xml" class="tab">
+<p>XML</p>
+</li>
+<li id="_tabs_2_json" class="tab">
+<p>JSON</p>
+</li>
+<li id="_tabs_2_yaml" class="tab">
+<p>YAML</p>
+</li>
+<li id="_tabs_2_java_properties" class="tab">
+<p>Java properties</p>
+</li>
+</ul>
+</div>
+<div id="_tabs_2_xml--panel" class="tabpanel" aria-labelledby="_tabs_2_xml">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs"
data-lang="xml"><?xml version="1.0" encoding="UTF-8"?>
-
-<!-- Don't forget to set system property
--Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-or
--Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.BasicAsyncLoggerContextSelector
- to make all loggers asynchronous. -->
-
-<Configuration status="WARN">
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+ https://logging.apache.org/xml/ns/log4j-config-2.xsd">
<Appenders>
- <!-- Async Loggers will auto-flush in batches, so switch off
immediateFlush. -->
- <RandomAccessFile name="RandomAccessFile" fileName="async.log"
immediateFlush="false" append="false">
- <PatternLayout>
- <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
- </PatternLayout>
- </RandomAccessFile>
+ <File name="AUDIT" fileName="logs/audit.log"
ignoreExceptions="false">
+ <JsonTemplateLayout/>
+ </File>
+ <File name="DEBUG_LOG" fileName="logs/debug.log">
+ <PatternLayout/>
+ </File>
</Appenders>
<Loggers>
- <Root level="info" includeLocation="false">
- <AppenderRef ref="RandomAccessFile"/>
+ <Root level="INFO">
+ <AppenderRef ref="AUDIT"> <i class="conum"
data-value="1"></i><b>(1)</b>
+ <MarkerFilter marker="AUDIT" onMatch="ACCEPT" onMimatch="DENY"/>
+ </AppenderRef>
</Root>
+ <AsyncLogger name="com.example" level="TRACE">
+ <AppenderRef ref="DEBUG_LOG"/> <i class="conum"
data-value="2"></i><b>(2)</b>
+ </AsyncLogger>
</Loggers>
</Configuration></code></pre>
</div>
</div>
-<div class="paragraph">
-<p>When <code>AsyncLoggerContextSelector</code> or
-<code>BasicAsyncLoggerContextSelector</code> is used to make all loggers
asynchronous, make sure to use normal <code><root></code> and
<code><logger></code> elements in the configuration.
-The context selector will ensure that all loggers are asynchronous, using a
mechanism that is different from what happens when you configure
<code><asyncRoot></code> or <code><asyncLogger></code>.
-The latter elements are intended for mixing async with sync loggers.
-If you use both mechanisms together you will end up with two background
threads, where your application passes the log message to thread A, which
passes the message to thread B, which then finally logs the message to disk.
-This works, but there will be an unnecessary step in the middle.</p>
</div>
-<div class="paragraph">
-<p>There are a few system properties you can use to control aspects of the
asynchronous logging subsystem.
-Some of these can be used to tune logging performance.</p>
+<div id="_tabs_2_json--panel" class="tabpanel" aria-labelledby="_tabs_2_json">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-json hljs"
data-lang="json">{
+ "Configuration": {
+ "Appenders": [
+ {
+ "name": "AUDIT",
+ "fileName": "logs/audit.log",
+ "ignoreExceptions": false,
+ "JsonTemplateLayout": {}
+ },
+ {
+ "name": "DEBUG_LOG",
+ "fileName": "logs/debug.log",
+ "PatternLayout": {}
+ }
+ ]
+ },
+ "Loggers": {
+ "Root": {
+ "level": "INFO",
+ "AppenderRef": { <i class="conum" data-value="1"></i><b>(1)</b>
+ "ref": "AUDIT",
+ "MarkerFilter": {
+ "marker": "AUDIT",
+ "onMatch": "ACCEPT",
+ "onMismatch": "DENY"
+ }
+ }
+ },
+ "AsyncLogger": { <i class="conum" data-value="2"></i><b>(2)</b>
+ "name": "com.example",
+ "level": "TRACE",
+ "AppenderRef": {
+ "ref": "DEBUG_LOG"
+ }
+ }
+ }
+}</code></pre>
</div>
-<div class="paragraph">
-<p>The below properties can also be specified by creating a file named
-<code>log4j2.component.properties</code> and including this file in the
classpath of the application.</p>
</div>
</div>
+<div id="_tabs_2_yaml--panel" class="tabpanel" aria-labelledby="_tabs_2_yaml">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-yaml hljs"
data-lang="yaml">Configuration:
+ Appenders:
+ File:
+ - name: "AUDIT"
+ fileName: "logs/audit.log"
+ ignoreExceptions: false
+ JsonTemplateLayout: {}
+ - name: "DEBUG_LOG"
+ fileName: "logs/debug.log"
+ PatternLayout: {}
+ Loggers:
+ Root:
+ level: "INFO"
+ AppenderRef: <i class="conum" data-value="1"></i><b>(1)</b>
+ ref: "AUDIT"
+ MarkerFilter:
+ marker: "AUDIT"
+ onMatch: "ACCEPT"
+ onMismatch: "DENY"
+ AsyncLogger:
+ name: "com.example"
+ level: "TRACE"
+ AppenderRef: <i class="conum" data-value="2"></i><b>(2)</b>
+ ref: "DEBUG_LOG"</code></pre>
+</div>
+</div>
+</div>
+<div id="_tabs_2_java_properties--panel" class="tabpanel"
aria-labelledby="_tabs_2_java_properties">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-properties hljs"
data-lang="properties">appender.0.type = File
+appender.0.name = AUDIT
+appender.0.fileName = logs/audit.log
+appender.0.ignoreExceptions = false
+appender.0.layout.type = JsonTemplateLayout
+
+appender.1.type = File
+appender.1.name = DEBUG_LOG
+appender.1.fileName = logs/debug.log
+appender.1.layout.type = PatternLayout
+
+rootLogger.level = INFO
+rootLogger.appenderRef.0.ref = AUDIT <i class="conum"
data-value="1"></i><b>(1)</b>
+rootLogger.appenderRef.0.filter.0.type = MarkerFilter
+rootLogger.appenderRef.0.filter.0.marker = AUDIT
+rootLogger.appenderRef.0.filter.0.onMatch = ACCEPT
+rootLogger.appenderRef.0.filter.0.onMismatch = DENY
+
+logger.0.type = AsyncLogger
+logger.0.name = com.example
+logger.0.level = TRACE
+logger.0.appenderRef.0.ref = DEBUG_LOG <i class="conum"
data-value="2"></i><b>(2)</b></code></pre>
</div>
-<div class="sect1">
-<h2 id="MixedSync-Async"><a class="anchor" href="#MixedSync-Async"></a>Mixing
Synchronous and Asynchronous Loggers</h2>
-<div class="sectionbody">
-<div class="admonitionblock note">
+</div>
+</div>
+</div>
+</div>
+<div class="colist arabic">
+<table>
+<tr>
+<td><i class="conum" data-value="1"></i><b>1</b></td>
+<td>All the appenders referenced by <code>Root</code> and <code>Logger</code>
are called synchronously.
+This is especially important for audit logging, since exceptions can be
forwarded to the caller.</td>
+</tr>
+<tr>
+<td><i class="conum" data-value="2"></i><b>2</b></td>
+<td>All the appenders references by <code>AsyncRoot</code> and
<code>AsyncLogger</code> are called asynchronously.
+These log statements will cause a smaller latency for the caller.</td>
+</tr>
+</table>
+</div>
+</div>
+<div class="sect2">
+<h3 id="common-configuration-properties"><a class="anchor"
href="#common-configuration-properties"></a>Common configuration properties</h3>
+<div class="admonitionblock tip">
<table>
<tr>
<td class="icon">
-<i class="fa icon-note" title="Note"></i>
+<i class="fa icon-tip" title="Tip"></i>
</td>
<td class="content">
-<em>Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the
classpath.
-Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.
-There is no need to set system property "Log4jContextSelector" to any
value.</em>
+<div class="paragraph">
+<p>You can place the values of configuration properties in a
<code>log4j2.component.properties</code> file at the root of your
application’s classpath.</p>
+</div>
+<div class="paragraph">
+<p>See <a href="systemproperties.html#property-sources" class="xref
page">Property Sources</a> for more details.</p>
+</div>
</td>
</tr>
</table>
</div>
<div class="paragraph">
-<p>Synchronous and asynchronous loggers can be combined in configuration.
-This gives you more flexibility at the cost of a slight loss in performance
(compared to making all loggers asynchronous).
-Use the
-<code><asyncRoot></code> or <code><asyncLogger></code>
configuration elements to specify the loggers that need to be asynchronous.
-A configuration can contain only one root logger (either a
<code><root></code> or an <code><asyncRoot></code> element), but
otherwise async and non-async loggers may be combined.
-For example, a configuration file containing <code><asyncLogger></code>
elements can also contain
-<code><root></code> and <code><logger></code> elements for the
synchronous loggers.</p>
+<p>Regardless of the way you configure asynchronous loggers in Log4j, you can
use the following properties to further tune your installation:</p>
</div>
+<div class="sect3">
+<h4 id="log4j.async.formatMessagesInBackground"><a class="anchor"
href="#log4j.async.formatMessagesInBackground"></a><code>log4j.async.formatMessagesInBackground</code></h4>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 16.6666%;">
+<col style="width: 83.3334%;">
+</colgroup>
+<tbody>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Env.
variable</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock">LOG4J_ASYNC_FORMAT_MESSAGES_IN_BACKGROUND</p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p
class="tableblock">Type</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>boolean</code></p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Default
value</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>false</code></p></td>
+</tr>
+</tbody>
+</table>
<div class="paragraph">
-<p>By default, <a href="#Location">location</a> is not passed to the I/O
thread by asynchronous loggers.
-If one of your layouts or custom filters needs location information, you need
to set "includeLocation=true" in the configuration of all relevant loggers,
including the root logger.</p>
+<p>If <code>false</code>, Log4j will make sure the message is formatted in the
caller thread, otherwise the formatting will occur on the asynchronous
thread.</p>
</div>
<div class="paragraph">
-<p>A configuration that mixes asynchronous loggers might look like:</p>
+<p><strong>Remark</strong>: messages annotated with <a
href="https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/message/AsynchronouslyFormattable">AsynchronouslyFormattable</a>
will be formatted on the async thread regardless of this setting.</p>
</div>
-<div class="listingblock">
-<div class="content">
-<pre class="highlightjs highlight"><code class="language-xml hljs"
data-lang="xml"><?xml version="1.0" encoding="UTF-8"?>
-
-<!-- No need to set system property "log4j2.contextSelector" to any value
- when using <asyncLogger> or <asyncRoot>. -->
-
-<Configuration status="WARN">
- <Appenders>
- <!-- Async Loggers will auto-flush in batches, so switch off
immediateFlush. -->
- <RandomAccessFile name="RandomAccessFile"
fileName="asyncWithLocation.log"
- immediateFlush="false" append="false">
- <PatternLayout>
- <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
- </PatternLayout>
- </RandomAccessFile>
- </Appenders>
- <Loggers>
- <!-- pattern layout actually uses location, so we need to include it
-->
- <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
- <AppenderRef ref="RandomAccessFile"/>
- </AsyncLogger>
- <Root level="info" includeLocation="true">
- <AppenderRef ref="RandomAccessFile"/>
- </Root>
- </Loggers>
-</Configuration></code></pre>
</div>
+<div class="sect3">
+<h4 id="log4j.async.queueFullPolicy.type"><a class="anchor"
href="#log4j.async.queueFullPolicy.type"></a><code>log4j.async.queueFullPolicy.type</code></h4>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 16.6666%;">
+<col style="width: 83.3334%;">
+</colgroup>
+<tbody>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Env.
variable</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock">LOG4J_ASYNC_QUEUE_FULL_POLICY_TYPE</p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p
class="tableblock">Type</p></th>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy">Class<?
extends AsyncQueueFullPolicy></a> or predefined constant</p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Default
value</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>Default</code></p></td>
+</tr>
+</tbody>
+</table>
+<div class="paragraph">
+<p>Determines the <a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy">AsyncQueueFullPolicy</a>
to use when the underlying async component cannot keep up with the logging
rate and the queue is filling up.</p>
</div>
<div class="paragraph">
-<p>There are a few system properties you can use to control aspects of the
asynchronous logging subsystem.
-Some of these can be used to tune logging performance.</p>
+<p>Its value should be the fully qualified class name of an
<code>AsyncQueueFullPolicy</code> implementation or one of these predefined
constants:</p>
+</div>
+<div class="dlist">
+<dl>
+<dt class="hdlist1">Default</dt>
+<dd>
+<p>blocks the calling thread until the event can be added to the queue.</p>
+</dd>
+<dt class="hdlist1">Discard</dt>
+<dd>
+<p>when the queue is full, it drops the events whose level is equal or less
than the threshold level (see
+<a
href="#log4j.async.queueFullPolicy.discardThreshold"><code>log4j.async.queueFullPolicy.discardThreshold</code></a>).</p>
+</dd>
+</dl>
</div>
+</div>
+<div class="sect3">
+<h4 id="log4j.async.queueFullPolicy.discardThreshold"><a class="anchor"
href="#log4j.async.queueFullPolicy.discardThreshold"></a><code>log4j.async.queueFullPolicy.discardThreshold</code></h4>
+<table class="tableblock frame-all grid-all stretch">
+<colgroup>
+<col style="width: 16.6666%;">
+<col style="width: 83.3334%;">
+</colgroup>
+<tbody>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Env.
variable</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock">LOG4J_ASYNC_QUEUE_FULL_POLICY_DISCARD_THRESHOLD</p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p
class="tableblock">Type</p></th>
+<td class="tableblock halign-left valign-top"><p class="tableblock"><a
href="https://logging.apache.org/log4j/2.x/javadoc/log4j-api/org/apache/logging/log4j/Level">Level</a></p></td>
+</tr>
+<tr>
+<th class="tableblock halign-left valign-top"><p class="tableblock">Default
value</p></th>
+<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>INFO</code></p></td>
+</tr>
+</tbody>
+</table>
<div class="paragraph">
-<p>The below properties can also be specified by creating a file named
-<code>log4j2.component.properties</code> and including this file in the
classpath of the application.</p>
+<p>Determines the threshold level used by a <code>Discard</code> queue full
policy.
+Log events whose level is equal or less specific than the threshold level will
be discarded during a queue full event.
+See also <a
href="#log4j.async.queueFullPolicy.type"><code>log4j.async.queueFullPolicy.type</code></a>.</p>
+</div>
+</div>
</div>
</div>
</div>
<div class="sect1">
-<h2 id="configuration-properties"><a class="anchor"
href="#configuration-properties"></a>Configuration properties</h2>
+<h2 id="log4j.async.logger.configExceptionHandler"><a class="anchor"
href="#log4j.async.logger.configExceptionHandler"></a><code>log4j.async.logger.configExceptionHandler</code></h2>
<div class="sectionbody">
-<div class="sect2">
-<h3 id="log4j.async.logger.configExceptionHandler"><a class="anchor"
href="#log4j.async.logger.configExceptionHandler"></a><code>log4j.async.logger.configExceptionHandler</code></h3>
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -553,8 +855,10 @@ The class needs to have a public zero-argument
constructor.</p>
</table>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.exceptionHandler"><a class="anchor"
href="#log4j.async.logger.exceptionHandler"></a><code>log4j.async.logger.exceptionHandler</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.exceptionHandler"><a class="anchor"
href="#log4j.async.logger.exceptionHandler"></a><code>log4j.async.logger.exceptionHandler</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -602,8 +906,10 @@ The class needs to have a public zero-argument
constructor.</p>
</table>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.synchronizeEnqueueWhenQueueFull"><a class="anchor"
href="#log4j.async.logger.synchronizeEnqueueWhenQueueFull"></a><code>log4j.async.logger.synchronizeEnqueueWhenQueueFull</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.synchronizeEnqueueWhenQueueFull"><a class="anchor"
href="#log4j.async.logger.synchronizeEnqueueWhenQueueFull"></a><code>log4j.async.logger.synchronizeEnqueueWhenQueueFull</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -631,8 +937,10 @@ CPU utilization is significantly reduced by restricting
access to the enqueue op
Setting this value to <code>false</code> may lead to very high CPU utilization
when the async logging queue is full.</p>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.ringBuffer.size"><a class="anchor"
href="#log4j.async.logger.ringBuffer.size"></a><code>log4j.async.logger.ringBuffer.size</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.ringBuffer.size"><a class="anchor"
href="#log4j.async.logger.ringBuffer.size"></a><code>log4j.async.logger.ringBuffer.size</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -664,8 +972,10 @@ The RingBuffer will be pre-allocated at first use and will
never grow or shrink
<p>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 behaviour is
determined by the <a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html">AsyncQueueFullPolicy</a>.</p>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.waitStrategy.type"><a class="anchor"
href="#log4j.async.logger.waitStrategy.type"></a><code>log4j.async.logger.waitStrategy.type</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.waitStrategy.type"><a class="anchor"
href="#log4j.async.logger.waitStrategy.type"></a><code>log4j.async.logger.waitStrategy.type</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -718,8 +1028,10 @@ This strategy has very low impact on the application
thread, in exchange for som
</dl>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.waitStrategy.retries"><a class="anchor"
href="#log4j.async.logger.waitStrategy.retries"></a><code>log4j.async.logger.waitStrategy.retries</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.waitStrategy.retries"><a class="anchor"
href="#log4j.async.logger.waitStrategy.retries"></a><code>log4j.async.logger.waitStrategy.retries</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -744,8 +1056,10 @@ This strategy has very low impact on the application
thread, in exchange for som
<p>Total number of spin cycles and <code>Thread.yield()</code> cycles of
<code>Sleep</code> (see <a
href="#log4j.async.logger.waitStrategy.type"><code>log4j.async.logger.waitStrategy.type</code></a>).</p>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.waitStrategy.sleepTimeNs"><a class="anchor"
href="#log4j.async.logger.waitStrategy.sleepTimeNs"></a><code>log4j.async.logger.waitStrategy.sleepTimeNs</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.waitStrategy.sleepTimeNs"><a class="anchor"
href="#log4j.async.logger.waitStrategy.sleepTimeNs"></a><code>log4j.async.logger.waitStrategy.sleepTimeNs</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -770,8 +1084,10 @@ This strategy has very low impact on the application
thread, in exchange for som
<p>Sleep time in nanoseconds of <code>Sleep</code> wait strategy (see <a
href="#log4j.async.logger.waitStrategy.type"><code>log4j.async.logger.waitStrategy.type</code></a>).</p>
</div>
</div>
-<div class="sect2">
-<h3 id="log4j.async.logger.waitStrategy.timeout"><a class="anchor"
href="#log4j.async.logger.waitStrategy.timeout"></a><code>log4j.async.logger.waitStrategy.timeout</code></h3>
+</div>
+<div class="sect1">
+<h2 id="log4j.async.logger.waitStrategy.timeout"><a class="anchor"
href="#log4j.async.logger.waitStrategy.timeout"></a><code>log4j.async.logger.waitStrategy.timeout</code></h2>
+<div class="sectionbody">
<table class="tableblock frame-all grid-all stretch">
<colgroup>
<col style="width: 16.6666%;">
@@ -797,112 +1113,158 @@ This strategy has very low impact on the application
thread, in exchange for som
</div>
</div>
</div>
-</div>
<div class="sect1">
-<h2 id="WaitStrategy"><a class="anchor" href="#WaitStrategy"></a>Custom
WaitStrategy</h2>
+<h2 id="custom-waitstrategy"><a class="anchor"
href="#custom-waitstrategy"></a>Custom <code>WaitStrategy</code></h2>
<div class="sectionbody">
<div class="paragraph">
-<p>The system properties mentioned above allow only choice from among a fixed
set of predefined WaitStrategies.
-There may be cases where you want to configure a custom WaitStrategy that is
not in this list.
-This is possible by using a <code>AsyncWaitStrategyFactory</code> element in
the Log4j configuration.</p>
+<p>The system properties mentioned in the section above allow only to choose
from among a fixed set of wait strategies.</p>
</div>
<div class="paragraph">
-<p>A configuration that configures a custom WaitStrategy can look as
follows:</p>
+<p>In order to use a custom wait strategy you need to:</p>
+</div>
+<div class="olist arabic">
+<ol class="arabic">
+<li>
+<p>Use the <a href="#MixedSync-Async">mixed sync/async configuration
method</a> above,</p>
+</li>
+<li>
+<p>Implement the interface
+<a
href="../javadoc/log4j-core/org/apache/logging/log4j/core/async/AsyncWaitStrategyFactory.html">AsyncWaitStrategyFactory</a>;
the implementation must have a public no-arg constructor,</p>
+</li>
+<li>
+<p>Add an <a
href="../plugin-reference.html#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-async-AsyncWaitStrategyFactoryConfig"
class="xref page">AsyncWaitStrategyFactory Log4j plugin</a>
+to your configuration.</p>
+</li>
+</ol>
+</div>
+<div id="_tabs_3" class="openblock tabs is-loading">
+<div class="content">
+<div class="ulist tablist">
+<ul>
+<li id="_tabs_3_xml" class="tab">
+<p>XML</p>
+</li>
+<li id="_tabs_3_json" class="tab">
+<p>JSON</p>
+</li>
+<li id="_tabs_3_yaml" class="tab">
+<p>YAML</p>
+</li>
+<li id="_tabs_3_java_properties" class="tab">
+<p>Java properties</p>
+</li>
+</ul>
</div>
+<div id="_tabs_3_xml--panel" class="tabpanel" aria-labelledby="_tabs_3_xml">
<div class="listingblock">
<div class="content">
<pre class="highlightjs highlight"><code class="language-xml hljs"
data-lang="xml"><?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-
- <AsyncWaitStrategyFactory
- class="my.custom.AsyncWaitStrategyFactory" />
-
- <Appenders>
- <File name="MyFile" fileName="logs/app.log">
- <PatternLayout pattern="%d %p %c{1.} [%t] %m%n" />
- </File>
- </Appenders>
- <Loggers>
- <AsyncRoot level="info">
- <AppenderRef ref="MyFile"/>
- </AsyncRoot>
- </Loggers>
+<Configuration xmlns="https://logging.apache.org/xml/ns"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="
+ https://logging.apache.org/xml/ns
+
https://logging.apache.org/xml/ns/log4j-config-2.xsd">
+ <AsyncWaitStrategyFactory
class="com.example.AsyncWaitStrategyFactory"/>
</Configuration></code></pre>
</div>
</div>
-<div class="paragraph">
-<p>The specified class must implement the
-<code>org.apache.logging.log4j.core.async.AsyncWaitStrategyFactory</code>
interface, which is defined as follows:</p>
</div>
+<div id="_tabs_3_json--panel" class="tabpanel" aria-labelledby="_tabs_3_json">
<div class="listingblock">
<div class="content">
-<pre class="highlightjs highlight"><code class="language-java hljs"
data-lang="java">public interface AsyncWaitStrategyFactory {
- /**
- * Returns a non-null implementation of the LMAX Disruptor's WaitStrategy
interface.
- * This WaitStrategy will be used by Log4j Async Loggers and Async
LoggerConfigs.
- *
- * @return the WaitStrategy instance to be used by Async Loggers and Async
LoggerConfigs
- */
- WaitStrategy createWaitStrategy();
+<pre class="highlightjs highlight"><code class="language-json hljs"
data-lang="json">{
+ "Configuration": {
+ "AsyncWaitStrategyFactor": {
+ "class": "com.example.AsyncWaitStrategyFactory"
+ }
+ }
}</code></pre>
</div>
</div>
-<div class="paragraph">
-<p>The specified class must also have a public no-argument constructor; Log4j
will instantiate an instance of the specified factory class and use this
factory to create the WaitStrategy used by all Async Loggers.</p>
</div>
-<div class="paragraph">
-<p>WaitStrategy-related system properties are ignored if a
<code>AsyncWaitStrategyFactory</code> is configured.</p>
+<div id="_tabs_3_yaml--panel" class="tabpanel" aria-labelledby="_tabs_3_yaml">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-yaml hljs"
data-lang="yaml">Configuration:
+ AsyncWaitStrategyFactory:
+ class: "com.example.AsyncWaitStrategyFactory"</code></pre>
</div>
</div>
</div>
-<div class="sect1">
-<h2 id="Location"><a class="anchor" href="#Location"></a>Location, location,
location…​</h2>
-<div class="sectionbody">
-<div class="paragraph">
-<p>If one of the layouts is configured with a location-related attribute like
HTML <a href="layouts.html#HtmlLocationInfo" class="xref
page">locationInfo</a>, or one of the patterns <a
href="layouts.html#PatternClass" class="xref page">%C or $class</a>,
-<a href="layouts.html#PatternFile" class="xref page">%F or %file</a>,
-<a href="layouts.html#PatternLocation" class="xref page">%l or %location</a>,
-<a href="layouts.html#PatternLine" class="xref page">%L or %line</a>,
-<a href="layouts.html#PatternMethod" class="xref page">%M or %method</a>,
Log4j will take a snapshot of the stack, and walk the stack trace to find the
location information.</p>
+<div id="_tabs_3_java_properties--panel" class="tabpanel"
aria-labelledby="_tabs_3_java_properties">
+<div class="listingblock">
+<div class="content">
+<pre class="highlightjs highlight"><code class="language-properties hljs"
data-lang="properties">strategy.type = AsyncWaitStrategyFactory
+strategy.class = com.exampleAsyncWaitStrategyFactory</code></pre>
+</div>
+</div>
</div>
-<div class="paragraph">
-<p>This is an expensive operation: 1.3 - 5 times slower for synchronous
loggers.
-Synchronous loggers wait as long as possible before they take this stack
snapshot.
-If no location is required, the snapshot will never be taken.</p>
</div>
-<div class="paragraph">
-<p>However, asynchronous loggers need to make this decision before passing the
log message to another thread; the location information will be lost after that
point.
-The performance impact of taking a stack trace snapshot is even higher for
asynchronous loggers:
-logging with location is 30-100 times slower than without location.
-For this reason, asynchronous loggers and asynchronous appenders do not
include location information by default.</p>
</div>
+</div>
+</div>
+<div class="sect1">
+<h2 id="Location"><a class="anchor" href="#Location"></a>Location
information</h2>
+<div class="sectionbody">
<div class="paragraph">
-<p>You can override the default behaviour in your logger or asynchronous
appender configuration by specifying <code>includeLocation="true"</code>.</p>
+<p><a href="layouts.html#LocationInformation" class="xref page">Computing the
location information (i.e., the caller class, method, file, and line number) of
a log event is an expensive operation.</a>
+The impact on asynchronous loggers and appenders is even higher, since the
component must decide whether to compute it or not <strong>before</strong>
crossing the asynchronous barrier.
+Hence, the location information is disabled by default for asynchronous
loggers and appenders.
+In order to enable it for a certain logger, set its <a
href="configuration.html#logger-attributes-includeLocation" class="xref
page"><code>includeLocation</code></a> attribute to <code>true</code>.</p>
</div>
</div>
</div>
<div class="sect1">
-<h2 id="UnderTheHood"><a class="anchor" href="#UnderTheHood"></a>Under The
Hood</h2>
+<h2 id="exception-handler"><a class="anchor"
href="#exception-handler"></a>Exception handler</h2>
<div class="sectionbody">
<div class="paragraph">
-<p>Asynchronous Loggers are implemented using the
-<a href="https://lmax-exchange.github.io/disruptor/">LMAX Disruptor</a>
inter-thread messaging library.
-From the LMAX web site:</p>
+<p>In order to handle exceptions that occur on the asynchronous thread, you
can configure a custom
+<a
href="https://lmax-exchange.github.io/disruptor/javadoc/com.lmax.disruptor/com/lmax/disruptor/ExceptionHandler.html">ExceptionHandler<T></a>.</p>
</div>
-<div class="quoteblock">
-<blockquote>
<div class="paragraph">
-<p>…​using queues to pass data between stages of the system was
-introducing latency, so we focused on optimising this area.
-The Disruptor is the result of our research and testing.
-We found that cache misses at the CPU-level, and locks requiring kernel
arbitration are both extremely costly, so we created a framework which has
"mechanical sympathy" for the hardware it’s running on, and that’s
lock-free.</p>
+<p>The exact type of handler depends on the configuration mode:</p>
</div>
-</blockquote>
+<div class="dlist">
+<dl>
+<dt class="hdlist1">Full asynchronous</dt>
+<dd>
+<div class="paragraph">
+<p>If all the loggers are asynchronous you need to:</p>
</div>
+<div class="ulist">
+<ul>
+<li>
+<p>implement an
+<a
href="../javadoc/log4j-async-logger/org/apache/logging/log4j/async/logger/AsyncLoggerExceptionHandler.html"><code>AsyncLoggerExceptionHandler</code></a></p>
+</li>
+<li>
+<p>set its fully qualified class name as value of the
+<a href="systemproperties.html#log4j.async.logger.exceptionHandler"
class="xref page"><code>log4j.async.logger.exceptionHandler</code></a>
+configuration property.</p>
+</li>
+</ul>
+</div>
+</dd>
+<dt class="hdlist1">Mixed synchronous/asynchronous</dt>
+<dd>
<div class="paragraph">
-<p>LMAX Disruptor internal performance comparisons with
-<code>java.util.concurrent.ArrayBlockingQueue</code> can be found
-<a
href="https://github.com/LMAX-Exchange/disruptor/wiki/Performance-Results">here</a>.</p>
+<p>If you use a mix of synchronous and asynchronous loggers you need to:</p>
+</div>
+<div class="ulist">
+<ul>
+<li>
+<p>implement a
+<a
href="../javadoc/log4j-async-logger/org/apache/logging/log4j/async/logger/AsyncLoggerConfigExceptionHandler.html"><code>AsyncLoggerConfigExceptionHandler</code></a></p>
+</li>
+<li>
+<p>set its fully qualified class name as value of the
+<a href="systemproperties.html#log4j.async.logger.configExceptionHandler"
class="xref page"><code>log4j.async.logger.configExceptionHandler</code></a>
+configuration property.</p>
+</li>
+</ul>
+</div>
+</dd>
+</dl>
</div>
</div>
</div>
diff --git a/manual/performance.html b/manual/performance.html
index 9db8f71abc..e451b7c3bc 100644
--- a/manual/performance.html
+++ b/manual/performance.html
@@ -591,13 +591,13 @@ This can partly be alleviated by configuring an exception
handler, but this may
<p>Most
<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/Message.html"><code>Message</code></a>
implementations take a snapshot of the formatted message on the calling thread
(cf.
-<a href="systemproperties.html#log4j2.formatMsgAsync" class="xref
page"><code>log4j2.formatMsgAsync</code></a>).
+<a href="systemproperties.html#log4j.async.formatMessagesInBackground"
class="xref page"><code>log4j.async.formatMessagesInBackground</code></a>).
The log message will not change even if the arguments of the logging call are
modified later.</p>
<div class="paragraph">
<p>There are some exceptions to this rule.
-<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/MapMessage.html"><code>MapMessage</code></a>
+<a
href="https://logging.apache.org/log4j/2.x/manual/messages.html#MapMessage"><code>MapMessage</code></a>
and
-<a
href="../javadoc/log4j-api/org/apache/logging/log4j/message/StructuredDataMessage.html"><code>StructuredDataMessage</code></a>
+<a
href="https://logging.apache.org/log4j/2.x/manual/messages.html#StructuredDataMessage"><code>StructuredDataMessage</code></a>
for example are mutable by design: fields can be added to these messages after
the message object was created.
These messages should not be modified after they are logged with asynchronous
loggers or asynchronous appenders.</p>
</div>
diff --git a/plugin-reference.html b/plugin-reference.html
index a3cd5309e9..34cc3e0958 100644
--- a/plugin-reference.html
+++ b/plugin-reference.html
@@ -2557,7 +2557,12 @@ This attribute is ignored if <code>immediateFlush</code>
is set to <code>true</c
<tr>
<td class="tableblock halign-left valign-top"><p
class="tableblock"><code>Property</code></p></td>
<td class="tableblock halign-left valign-top"><p class="tableblock"><code><a
href="#org-apache-logging-log4j_log4j-core_org-apache-logging-log4j-core-config-Property">Property</a>?</code></p></td>
-<td class="tableblock halign-left valign-top"><div class="content"></div></td>
+<td class="tableblock halign-left valign-top"><div class="content"><div
class="paragraph">
+<p>A generic list of key/value properties</p>
+</div>
+<div class="paragraph">
+<p>The meaning of these properties depends on the component.</p>
+</div></div></td>
</tr>
<tr>
<td class="tableblock halign-left valign-top"></td>
diff --git a/sitemap.xml b/sitemap.xml
index 9d5d5a4942..ed879c61b0 100644
--- a/sitemap.xml
+++ b/sitemap.xml
@@ -2,186 +2,186 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://logging.apache.org/log4j/3.x/articles.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/development.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/download.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/faq.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/getting-started.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/index.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/javadoc.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-1.2-api.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-api.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-docker.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-flume-ng.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-iostreams.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-jpl.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-jul.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-slf4j-impl.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-slf4j2-impl.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-spring-cloud-config-client.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-to-jul.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/log4j-to-slf4j.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/api.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/appenders.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/architecture.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/async.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/cloud.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/configuration.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/customconfig.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/dependencyinjection.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/extending.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/filters.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/garbagefree.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/index.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/installation.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/jmx.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/json-template-layout.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/layouts.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/logsep.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/lookups.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/migration.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/performance.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/plugins.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/scripts.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/systemproperties.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/manual/usage.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/plugin-reference.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/release-notes.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
<url>
<loc>https://logging.apache.org/log4j/3.x/thanks.html</loc>
-<lastmod>2024-05-28T13:19:19.044Z</lastmod>
+<lastmod>2024-05-28T13:49:27.912Z</lastmod>
</url>
</urlset>