You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by ma...@apache.org on 2018/04/06 22:19:51 UTC

[1/5] logging-log4j2 git commit: Use more consistent page titles

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 332383104 -> 0c47af7f2


Use more consistent page titles


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/1b85a525
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/1b85a525
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/1b85a525

Branch: refs/heads/master
Commit: 1b85a525c5b806c5e0ecdbf17445aa3c91dbfe67
Parents: 3323831
Author: Matt Sicker <bo...@gmail.com>
Authored: Fri Apr 6 16:43:55 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Fri Apr 6 16:43:55 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/thanks.adoc | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1b85a525/src/site/asciidoc/thanks.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/thanks.adoc b/src/site/asciidoc/thanks.adoc
index 4c94cd2..a254e44 100644
--- a/src/site/asciidoc/thanks.adoc
+++ b/src/site/asciidoc/thanks.adoc
@@ -14,7 +14,7 @@
     See the License for the specific language governing permissions and
     limitations under the License.
 ////
-= Log4j 2 Project Thanks
+= Project Thanks
 
 Log4j 2 is a successful project because of the large and diverse
 community that contributes to it.


[5/5] logging-log4j2 git commit: LOG4J2-1802: Convert appenders manual to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert appenders manual to asciidoc


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/0c47af7f
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/0c47af7f
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/0c47af7f

Branch: refs/heads/master
Commit: 0c47af7f22b4ab7b720d857fc482ef1fc6fabf4e
Parents: 8af36c9
Author: Matt Sicker <bo...@gmail.com>
Authored: Fri Apr 6 17:19:43 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Fri Apr 6 17:19:43 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/appenders.adoc | 4483 +++++++++++++++++++++
 src/site/xdoc/manual/appenders.xml      | 5400 --------------------------
 2 files changed, 4483 insertions(+), 5400 deletions(-)
----------------------------------------------------------------------



[2/5] logging-log4j2 git commit: Add asciidoc tables to striped table hack

Posted by ma...@apache.org.
Add asciidoc tables to striped table hack


Project: http://git-wip-us.apache.org/repos/asf/logging-log4j2/repo
Commit: http://git-wip-us.apache.org/repos/asf/logging-log4j2/commit/8af36c9d
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/8af36c9d
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/8af36c9d

Branch: refs/heads/master
Commit: 8af36c9d10a1bd17f1267f2d2f198c5bcf66f052
Parents: 1b85a52
Author: Matt Sicker <bo...@gmail.com>
Authored: Fri Apr 6 17:19:18 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Fri Apr 6 17:19:18 2018 -0500

----------------------------------------------------------------------
 src/site/resources/js/site.js | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/8af36c9d/src/site/resources/js/site.js
----------------------------------------------------------------------
diff --git a/src/site/resources/js/site.js b/src/site/resources/js/site.js
index 50bff12..902a0dd 100644
--- a/src/site/resources/js/site.js
+++ b/src/site/resources/js/site.js
@@ -61,7 +61,7 @@ $(document).ready(function() {
 	
 	// Hack to add default visuals to tables
 	$('table').each(function() {
-		if ($(this).hasClass('bodyTable')) {
+		if ($(this).hasClass('bodyTable') || $(this).hasClass('tableblock')) {
 			
 			// Remove border="1" which is added by maven
 			this.border = 0;


[3/5] logging-log4j2 git commit: LOG4J2-1802: Convert appenders manual to asciidoc

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0c47af7f/src/site/xdoc/manual/appenders.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/appenders.xml b/src/site/xdoc/manual/appenders.xml
deleted file mode 100644
index caabe2d..0000000
--- a/src/site/xdoc/manual/appenders.xml
+++ /dev/null
@@ -1,5400 +0,0 @@
-<?xml version="1.0"?>
-<!--
-    Licensed to the Apache Software Foundation (ASF) under one or more
-    contributor license agreements.  See the NOTICE file distributed with
-    this work for additional information regarding copyright ownership.
-    The ASF licenses this file to You under the Apache License, Version 2.0
-    (the "License"); you may not use this file except in compliance with
-    the License.  You may obtain a copy of the License at
-
-         http://www.apache.org/licenses/LICENSE-2.0
-
-    Unless required by applicable law or agreed to in writing, software
-    distributed under the License is distributed on an "AS IS" BASIS,
-    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-    See the License for the specific language governing permissions and
-    limitations under the License.
--->
-
-<document xmlns="http://maven.apache.org/XDOC/2.0"
-          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-          xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
-    <properties>
-        <title>Log4j 2 Appenders</title>
-        <author email="rgoers@apache.org">Ralph Goers</author>
-        <author email="ggrgeory@apache.org">Gary Gregory</author>
-        <author email="nickwilliams@apache.org">Nick Williams</author>
-        <author email="mattsicker@apache.org">Matt SIcker</author>
-    </properties>
-
-    <body>
-      <section name="Appenders">
-        <p>
-          Appenders are responsible for delivering LogEvents to their destination. Every Appender must
-          implement the <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html">Appender</a>
-          interface. Most Appenders will extend
-          <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/appender/AbstractAppender.html">AbstractAppender</a>
-          which adds <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/LifeCycle.html">Lifecycle</a>
-          and <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/filter/Filterable.html">Filterable</a>
-          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.
-        </p>
-        <p>
-          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 <a href="layouts.html">layout</a>. 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.
-        </p>
-        <p>
-          Appenders always have a name so that they can be referenced from Loggers.
-        </p>
-        <p>
-          In the tables below, the "Type" column corresponds to the Java type expected. For non-JDK classes, these
-          should usually be in <a href="../log4j-core/apidocs/index.html">Log4j Core</a> unless otherwise noted.
-        </p>
-        <a name="AsyncAppender"/>
-        <subsection name="AsyncAppender">
-          <p>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.</p>
-          <p>
-            By default, AsyncAppender uses
-            <a class="javadoc" href="http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html">java.util.concurrent.ArrayBlockingQueue</a>
-            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
-            <a href="../performance.html#asyncLogging">tests showed</a>
-            performance may become worse when more threads are logging concurrently.
-            Consider using <a href="async.html">lock-free Async Loggers</a> for optimal performance.
-          </p>
-          <table>
-            <caption align="top">AsyncAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>AppenderRef</td>
-              <td>String</td>
-              <td>The name of the Appenders to invoke asynchronously. Multiple AppenderRef
-                elements can be configured.</td>
-            </tr>
-            <tr>
-              <td>blocking</td>
-              <td>boolean</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>shutdownTimeout</td>
-              <td>integer</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>bufferSize</td>
-              <td>integer</td>
-              <td>Specifies the maximum number of events that can be queued. The default is 1024. Note that when using a
-                disruptor-style <tt>BlockingQueue</tt>, this buffer size must be a power of 2.
-                <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 behavious is determined by the
-                  <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html">AsyncQueueFullPolicy</a>.
-                </p>
-              </td>
-            </tr>
-            <tr>
-              <td>errorRef</td>
-              <td>String</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-                may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>includeLocation</td>
-              <td>boolean</td>
-              <td>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".</td>
-            </tr>
-            <tr>
-              <td>BlockingQueueFactory</td>
-              <td>BlockingQueueFactory</td>
-              <td>This element overrides what type of <tt>BlockingQueue</tt> to use. See
-                <a href="#BlockingQueueFactory">below documentation</a> for more details.</td>
-            </tr>
-          </table>
-          <p>
-            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
-            <a href="configuration.html#log4j2.AsyncQueueFullPolicy"><tt>log4j2.AsyncQueueFullPolicy</tt> and
-              <tt>log4j2.DiscardThreshold</tt></a>.
-          </p>
-          <p>
-            A typical AsyncAppender configuration might look like:
-          </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-          <p>
-            <a name="BlockingQueueFactory"/>
-            Starting in Log4j 2.7, a custom implementation of <tt>BlockingQueue</tt> or <tt>TransferQueue</tt> can be
-            specified using a
-            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/BlockingQueueFactory.html">BlockingQueueFactory</a>
-            plugin. To override the default <tt>BlockingQueueFactory</tt>, specify the plugin inside an
-            <code><![CDATA[<Async/>]]></code> element like so:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<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>]]></pre>
-          <p>
-            Log4j ships with the following implementations:
-          </p>
-          <table>
-            <caption align="top">BlockingQueueFactory Implementations</caption>
-            <tr>
-              <th>Plugin Name</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>ArrayBlockingQueue</td>
-              <td>
-                This is the default implementation that uses
-                <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html">ArrayBlockingQueue</a>.
-              </td>
-            </tr>
-            <tr>
-              <td>DisruptorBlockingQueue</td>
-              <td>
-                This uses the <a href="https://github.com/conversant/disruptor">Conversant Disruptor</a> implementation
-                of <tt>BlockingQueue</tt>. This plugin takes a single optional attribute, <tt>spinPolicy</tt>, which
-                corresponds to
-                <!-- TODO: this needs performance charts and links added -->
-              </td>
-            </tr>
-            <tr>
-              <td>JCToolsBlockingQueue</td>
-              <td>
-                This uses <a href="https://jctools.github.io/JCTools/">JCTools</a>, specifically the
-                <abbr title="multiple producer single consumer">MPSC</abbr> bounded lock-free queue.
-                <!-- TODO: this need performance charts and links added -->
-              </td>
-            </tr>
-            <tr>
-              <td>LinkedTransferQueue</td>
-              <td>
-                This uses the new in Java 7 implementation
-                <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedTransferQueue.html">LinkedTransferQueue</a>.
-                Note that this queue does not use the <tt>bufferSize</tt> configuration attribute from AsyncAppender as
-                <tt>LinkedTransferQueue</tt> does not support a maximum capacity.
-                <!-- TODO: this needs performance charts and links added -->
-              </td>
-            </tr>
-          </table>
-        </subsection>
-        <a name="CassandraAppender"/>
-        <subsection name="CassandraAppender">
-          <p>
-            The CassandraAppender writes its output to an <a href="https://cassandra.apache.org/">Apache Cassandra</a>
-            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 <a href="layouts.html">StringLayout</a> (e.g., a
-            <a href="layouts.html#PatternLayout">PatternLayout</a>) along with an optional conversion type, or only
-            a conversion type for <code>org.apache.logging.log4j.spi.ThreadContextMap</code> or
-            <code>org.apache.logging.log4j.spi.ThreadContextStack</code> to store the <a href="thread-context.html">MDC or NDC</a>
-            in a map or list column respectively. A conversion type compatible with <code>java.util.Date</code> will
-            use the log event timestamp converted to that type (e.g., use <code>java.util.Date</code> to fill a
-            <code>timestamp</code> column type in Cassandra).
-          </p>
-          <table>
-            <caption align="top">CassandraAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>batched</td>
-              <td>boolean</td>
-              <td>Whether or not to use batch statements to write log messages to Cassandra. By default, this is <code>false</code>.</td>
-            </tr>
-            <tr>
-              <td>batchType</td>
-              <td><a href="http://docs.datastax.com/en/drivers/java/3.0/com/datastax/driver/core/BatchStatement.Type.html">BatchStatement.Type</a></td>
-              <td>The batch type to use when using batched writes. By default, this is <code>LOGGED</code>.</td>
-            </tr>
-            <tr>
-              <td>bufferSize</td>
-              <td>int</td>
-              <td>The number of log messages to buffer or batch before writing. By default, no buffering is done.</td>
-            </tr>
-            <tr>
-              <td>clusterName</td>
-              <td>String</td>
-              <td>The name of the Cassandra cluster to connect to.</td>
-            </tr>
-            <tr>
-              <td>columns</td>
-              <td>ColumnMapping[]</td>
-              <td>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
-                <code>String</code>. If the configured type is assignment-compatible with
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/util/ReadOnlyStringMap.html">ReadOnlyStringMap</a>
-                /
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextMap.html">ThreadContextMap</a>
-                or
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextStack.html">ThreadContextStack</a>,
-                then that column will be populated with the MDC or NDC respectively. If the configured type is
-                assignment-compatible with <code>java.util.Date</code>, then the log timestamp will be converted to
-                that configured date type. If a <code>literal</code> attribute is given, then its value will be used as
-                is in the <code>INSERT</code> query without any escaping. Otherwise, the layout or pattern specified
-                will be converted into the configured type and stored in that column.
-              </td>
-            </tr>
-            <tr>
-              <td>contactPoints</td>
-              <td>SocketAddress[]</td>
-              <td>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, <code>localhost:9042</code> will be used.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be used
-                by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>keyspace</td>
-              <td>String</td>
-              <td>The name of the keyspace containing the table that log messages will be written to.</td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>password</td>
-              <td>String</td>
-              <td>The password to use (along with the username) to connect to Cassandra.</td>
-            </tr>
-            <tr>
-              <td>table</td>
-              <td>String</td>
-              <td>The name of the table to write log messages to.</td>
-            </tr>
-            <tr>
-              <td>useClockForTimestampGenerator</td>
-              <td>boolean</td>
-              <td>Whether or not to use the configured <code>org.apache.logging.log4j.core.time.Clock</code> as a
-                <a class="javadoc" href="http://docs.datastax.com/en/drivers/java/3.0/com/datastax/driver/core/TimestampGenerator.html">TimestampGenerator</a>.
-                By default, this is <code>false</code>.</td>
-            </tr>
-            <tr>
-              <td>username</td>
-              <td>String</td>
-              <td>The username to use to connect to Cassandra. By default, no username or password is used.</td>
-            </tr>
-            <tr>
-              <td>useTls</td>
-              <td>boolean</td>
-              <td>Whether or not to use TLS/SSL to connect to Cassandra. This is <code>false</code> by default.</td>
-            </tr>
-          </table>
-          <p>
-            Here is an example CassandraAppender configuration:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<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>
-]]></pre>
-          <p>
-            This example configuration uses the following table schema:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-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>
-);
-]]></pre>
-        </subsection>
-        <a name="ConsoleAppender"/>
-        <subsection name="ConsoleAppender">
-          <p>
-            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.
-          </p>
-          <table>
-            <caption align="top">ConsoleAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-              may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>layout</td>
-              <td>Layout</td>
-              <td>The Layout to use to format the LogEvent. If no layout is supplied the default pattern layout
-              of "%m%n" will be used.</td>
-            </tr>
-            <tr>
-              <td>follow</td>
-              <td>boolean</td>
-              <td>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 <code>direct</code>.</td>
-            </tr>
-            <tr>
-              <td>direct</td>
-              <td>boolean</td>
-              <td>Write directly to <code>java.io.FileDescriptor</code> and bypass <code>java.lang.System.out/.err</code>.
-                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 <code>follow</code>. Output will not respect
-                <code>java.lang.System.setOut()/.setErr()</code> and may get intertwined with other output to
-                <code>java.lang.System.out/.err</code> in a multi-threaded application.
-                <i>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.</i></td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>target</td>
-              <td>String</td>
-              <td>Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is "SYSTEM_OUT".</td>
-            </tr>
-          </table>
-          <p>
-            A typical Console configuration might look like:
-          </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-        </subsection>
-        <a name="FailoverAppender"/>
-        <subsection name="FailoverAppender">
-          <p>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.</p>
-          <table>
-            <caption align="top">FailoverAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-              may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>primary</td>
-              <td>String</td>
-              <td>The name of the primary Appender to use.</td>
-            </tr>
-            <tr>
-              <td>failovers</td>
-              <td>String[]</td>
-              <td>The names of the secondary Appenders to use.</td>
-            </tr>
-
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>retryIntervalSeconds</td>
-              <td>integer</td>
-              <td>The number of seconds that should pass before retrying the primary Appender. The default is 60.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead.</td>
-            </tr>
-            <tr>
-              <td>target</td>
-              <td>String</td>
-              <td>Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is "SYSTEM_ERR".</td>
-            </tr>
-          </table>
-          <p>
-            A Failover configuration might look like:
-          </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-        </subsection>
-        <a name="FileAppender"/>
-        <subsection name="FileAppender">
-          <p>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.</p>
-          <table>
-            <caption align="top">FileAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>append</td>
-              <td>boolean</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>bufferedIO</td>
-              <td>boolean</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>bufferSize</td>
-              <td>int</td>
-              <td>When bufferedIO is true, this is the buffer size, the default is 8192 bytes.</td>
-            </tr>
-            <tr>
-              <td>createOnDemand</td>
-              <td>boolean</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-              may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>fileName</td>
-              <td>String</td>
-              <td>The name of the file to write to. If the file, or any of its parent directories, do not exist,
-                they will be created.</td>
-            </tr>
-            <tr>
-              <td>immediateFlush</td>
-              <td>boolean</td>
-              <td><p>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.</p>
-                <p>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.</p>
-              </td>
-            </tr>
-            <tr>
-              <td>layout</td>
-              <td>Layout</td>
-              <td>The Layout to use to format the LogEvent. If no layout is supplied the default pattern layout
-                of "%m%n" will be used.</td>
-            </tr>
-            <tr>
-              <td>locking</td>
-              <td>boolean</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>filePermissions</td>
-              <td>String</td>
-              <td><p>File attribute permissions in POSIX format to apply whenever the file is created.</p>
-                  <p>Underlying files system shall support <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html">POSIX</a> file attribute view.</p>
-              <p>Examples: rw------- or rw-rw-rw- etc...</p></td>
-            </tr>
-            <tr>
-              <td>fileOwner</td>
-              <td>String</td>
-              <td><p>File owner to define whenever the file is created.</p>
-                  <p>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 <a href="http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html">_POSIX_CHOWN_RESTRICTED</a> is in effect for path.</p>
-                  <p>Underlying files system shall support file <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html">owner</a> attribute view.</p>
-              </td>
-            </tr>
-            <tr>
-              <td>fileGroup</td>
-              <td>String</td>
-              <td><p>File group to define whenever the file is created.</p>
-                  <p>Underlying files system shall support <a class="javadoc" href="https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html">POSIX</a> file attribute view.</p>
-              </td>
-            </tr>
-          </table>
-          <p>
-            Here is a sample File configuration:
-          </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-        </subsection>
-        <a name="FlumeAppender"/>
-        <subsection name="FlumeAppender">
-          <p><i>This is an optional component supplied in a separate jar.</i></p>
-          <p><a href="http://flume.apache.org/index.html">Apache Flume</a> 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.</p>
-          <p>
-            The Flume Appender supports three modes of operation.
-          </p>
-            <ol>
-              <li>It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured
-              with an Avro Source.</li>
-              <li>It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing.</li>
-              <li>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.</li>
-            </ol>
-          <p>
-            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.
-          </p>
-          <table>
-            <caption align="top">FlumeAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>agents</td>
-              <td>Agent[]</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>agentRetries</td>
-              <td>integer</td>
-              <td>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).</td>
-            </tr>
-            <tr>
-              <td>batchSize</td>
-              <td>integer</td>
-              <td>Specifies the number of events that should be sent as a batch. The default is 1. <i>This
-                parameter only applies to the Flume Appender.</i></td>
-            </tr>
-            <tr>
-              <td>compress</td>
-              <td>boolean</td>
-              <td>When set to true the message body will be compressed using gzip</td>
-            </tr>
-            <tr>
-              <td>connectTimeoutMillis</td>
-              <td>integer</td>
-              <td>The number of milliseconds Flume will wait before timing out the connection.</td>
-            </tr>
-            <tr>
-              <td>dataDir</td>
-              <td>String</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-              may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>eventPrefix</td>
-              <td>String</td>
-              <td>The character string to prepend to each event attribute in order to distinguish it from MDC attributes.
-                The default is an empty string.</td>
-            </tr>
-            <tr>
-              <td>flumeEventFactory</td>
-              <td>FlumeEventFactory</td>
-              <td>Factory that generates the Flume events from Log4j events. The default factory is the
-                FlumeAvroAppender itself.</td>
-            </tr>
-            <tr>
-              <td>layout</td>
-              <td>Layout</td>
-              <td>The Layout to use to format the LogEvent. If no layout is specified RFC5424Layout will be used.</td>
-            </tr>
-            <tr>
-              <td>lockTimeoutRetries</td>
-              <td>integer</td>
-              <td>The number of times to retry if a LockConflictException occurs while writing to Berkeley DB. The
-                default is 5.</td>
-            </tr>
-            <tr>
-              <td>maxDelayMillis</td>
-              <td>integer</td>
-              <td>The maximum number of milliseconds to wait for batchSize events before publishing the batch.</td>
-            </tr>
-            <tr>
-              <td>mdcExcludes</td>
-              <td>String</td>
-              <td>A comma separated list of mdc keys that should be excluded from the FlumeEvent. This is mutually
-                exclusive with the mdcIncludes attribute.</td>
-            </tr>
-            <tr>
-              <td>mdcIncludes</td>
-              <td>String</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>mdcRequired</td>
-              <td>String</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>mdcPrefix</td>
-              <td>String</td>
-              <td>A string that should be prepended to each MDC key in order to distinguish it from event attributes.
-                The default string is "mdc:".</td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>properties</td>
-              <td>Property[]</td>
-              <td><p>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.</p>
-                <p>When used to configure in Persistent mode the valid properties are:</p>
-                <ol>
-                  <li>"keyProvider" to specify the name of the plugin to provide the secret key for encryption.</li>
-                </ol>
-              </td>
-            </tr>
-            <tr>
-              <td>requestTimeoutMillis</td>
-              <td>integer</td>
-              <td>The number of milliseconds Flume will wait before timing out the request.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>type</td>
-              <td>enumeration</td>
-              <td>One of "Avro", "Embedded", or "Persistent" to indicate which variation of the Appender is desired.</td>
-            </tr>
-          </table>
-            <p>
-              A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
-              compresses the body, and formats the body using the RFC5424Layout:
-            </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-          <p>
-            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:
-          </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-          <p>
-            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.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-          <p>
-            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.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-        </subsection>
-        <a name="JDBCAppender"/>
-        <subsection name="JDBCAppender">
-          <p>
-             As of Log4j 2.11.0, JDBC support has moved from the existing module <code>logj-core</code> to the new module <code>log4j-jdbc</code>.
-          </p>
-          <p>The JDBCAppender writes log events to a relational database table using standard JDBC. It can be configured
-            to obtain JDBC connections using a JNDI <code>DataSource</code> or a custom factory method. Whichever
-            approach you take, it <strong><em>must</em></strong> be backed by a connection pool. Otherwise, logging
-            performance will suffer greatly. If batch statements are supported by the configured JDBC driver and a
-            <code>bufferSize</code> 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 <code>ColumnConfig</code>
-            style that only allows strings and timestamps, and the new <code>ColumnMapping</code> plugin that uses Log4j's
-            built-in type conversion to allow for more data types (this is the same plugin as in the
-            <a href="#CassandraAppender">Cassandra Appender</a>).</p>
-          <p>
-            To get off the ground quickly during development, an alternative to using a connection source based on 
-            JNDI is to use the non-pooling <code>DriverManager</code> connection source. This connection source uses 
-            a JDBC connection string, a user name, and a password. Optionally, you can also use properties.
-          </p>
-          <table>
-            <caption align="top">JDBCAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be
-                used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>bufferSize</td>
-              <td>int</td>
-              <td>If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
-                buffer reaches this size.</td>
-            </tr>
-            <tr>
-              <td>connectionSource</td>
-              <td>ConnectionSource</td>
-              <td><em>Required.</em> The connections source from which database connections should be retrieved.</td>
-            </tr>
-            <tr>
-              <td>tableName</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the database table to insert log events into.</td>
-            </tr>
-            <tr>
-              <td>columnConfigs</td>
-              <td>ColumnConfig[]</td>
-              <td><em>Required (and/or columnMappings).</em> Information about the columns that log event data should be inserted into and how
-                to insert that data. This is represented with multiple <code>&lt;Column&gt;</code> elements.</td>
-            </tr>
-            <tr>
-              <td>columnMappings</td>
-              <td>ColumnMapping[]</td>
-              <td><em>Required (and/or columnConfigs).</em> 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 <code>String</code>. If the configured type is
-                assignment-compatible with
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/util/ReadOnlyStringMap.html">ReadOnlyStringMap</a>
-                /
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextMap.html">ThreadContextMap</a>
-                or
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextStack.html">ThreadContextStack</a>,
-                then that column will be populated with the MDC or NDC respectively (this is database-specific how they
-                handle inserting a <code>Map</code> or <code>List</code> value). If the configured type is
-                assignment-compatible with <code>java.util.Date</code>, then the log timestamp will be converted to
-                that configured date type. If the configured type is assignment-compatible with <code>java.sql.Clob</code>
-                or <code>java.sql.NClob</code>, then the formatted event will be set as a Clob or NClob respectively
-                (similar to the traditional ColumnConfig plugin). If a <code>literal</code> attribute is given, then its
-                value will be used as is in the <code>INSERT</code> query without any escaping. Otherwise, the layout or
-                pattern specified will be converted into the configured type and stored in that column.
-              </td>
-            </tr>
-          </table>
-          <p>When configuring the JDBCAppender, you must specify a <code>ConnectionSource</code> implementation from
-            which the Appender gets JDBC connections. You must use exactly one of the following nested elements:</p>
-          <ul>
-            <li><a href="#JDBCDataSource"><code>&lt;DataSource&gt;</code></a>: Uses JNDI.</li>
-            <li><a href="#JDBCConnectionFactory"><code>&lt;ConnectionFactory&gt;</code></a>: Points to a class-method pair to provide JDBC connections.</li>
-            <li><a href="#JDBCDriverManager"><code>&lt;DriverManager&gt;</code></a>: A quick and dirty way to get off the ground, no connection pooling.</li>
-            <li><a href="#JDBCPoolingDriver"><code>&lt;PoolingDriver&gt;</code></a>: Uses Apache Commons DBCP to provide connection pooling.</li>
-          </ul>
-          <a name="JDBCDataSource"/>
-          <table>
-            <caption align="top">DataSource Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>jndiName</td>
-              <td>String</td>
-              <td><em>Required.</em> The full, prefixed JNDI name that the <code>javax.sql.DataSource</code> is bound
-                to, such as <code>java:/comp/env/jdbc/LoggingDatabase</code>. The <code>DataSource</code> must be backed
-                by a connection pool; otherwise, logging will be very slow.</td>
-            </tr>
-          </table>
-          <a name="JDBCConnectionFactory"/>
-          <table>
-            <caption align="top">ConnectionFactory Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>class</td>
-              <td>Class</td>
-              <td><em>Required.</em> The fully qualified name of a class containing a static factory method for
-                obtaining JDBC connections.</td>
-            </tr>
-            <tr>
-              <td>method</td>
-              <td>Method</td>
-              <td><em>Required.</em> The name of a static factory method for obtaining JDBC connections. This method
-                must have no parameters and its return type must be either <code>java.sql.Connection</code> or
-                <code>DataSource</code>. If the method returns <code>Connection</code>s, 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 <code>DataSource</code>, the <code>DataSource</code> will
-                only be retrieved once, and it must be backed by a connection pool for the same reasons.</td>
-            </tr>
-          </table>
-          <a name="JDBCDriverManager"/>
-          <table>
-            <caption align="top">DriverManager Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>connectionString</td>
-              <td>String</td>
-              <td><em>Required.</em> The driver-specific JDBC connection string.</td>
-            </tr>
-            <tr>
-              <td>userName</td>
-              <td>String</td>
-              <td>The database user name. You cannot specify both properties and a user name or password.</td>
-            </tr>
-            <tr>
-              <td>password</td>
-              <td>String</td>
-              <td>The database password. You cannot specify both properties and a user name or password.</td>
-            </tr>
-            <tr>
-              <td>driverClassName</td>
-              <td>String</td>
-              <td>The JDBC driver class name. Some old JDBC Driver can only be discovered by explicitly loading them by class name.</td>
-            </tr>
-            <tr>
-              <td>properties</td>
-              <td>Property[]</td>
-              <td>A list of properties. You cannot specify both properties and a user name or password.</td>
-            </tr>
-          </table>
-          <a name="JDBCPoolingDriver"/>
-          <table>
-            <caption align="top">PoolingDriver Parameters (Apache Commons DBCP)</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>DriverManager parameters</td>
-              <td>DriverManager parameters</td>
-              <td>This connection source inherits all parameter from the DriverManager connection source.</td>
-            </tr>
-            <tr>
-              <td>poolName</td>
-              <td>String</td>
-              <td>The pool name used to pool JDBC Connections. Defaults to <code>example</code>. You can use the JDBC 
-              connection string prefix <code>jdbc:apache:commons:dbcp:</code> followed by the pool name if you want 
-              to use a pooled connection elsewhere. For example: <code>jdbc:apache:commons:dbcp:example</code>.</td>
-            </tr>
-          </table>
-          <p>When configuring the JDBCAppender, use the nested <code>&lt;Column&gt;</code> 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 <code>PreparedStatement</code> to insert records without SQL injection vulnerability.</p>
-          <table>
-            <caption align="top">Column Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the database column.</td>
-            </tr>
-            <tr>
-              <td>pattern</td>
-              <td>String</td>
-              <td>Use this attribute to insert a value or values from the log event in this column using a
-                <code>PatternLayout</code> pattern. Simply specify any legal pattern in this attribute. Either this
-                attribute, <code>literal</code>, or <code>isEventTimestamp="true"</code> must be specified, but not more
-                than one of these.</td>
-            </tr>
-            <tr>
-              <td>literal</td>
-              <td>String</td>
-              <td>
-                <p>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: <code>literal="'Literal String'"</code>). This is especially
-                useful for databases that don't support identity columns. For example, if you are using Oracle you could
-                specify <code>literal="NAME_OF_YOUR_SEQUENCE.NEXTVAL"</code> to insert a unique ID in an ID column.
-                Either this attribute, <code>pattern</code>, or <code>isEventTimestamp="true"</code> must be specified,
-                but not more than one of these.
-                </p>
-              </td>
-            </tr>
-            <tr>
-              <td>parameter</td>
-              <td>String</td>
-              <td>
-                <p>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: 
-                </p>
-                <p>
-                  <code>&lt;ColumnMapping name="instant" parameter="TIMESTAMPADD('MILLISECOND', ?, TIMESTAMP '1970-01-01')"/></code>
-                </p>
-                <p>
-                  You can only specify one of <code>literal</code> or <code>parameter</code>.
-                </p>
-              </td>
-            </tr>
-            <tr>
-              <td>isEventTimestamp</td>
-              <td>boolean</td>
-              <td>Use this attribute to insert the event timestamp in this column, which should be a SQL datetime. The
-                value will be inserted as a <code>java.sql.Types.TIMESTAMP</code>. Either this attribute (equal to
-                <code>true</code>), <code>pattern</code>, or <code>isEventTimestamp</code> must be specified, but not
-                more than one of these.</td>
-            </tr>
-            <tr>
-              <td>isUnicode</td>
-              <td>boolean</td>
-              <td>This attribute is ignored unless <code>pattern</code> is specified. If <code>true</code> or omitted
-                (default), the value will be inserted as unicode (<code>setNString</code> or <code>setNClob</code>).
-                Otherwise, the value will be inserted non-unicode (<code>setString</code> or <code>setClob</code>).</td>
-            </tr>
-            <tr>
-              <td>isClob</td>
-              <td>boolean</td>
-              <td>This attribute is ignored unless <code>pattern</code> is specified. Use this attribute to indicate
-                that the column stores Character Large Objects (CLOBs). If <code>true</code>, the value will be inserted
-                as a CLOB (<code>setClob</code> or <code>setNClob</code>). If <code>false</code> or omitted (default),
-                the value will be inserted as a VARCHAR or NVARCHAR (<code>setString</code> or <code>setNString</code>).
-              </td>
-            </tr>
-          </table>
-          <table>
-            <caption align="top">ColumnMapping Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the database column.</td>
-            </tr>
-            <tr>
-              <td>pattern</td>
-              <td>String</td>
-              <td>Use this attribute to insert a value or values from the log event in this column using a
-                <code>PatternLayout</code> pattern. Simply specify any legal pattern in this attribute. Either this
-                attribute, <code>literal</code>, or <code>isEventTimestamp="true"</code> must be specified, but not more
-                than one of these.</td>
-            </tr>
-            <tr>
-              <td>literal</td>
-              <td>String</td>
-              <td>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: <code>literal="'Literal String'"</code>). This is especially
-                useful for databases that don't support identity columns. For example, if you are using Oracle you could
-                specify <code>literal="NAME_OF_YOUR_SEQUENCE.NEXTVAL"</code> to insert a unique ID in an ID column.
-                Either this attribute, <code>pattern</code>, or <code>isEventTimestamp="true"</code> must be specified,
-                but not more than one of these.</td>
-            </tr>
-            <tr>
-              <td>layout</td>
-              <td>Layout</td>
-              <td>The Layout to format the LogEvent.</td>
-            </tr>
-            <tr>
-              <td>type</td>
-              <td>String</td>
-              <td>Conversion type name, a fully-qualified class name.</td>
-            </tr>
-          </table>
-          <p>
-            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:
-          </p>
-
-            <pre class="prettyprint linenums lang-xml"><![CDATA[<?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>]]></pre>
-
-            <pre class="prettyprint linenums lang-xml"><![CDATA[<?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>]]></pre>
-            <pre class="prettyprint linenums lang-java"><![CDATA[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();
-    }
-}]]></pre>
-          <p>
-            This appender is <a href="messages.html#MapMessage">MapMessage</a>-aware.
-          </p>
-          <p>
-            The following configuration uses a <code>MessageLayout</code> to indicate that the Appender should match 
-            the keys of a <code>MapMessage</code> to the names of <code>ColumnMapping</code>s 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 <code>MapMessage</code> instead of values from <code>LogEvent</code>s.
-          </p>
-          <pre class="prettyprint linenums lang-xml"><![CDATA[<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>]]></pre>          
-        </subsection>
-        <a name="JMSAppender"/>
-        <!-- cool URLs don't change, so here are some old anchors -->
-        <a name="JMSQueueAppender"/>
-        <a name="JMSTopicAppender"/>
-        <subsection name="JMS Appender">
-          <p>
-             As of Log4j 2.11.0, JPA support has moved from the existing module <code>logj-core</code> to the new module <code>log4j-jms</code>.
-          </p>
-          <p>The JMS Appender sends the formatted log event to a JMS Destination.</p>
-          <p>
-            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 <code>&lt;JMSQueue/&gt;</code> or
-            <code>&lt;JMSTopic/&gt;</code> elements will continue to work with the new <code>&lt;JMS/&gt;</code>
-            configuration element.
-          </p>
-          <table>
-            <caption align="top">JMS Appender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Default</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>factoryBindingName</td>
-              <td>String</td>
-              <td><em>Required</em></td>
-              <td>The name to locate in the Context that provides the
-                <a class="javadoc" href="http://download.oracle.com/javaee/5/api/javax/jms/ConnectionFactory.html">ConnectionFactory</a>.
-                This can be any subinterface of <code>ConnectionFactory</code> as well.
-              </td>
-            </tr>
-            <tr>
-              <td>factoryName</td>
-              <td>String</td>
-              <td><em>Required</em></td>
-              <td>The fully qualified class name that should be used to define the Initial Context Factory as defined in
-                <a class="javadoc" href="http://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY">INITIAL_CONTEXT_FACTORY</a>.
-                If a factoryName is specified without a providerURL a warning message will be logged as this is
-                likely to cause problems.
-              </td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>null</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
-              may be used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>layout</td>
-              <td>Layout</td>
-              <td><em>Required</em></td>
-              <td>
-                The Layout to use to format the LogEvent.
-                <em>New since 2.9, in previous versions SerializedLayout was default.</em>
-              </td>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td><em>Required</em></td>
-              <td>The name of the Appender. </td>
-            </tr>
-            <tr>
-              <td>password</td>
-              <td>String</td>
-              <td>null</td>
-              <td>The password to use to create the JMS connection.</td>
-            </tr>
-            <tr>
-              <td>providerURL</td>
-              <td>String</td>
-              <td><em>Required</em></td>
-              <td>The URL of the provider to use as defined by
-                <a class="javadoc" href="http://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#PROVIDER_URL">PROVIDER_URL</a>.
-              </td>
-            </tr>
-            <tr>
-              <td>destinationBindingName</td>
-              <td>String</td>
-              <td><em>Required</em></td>
-              <td>
-                The name to use to locate the
-                <a class="javadoc" href="http://download.oracle.com/javaee/5/api/javax/jms/Destination.html">Destination</a>.
-                This can be a <code>Queue</code> or <code>Topic</code>, and as such, the attribute names
-                <code>queueBindingName</code> and <code>topicBindingName</code> are aliases to maintain compatibility
-                with the Log4j 2.0 JMS appenders.
-              </td>
-            </tr>
-            <tr>
-              <td>securityPrincipalName</td>
-              <td>String</td>
-              <td>null</td>
-              <td>The name of the identity of the Principal as specified by
-                <a class="javadoc" href="http://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL">SECURITY_PRINCIPAL</a>.
-                If a securityPrincipalName is specified without securityCredentials a warning message will be
-                logged as this is likely to cause problems.</td>
-            </tr>
-            <tr>
-              <td>securityCredentials</td>
-              <td>String</td>
-              <td>null</td>
-              <td>The security credentials for the principal as specified by
-                <a class="javadoc" href="http://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS">SECURITY_CREDENTIALS</a>.
-              </td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>true</td>
-              <td>When <code>true</code>, exceptions caught while appending events are
-                internally logged and then ignored. When <code>false</code> exceptions are propagated to the
-                caller. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>immediateFail</td>
-              <td>boolean</td>
-              <td>false</td>
-              <td>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.</td>
-            </tr>
-            <tr>
-              <td>reconnectIntervalMillis</td>
-              <td>long</td>
-              <td>5000</td>
-              <td>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 <code>ignoreExceptions</code> is
-                set to <code>false</code>). New in 2.9.</td>
-            </tr>
-            <tr>
-              <td>urlPkgPrefixes</td>
-              <td>String</td>
-              <td>null</td>
-              <td>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
-                <a class="javadoc" href="http://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#URL_PKG_PREFIXES">URL_PKG_PREFIXES</a>.
-              </td>
-            </tr>
-            <tr>
-              <td>userName</td>
-              <td>String</td>
-              <td>null</td>
-              <td>The user id used to create the JMS connection.</td>
-            </tr>
-          </table>
-          <p>
-            Here is a sample JMS Appender configuration:
-          </p>
-
-          <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-
-        <p>
-          To map your Log4j <code>MapMessage</code>s to JMS <code>javax.jms.MapMessage</code>s, set the
-          layout of the appender to <code>MessageLayout</code> with <code>&lt;MessageLayout /&gt;</code> (Since 2.9.):
-        </p>
-
-            <pre class="prettyprint linenums"><![CDATA[<?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>]]></pre>
-
-        </subsection>
-        <a name="JPAAppender"/>
-        <subsection name="JPAAppender">
-          <p>
-             As of Log4j 2.11.0, JPA support has moved from the existing module <code>logj-core</code> to the new module <code>log4j-jpa</code>.
-          </p>
-          <p>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
-            <code>org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity</code> (if you mostly want to
-            use the default mappings) and provide at least an <code>@Id</code> property, or
-            <code>org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity</code> (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.</p>
-          <table>
-            <caption align="top">JPAAppender Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the Appender.</td>
-            </tr>
-            <tr>
-              <td>ignoreExceptions</td>
-              <td>boolean</td>
-              <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
-                internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
-                caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
-                <a href="#FailoverAppender">FailoverAppender</a>.</td>
-            </tr>
-            <tr>
-              <td>filter</td>
-              <td>Filter</td>
-              <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be
-                used by using a CompositeFilter.</td>
-            </tr>
-            <tr>
-              <td>bufferSize</td>
-              <td>int</td>
-              <td>If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
-                buffer reaches this size.</td>
-            </tr>
-            <tr>
-              <td>entityClassName</td>
-              <td>String</td>
-              <td><em>Required.</em> The fully qualified name of the concrete LogEventWrapperEntity implementation that
-                has JPA annotations mapping it to a database table.</td>
-            </tr>
-            <tr>
-              <td>persistenceUnitName</td>
-              <td>String</td>
-              <td><em>Required.</em> The name of the JPA persistence unit that should be used for persisting log
-                events.</td>
-            </tr>
-          </table>
-          <p>
-            Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file,
-            the second is the <code>persistence.xml</code> file. EclipseLink is assumed here, but any JPA 2.1 or higher
-            provider will do. You should <em>always</em> create a <em>separate</em> persistence unit for logging, for
-            two reasons. First, <code>&lt;shared-cache-mode&gt;</code> <em>must</em> 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 <em>must</em> also contain <code>&lt;class&gt;</code> elements for all of the
-            <code>org.apache.logging.log4j.core.appender.db.jpa.converter</code> converter classes.
-          </p>
-
-            <pre class="prettyprint linenums lang-xml"><![CDATA[<?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>]]></pre>
-
-            <pre class="prettyprint linenums lang-xml"><![CDATA[<?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>]]></pre>
-
-            <pre class="prettyprint linenums lang-java"><![CDATA[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.
-}]]></pre>
-
-            <pre class="prettyprint linenums lang-java"><![CDATA[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();
-    }
-    ...
-}]]></pre>
-        </subsection>
-        <a name="HttpAppender"/>
-        <subsection name="HttpAppender">
-          <p>
-            The HttpAppender sends log events over HTTP. A Layout must be provided to format the LogEvent.
-          </p>
-          <p>
-            Will set the <code>Content-Type</code> header according to the layout. Additional headers can be specified
-            with embedded Property elements.
-          </p>
-          <p>
-            Will wait for response from server, and throw error if no 2xx

<TRUNCATED>

[4/5] logging-log4j2 git commit: LOG4J2-1802: Convert appenders manual to asciidoc

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0c47af7f/src/site/asciidoc/manual/appenders.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/appenders.adoc b/src/site/asciidoc/manual/appenders.adoc
new file mode 100644
index 0000000..b37af23
--- /dev/null
+++ b/src/site/asciidoc/manual/appenders.adoc
@@ -0,0 +1,4483 @@
+= Appenders
+Ralph Goers; Gary Gregory; Nick Williams; Matt Sicker
+
+Appenders are responsible for delivering LogEvents to their destination.
+Every Appender must implement the
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html[`Appender`]
+interface. Most Appenders will extend
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/appender/AbstractAppender.html[`AbstractAppender`]
+which adds
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/LifeCycle.html[`Lifecycle`]
+and
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/filter/Filterable.html[`Filterable`]
+support. `Lifecycle` allows components to finish initialization after
+configuration has completed and to perform cleanup during shutdown.
+`Filterable` allows the component to have `Filter`s 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 link:layouts.html[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
+link:../log4j-core/apidocs/index.html[Log4j Core] unless otherwise
+noted.
+
+[#AsyncAppender]
+== 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
+https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html[`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
+link:../performance.html#asyncLogging[tests showed] performance may
+become worse when more threads are logging concurrently. Consider using
+link:async.html[lock-free Async Loggers] for optimal performance.
+
+.AsyncAppender Parameters
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================
+|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.
+
+|bufferSize |integer a|
+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
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html[`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 link:#FailoverAppender[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 link:#BlockingQueueFactory[below
+documentation] for more details.
+|=======================================================================
+
+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
+link:configuration.html#log4j2.AsyncQueueFullPolicy[`log4j2.AsyncQueueFullPolicy`
+and `log4j2.DiscardThreshold`].
+
+A typical AsyncAppender configuration might look like:
+
+[source,xml]
+----
+<?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>
+----
+
+[[BlockingQueueFactory]] Starting in Log4j 2.7, a custom implementation
+of `BlockingQueue` or `TransferQueue` can be specified using a
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/async/BlockingQueueFactory.html[`BlockingQueueFactory`]
+plugin. To override the default `BlockingQueueFactory`, specify the
+plugin inside an `<Async/>` element like so:
+
+[source,xml]
+----
+<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:
+
+.BlockingQueueFactory Implementations
+[cols=",",options="header",]
+|=======================================================================
+|Plugin Name |Description
+|ArrayBlockingQueue |This is the default implementation that uses
+https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/ArrayBlockingQueue.html[`ArrayBlockingQueue`].
+
+|DisruptorBlockingQueue |This uses the
+https://github.com/conversant/disruptor[Conversant Disruptor]
+implementation of `BlockingQueue`. This plugin takes a single optional
+attribute, `spinPolicy`, which corresponds to the `SpinPolicy` enum.
+
+|JCToolsBlockingQueue |This uses
+https://jctools.github.io/JCTools/[JCTools], specifically the MPSC
+bounded lock-free queue.
+
+|LinkedTransferQueue |This uses the new in Java 7 implementation
+https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/LinkedTransferQueue.html[`LinkedTransferQueue`].
+Note that this queue does not use the `bufferSize` configuration
+attribute from AsyncAppender as `LinkedTransferQueue` does not support a
+maximum capacity.
+|=======================================================================
+
+[#CassandraAppender]
+== CassandraAppender
+
+The CassandraAppender writes its output to an
+https://cassandra.apache.org/[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
+link:layouts.html[StringLayout] (e.g., a
+link:layouts.html#PatternLayout[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
+link:thread-context.html[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).
+
+.CassandraAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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
+|http://docs.datastax.com/en/drivers/java/3.0/com/datastax/driver/core/BatchStatement.Type.html[`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.
+
+|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
+link:../log4j-api/apidocs/org/apache/logging/log4j/util/ReadOnlyStringMap.html[`ReadOnlyStringMap`]
+/
+link:../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextMap.html[`ThreadContextMap`]
+or
+link:../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextStack.html[`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 link:#FailoverAppender[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.
+
+|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.time.Clock` as a
+http://docs.datastax.com/en/drivers/java/3.0/com/datastax/driver/core/TimestampGenerator.html[`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.
+|=======================================================================
+
+Here is an example CassandraAppender configuration:
+
+[source,xml]
+----
+<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:
+
+[source,sql]
+----
+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>
+);
+----
+
+[#ConsoleAppender]
+== 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.
+
+.ConsoleAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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`.
+
+|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 link:#FailoverAppender[FailoverAppender].
+
+|target |String |Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is
+"SYSTEM_OUT".
+|=======================================================================
+
+A typical Console configuration might look like:
+
+[source,prettyprint,linenums]
+----
+<?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>
+----
+
+[#FailoverAppender]
+== 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.
+
+.FailoverAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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".
+|=======================================================================
+
+A Failover configuration might look like:
+
+[source,xml]
+----
+<?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>
+----
+
+[#FileAppender]
+== 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.
+
+.FileAppender Parameters
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================
+|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.
+
+|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 a|
+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.
+
+|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 link:#FailoverAppender[FailoverAppender].
+
+|filePermissions |String a|
+File attribute permissions in POSIX format to apply whenever the file is
+created.
+
+Underlying files system shall support
+https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX]
+file attribute view.
+
+Examples: `rw-------` or `rw-rw-rw-` etc...
+
+|fileOwner |String a|
+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
+http://www.gnu.org/software/libc/manual/html_node/Options-for-Files.html[_POSIX_CHOWN_RESTRICTED]
+is in effect for path.
+
+Underlying files system shall support file
+https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/FileOwnerAttributeView.html[owner]
+attribute view.
+
+|fileGroup |String a|
+File group to define whenever the file is created.
+
+Underlying files system shall support
+https://docs.oracle.com/javase/7/docs/api/java/nio/file/attribute/PosixFileAttributeView.html[POSIX]
+file attribute view.
+
+|=======================================================================
+
+Here is a sample File configuration:
+
+[source,xml]
+----
+<?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>
+----
+
+[#FlumeAppender]
+== FlumeAppender
+
+_This is an optional component supplied in a separate jar._
+
+http://flume.apache.org/index.html[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.
+
+.FlumeAppender Parameters
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================
+|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.
+
+|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.
+
+|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[] a|
+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 link:#FailoverAppender[FailoverAppender].
+
+|type |enumeration |One of "Avro", "Embedded", or "Persistent" to
+indicate which variation of the Appender is desired.
+|=======================================================================
+
+A sample FlumeAppender configuration that is configured with a primary
+and a secondary agent, compresses the body, and formats the body using
+the RFC5424Layout:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp">
+  <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:
+
+[source,xml]
+----
+<?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.
+
+[source,xml]
+----
+<?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.
+
+[source,xml]
+----
+<?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>
+----
+
+[#JDBCAppender]
+== JDBCAppender
+
+As of Log4j 2.11.0, JDBC support has moved from the existing module
+`logj-core` to the new module `log4j-jdbc`.
+
+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 <<CassandraAppender>>).
+
+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.
+
+.JDBCAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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 link:#FailoverAppender[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.
+
+|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
+link:../log4j-api/apidocs/org/apache/logging/log4j/util/ReadOnlyStringMap.html[`ReadOnlyStringMap`]
+/
+link:../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextMap.html[`ThreadContextMap`]
+or
+link:../log4j-api/apidocs/org/apache/logging/log4j/spi/ThreadContextStack.html[`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.
+|=======================================================================
+
+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:
+
+* link:#JDBCDataSource[`<DataSource>`]: Uses JNDI.
+* link:#JDBCConnectionFactory[`<ConnectionFactory>`]: Points to a
+class-method pair to provide JDBC connections.
+* link:#JDBCDriverManager[`<DriverManager>`]: A quick and dirty way to
+get off the ground, no connection pooling.
+* link:#JDBCPoolingDriver[`<PoolingDriver>`]: Uses Apache Commons DBCP
+to provide connection pooling.
+
+[#JDBCDataSource]
+.DataSource Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|Parameter Name |Type |Description
+|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.
+|=======================================================================
+
+[#JDBCConnectionFactory]
+.ConnectionFactory Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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 `Connection`s, 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.
+|=======================================================================
+
+[#JDBCDriverManager]
+.DriverManager Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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.
+
+|properties |Property[] |A list of properties. You cannot specify both
+properties and a user name or password.
+|=======================================================================
+
+[#JDBCPoolingDriver]
+.PoolingDriver Parameters (Apache Commons DBCP)
+[cols=",,",options="header",]
+|=======================================================================
+|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`.
+|=======================================================================
+
+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.
+
+.Column Parameters
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================
+|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.
+
+|parameter |String a|
+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.
+
+|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`).
+|=======================================================================
+
+.ColumnMapping Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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.
+
+|type |String |Conversion type name, a fully-qualified class name.
+|=======================================================================
+
+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:
+
+[source,xml]
+----
+<?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>
+----
+
+[source,xml]
+----
+<?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>
+----
+
+[source,java]
+----
+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 link:messages.html#MapMessage[`MapMessage`]-aware.
+
+The following configuration uses a `MessageLayout` to indicate that the
+Appender should match the keys of a `MapMessage` to the names of
+`ColumnMapping`s 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 `LogEvent`s.
+
+[source,xml]
+----
+<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>
+----
+
+[#JMSAppender]
+== JMSAppender
+
+[[JMSQueueAppender]] [[JMSTopicAppender]]
+As of Log4j 2.11.0, JPA support has moved from the existing module
+`logj-core` to the new module `log4j-jms`.
+
+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.
+
+.JMS Appender Parameters
+[cols=",,,",options="header",]
+|=======================================================================
+|Parameter Name |Type |Default |Description
+|factoryBindingName |String |_Required_ |The name to locate in the
+Context that provides the
+https://download.oracle.com/javaee/5/api/javax/jms/ConnectionFactory.html[`ConnectionFactory`].
+This can be any subinterface of `ConnectionFactory` as well.
+
+|factoryName |String |_Required_ |The fully qualified class name that
+should be used to define the Initial Context Factory as defined in
+https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY[`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
+https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#PROVIDER_URL[`PROVIDER_URL`].
+
+|destinationBindingName |String |_Required_ |The name to use to locate
+the
+https://download.oracle.com/javaee/5/api/javax/jms/Destination.html[`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
+https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL[`SECURITY_PRINCIPAL`].
+If a securityPrincipalName is specified without securityCredentials a
+warning message will be logged as this is likely to cause problems.
+
+|securityCredentials |String |null |The security credentials for the
+principal as specified by
+https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS[`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
+link:#FailoverAppender[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
+https://download.oracle.com/javase/7/docs/api/javax/naming/Context.html#URL_PKG_PREFIXES[`URL_PKG_PREFIXES`].
+
+|userName |String |null |The user id used to create the JMS connection.
+|=======================================================================
+
+Here is a sample JMS Appender configuration:
+
+[source,prettyprint,linenums]
+----
+<?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 `MapMessage`s to JMS `javax.jms.MapMessage`s, set the
+layout of the appender to `MessageLayout` with `<MessageLayout />`
+(Since 2.9.):
+
+[source,prettyprint,linenums]
+----
+<?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>
+----
+
+[#JPAAppender]
+== 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.
+
+.JPAAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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 link:#FailoverAppender[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.
+|=======================================================================
+
+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.
+
+[source,prettyprint,linenums,lang-xml]
+----
+<?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>
+----
+
+[source,prettyprint,linenums,lang-xml]
+----
+<?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>
+----
+
+[source,prettyprint,linenums,lang-java]
+----
+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.
+}
+----
+
+[source,prettyprint,linenums,lang-java]
+----
+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();
+    }
+    ...
+}
+----
+
+[#HttpAppender]
+== HttpAppender
+
+The HttpAppender sends log events over HTTP. A Layout must be provided
+to format the LogEvent.
+
+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
+https://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html[HttpURLConnection].
+
+.HttpAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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 link:#SSL[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
+link:lookups.html[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 link:#FailoverAppender[FailoverAppender].
+|=======================================================================
+
+Here is a sample HttpAppender configuration snippet:
+
+[source,prettyprint,linenums]
+----
+<?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>
+----
+
+[#KafkaAppender]
+== KafkaAppender
+
+As of Log4j 2.11.0, https://kafka.apache.org/[Apache Kafka] support has
+moved from the existing module `logj-core` to the new module
+`log4j-kafka`.
+
+The KafkaAppender logs events to an https://kafka.apache.org/[Apache
+Kafka] topic. Each log event is sent as a Kafka record.
+
+.KafkaAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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
+link:./lookups.html[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 link:#FailoverAppender[FailoverAppender].
+
+|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
+http://kafka.apache.org/documentation.html#producerconfigs[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.
+|=======================================================================
+
+Here is a sample KafkaAppender configuration snippet:
+
+[source,prettyprint,linenums]
+----
+<?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
+http://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender[Async
+appender] and/or set syncSend to `false` to log asynchronously.
+
+This appender requires the http://kafka.apache.org/[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:
+
+[source,prettyprint,linenums]
+----
+<?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>
+----
+
+[#MemoryMappedFileAppender]
+== 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
+http://en.wikipedia.org/wiki/Page_cache[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.
+
+.MemoryMappedFileAppender Parameters
+[width="100%",cols="34%,33%,33%",options="header",]
+|=======================================================================
+|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.
+
+|immediateFlush |boolean a|
+When set to true, each write will be followed by a call to
+http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html#force()[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 link:#FailoverAppender[FailoverAppender].
+|=======================================================================
+
+Here is a sample MemoryMappedFile configuration:
+
+[source,prettyprint,linenums]
+----
+<?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>
+----
+
+[#NoSQLAppender]
+== 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.
+
+.NoSQLAppender Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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 link:#FailoverAppender[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.
+|=======================================================================
+
+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:
+
+[source,prettyprint,lang-javascript]
+----
+{
+    "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"
+    ]
+}
+----
+
+[#NoSQLAppenderMongoDB]
+== NoSQLAppenderMongoDB
+
+Starting with Log4 2.11.0, we provide two MongoDB modules:
+
+* `log4j-mongodb2` defines the configuration element
+link:#NoSQLAppenderMongoDB2[`MongoDb2`] matching the MongoDB Driver
+version 2.
+* `log4j-mongodb3` defines the configuration element
+link:#NoSQLAppenderMongoDB3[`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 link:#NoSQLAppenderMongoDB2[`MongoDb2`].
+
+[#NoSQLAppenderMongoDB2]
+== NoSQLAppenderMongoDB2
+
+This section details specializations of the
+link:#NoSQLAppender[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.
+
+.MongoDB2 Provider Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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`.
+
+|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
+https://docs.mongodb.com/manual/core/capped-collections/[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.
+|=======================================================================
+
+This appender is link:messages.html#MapMessage[MapMessage]-aware.
+
+Here are a few sample configurations for the NoSQLAppender and MongoDB2
+provider:
+
+[source,xml]
+----
+<?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>
+----
+
+[source,xml]
+----
+<?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`.
+
+[#NoSQLAppenderMongoDB3]
+== NoSQLAppenderMongoDB3
+
+This section details specializations of the
+link:#NoSQLAppender[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.
+
+.MongoDB3 Provider Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|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.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
+https://docs.mongodb.com/manual/core/capped-collections/[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.
+|=======================================================================
+
+This appender is link:messages.html#MapMessage[MapMessage]-aware.
+
+Here are a few sample configurations for the NoSQLAppender and MongoDB3
+provider:
+
+[source,xml]
+----
+<?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>
+----
+
+[source,xml]
+----
+<?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>
+----
+
+[#NoSQLAppenderCouchDB]
+== NoSQLAppenderCouchDB
+
+This section details specializations of the
+link:#NoSQLAppender[NoSQLAppender] provider for CouchDB. The
+NoSQLAppender writes log events to a NoSQL database using an internal
+lightweight provider interface.
+
+.CouchDB Provider Parameters
+[cols=",,",options="header",]
+|=======================================================================
+|Parameter Name |Type |Description
+|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`.
+|=======================================================================
+
+Here are a few sample configurations for the NoSQLAppender and CouchDB
+provider:
+
+[source,prettyprint,linenums,lang-xml]
+----
+<?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>
+</Configurat

<TRUNCATED>