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/09 01:08:55 UTC

[1/8] logging-log4j2 git commit: LOG4J2-1802: Convert garbage-free manual page to asciidoc

Repository: logging-log4j2
Updated Branches:
  refs/heads/master 86e8caa1e -> 59a9c2d4d


LOG4J2-1802: Convert garbage-free manual page 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/59a9c2d4
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/59a9c2d4
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/59a9c2d4

Branch: refs/heads/master
Commit: 59a9c2d4dce1c5f034aabe87eb939196b775b42e
Parents: bd15f9d
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 20:08:36 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/garbagefree.adoc | 578 ++++++++++++++++++++++++
 src/site/xdoc/manual/garbagefree.xml      | 598 -------------------------
 2 files changed, 578 insertions(+), 598 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/59a9c2d4/src/site/asciidoc/manual/garbagefree.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/garbagefree.adoc b/src/site/asciidoc/manual/garbagefree.adoc
new file mode 100644
index 0000000..0b88426
--- /dev/null
+++ b/src/site/asciidoc/manual/garbagefree.adoc
@@ -0,0 +1,578 @@
+////
+    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.
+////
+= Garbage-free Steady State Logging
+Remko Popma <rp...@apache.org>
+
+////
+Different applications have different performance requirements.
+Some only need to worry about throughput, but for many
+the most important performance consideration is latency (response time).
+Users of such applications would consider it a serious problem
+if the system becomes unresponsive for more than a few seconds, or even milliseconds in some cases.
+In financial trading for example predictable low latency is so important that it is often considered
+worthwhile to trade off some throughput in return for a consistent response time.
+////
+
+Garbage collection pauses are a common cause of latency spikes and for
+many systems significant effort is spent on controlling these pauses.
+
+Many logging libraries, including previous versions of Log4j, allocate
+temporary objects like log event objects, Strings, char arrays, byte
+arrays and more during steady state logging. This contributes to
+pressure on the garbage collector and increases the frequency with which
+GC pauses occur.
+
+From version 2.6, Log4j runs in "garbage free" mode by default where
+objects and buffers are reused and no temporary objects are allocated as
+much as possible. There is also a "low garbage" mode which is not
+completely garbage free but does not use ThreadLocal fields. This is the
+default mode when Log4j link:#Config[detects] it is running in a web
+application. Finally, it is possible to switch off all garbage-free
+logic and run in "classic mode" instead. For details, see the
+link:#Config[Configuration] section below.
+
+[#jfr]
+== A Contrived Example
+
+To highlight the difference that garbage-free logging can make, we used
+Java Flight Recorder to measure a simple application that does nothing
+but log a simple string as often as possible for about 12 seconds.
+
+The application was configured to use Async Loggers, a RandomAccessFile
+appender and a "%d %p %c{1.} [%t] %m %ex%n" pattern layout. (Async
+Loggers used the Yield WaitStrategy.)
+
+Mission Control shows that with Log4j 2.5 this application allocates
+memory at a rate of about 809 MB/sec, resulting in 141 minor
+collections. Log4j 2.6 does not allocate temporary objects in this
+configuration, and as a result the same application with Log4j 2.6 has a
+memory allocation rate of 1.6 MB/sec and was GC-free with 0 (zero)
+garbage collections.
+
+[cols="2*"]
+|===
+|link:../images/log4j-2.5-FlightRecording.png[image:../images/log4j-2.5-FlightRecording-thumbnail40pct.png[image]] +
+With Log4j 2.5: memory allocation rate 809 MB/sec, 141 minor
+collections.
+|link:../images/log4j-2.6-FlightRecording.png[image:../images/log4j-2.6-FlightRecording-thumbnail40pct.png[image]] +
+Log4j 2.6 did not allocate temporary objects: 0 (zero) garbage
+collections.
+|===
+
+[#Config]
+== Configuration
+
+Garbage-free logging in Log4j 2.6 is partially implemented by reusing
+objects in ThreadLocal fields, and partially by reusing buffers when
+converting text to bytes.
+
+ThreadLocal fields holding non-JDK classes can cause memory leaks in web
+applications when the application server's thread pool continues to
+reference these fields after the web application is undeployed. To avoid
+causing memory leaks, Log4j will not use these ThreadLocals when it
+detects that it is used in a web application (when the
+`javax.servlet.Servlet` class is in the classpath, or when system
+property `log4j2.isWebapp` is set to "true").
+
+Some garbage-reducing functionality does not rely on ThreadLocals and is
+enabled by default for all applications: in Log4j 2.6, converting log
+events to text and text to bytes can be done by directly encoding text
+into a reused ByteBuffer without creating intermediary Strings, char
+arrays and byte arrays. So while logging is not completely garbage-free
+for web applications yet, the pressure on the garbage collector can
+still be significantly reduced.
+
+NOTE: As of version 2.6, a Log4j configuration containing a
+`<Properties>` section will result in temporary objects being created
+during steady-state logging.
+
+NOTE: The Async Logger Timeout wait strategy (the default) and the
+Block wait strategy cause
+`java.util.concurrent.locks.AbstractQueuedSynchronizer$Node` objects to
+be created. The Yield and Sleep wait strategies are garbage-free. (See
+link:async.html#SysPropsAllAsync[here] and
+link:async.html#SysPropsMixedSync-Async[here].)
+
+=== Disabling Garbage-free Logging
+
+There are two separate system properties for manually controlling the
+mechanisms Log4j uses to avoid creating temporary objects:
+
+* `log4j2.enableThreadlocals` - if "true" (the default for non-web
+applications) objects are stored in ThreadLocal fields and reused,
+otherwise new objects are created for each log event.
+* `log4j2.enableDirectEncoders` - if "true" (the default) log events are
+converted to text and this text is converted to bytes without creating
+temporary objects. Note: _synchronous_ logging performance may be worse
+for multi-threaded applications in this mode due to synchronization on
+the shared buffer. If your application is multi-threaded and logging
+performance is important, consider using Async Loggers.
+* The ThreadContext map is _not_ garbage-free by default, but from Log4j
+2.7 it can be configured to be garbage-free by setting system property
+`log4j2.garbagefreeThreadContextMap` to "true".
+
+Instead of system properties, the above properties can also be specified
+in a file named `log4j2.component.properties` by including this file in
+the classpath of the application. See the
+link:configuration.html#SystemProperties[manual regarding system
+properties] for more info.
+
+[#Appenders]
+=== Supported Appenders
+
+The following link:appenders.html[appenders] are garbage-free during
+steady-state logging:
+
+* Console
+* File
+* RollingFile (some temporary objects are created during file rollover)
+* RandomAccessFile
+* RollingRandomAccessFile (some temporary objects are created during
+file rollover)
+* MemoryMappedFile
+
+Any other appenders not in the above list (including AsyncAppender)
+create temporary objects during steady-state logging. Instead of
+AsyncAppender, use link:async.html[Async Loggers] to log asynchronously
+in a garbage-free manner.
+
+[#Filters]
+=== Supported Filters
+
+The following link:filters.html[filters] are garbage-free during
+steady-state logging:
+
+* CompositeFilter (adding and removing element filters creates temporary
+objects for thread safety)
+* DynamicThresholdFilter
+* LevelRangeFilter (garbage free since 2.8)
+* MapFilter (garbage free since 2.8)
+* MarkerFilter (garbage free since 2.8)
+* StructuredDataFilter (garbage free since 2.8)
+* ThreadContextMapFilter (garbage free since 2.8)
+* ThresholdFilter (garbage free since 2.8)
+* TimeFilter (garbage free since 2.8)
+
+Other filters like BurstFilter, RegexFilter and ScriptFilter are not
+trivial to make garbage free, and there is currently no plan to change
+them.
+
+[#Layouts]
+=== Supported Layouts
+
+==== GelfLayout
+
+GelfLayout is garbage-free when used with compressionType="OFF", as long
+as no additional field contains '${' (variable substitution).
+
+==== PatternLayout
+
+PatternLayout with the following limited set of conversion patterns is
+garbage-free. Format modifiers to control such things as field width,
+padding, left and right justification will not generate garbage.
+
+[cols="1,2"]
+|===
+|Conversion Pattern |Description
+
+|%c{precision}, %logger{precision}
+|Logger name
+
+|%d, %date
+a|
+Note: Only the predefined date formats are garbage-free: (millisecond
+separator may be either a comma ',' or a period '.')
+
+!===
+!Pattern !Example
+
+!%d{DEFAULT}
+!2012-11-02 14:34:02,781
+
+!%d{ISO8601}
+!2012-11-02T14:34:02,781
+
+!%d{ISO8601_BASIC}
+!20121102T143402,781
+
+!%d{ABSOLUTE}
+!14:34:02,781
+
+!%d{DATE}
+!02 Nov 2012 14:34:02,781
+
+!%d{COMPACT}
+!20121102143402781
+
+!%d{HH:mm:ss,SSS}
+!14:34:02,781
+
+!%d{dd MMM yyyy HH:mm:ss,SSS}
+!02 Nov 2012 14:34:02,781
+
+!%d{HH:mm:ss}{GMT+0}
+!18:34:02
+
+!%d{UNIX}
+!1351866842
+
+!%d{UNIX_MILLIS}
+!1351866842781
+!===
+
+|%enc{pattern}, %encode{pattern}
+|Encodes special characters such as
+'\n' and HTML characters to help prevent log forging and some XSS
+attacks that could occur when displaying logs in a web browser -
+garbage-free since 2.8
+
+|%equals{pattern}{test}{substitution},
+%equalsIgnoreCase{pattern}{test}{substitution}
+|Replaces occurrences
+of 'test', a string, with its replacement 'substitution' in the string
+resulting from evaluation of the pattern - garbage-free since 2.8
+
+|%highlight{pattern}{style}
+|Adds ANSI colors - garbage-free since 2.7
+(unless nested pattern is not garbage free)
+
+|%K{key}, %map{key}, %MAP{key}
+|Outputs the entries in a
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html[MapMessage],
+if one is present in the event - garbage-free since 2.8.
+
+|%m, %msg, %message
+|Log message (garbage-free unless message text
+contains '${')
+
+|%marker
+|The full name of the marker (including parents) - garbage-free
+since 2.8
+
+|%markerSimpleName
+|The simple name of the marker (not including
+parents)
+
+|%maxLen, %maxLength
+|Truncates another pattern to some max number of
+characters - garbage-free since 2.8
+
+|%n
+|The platform dependent line separator
+
+|%N, %nano
+|System.nanoTime() when the event was logged
+
+|%notEmpty{pattern}, %varsNotEmpty{pattern},
+%variablesNotEmpty{pattern}
+|Outputs the result of evaluating the
+pattern if and only if all variables in the pattern are not empty -
+garbage-free since 2.8
+
+|%p, %level
+|The level of the logging event
+
+|%r, %relative
+|The number of milliseconds elapsed since the JVM was
+started until the creation of the logging event - garbage-free since 2.8
+
+|%sn, %sequenceNumber
+|A sequence number that will be incremented in
+every event - garbage-free since 2.8
+
+|%style{pattern}{ANSI style}
+|Style the message - garbage-free since
+2.7 (unless nested pattern is not garbage free)
+
+|%T, %tid, %threadId
+|The ID of the thread that generated the logging
+event
+
+|%t, %tn, %thread, %threadName
+|The name of the thread that generated
+the logging event
+
+|%tp
+|The priority of the thread that generated the logging event
+
+|%X{key[,key2...]}, %mdc{key[,key2...]}, %MDC{key[,key2...]}
+|Outputs
+the Thread Context Map (also known as the Mapped Diagnostic Context or
+MDC) associated with the thread that generated the logging event -
+garbage-free since 2.8
+
+|literal text
+|Garbage-free unless literal contains '${' (variable
+substitution)
+|===
+
+Other PatternLayout conversion patterns, and other Layouts may be
+updated to avoid creating temporary objects in future releases. (Patches
+welcome!)
+
+NOTE: Logging exceptions and stack traces will create temporary
+objects with any layout. (However, Layouts will only create these
+temporary objects when an exception actually occurs.) We haven't figured
+out a way to log exceptions and stack traces without creating temporary
+objects. That is unfortunate, but you probably still want to log them
+when they happen.
+
+****
+NOTE: patterns containing regular expressions and lookups for property
+substitution will result in temporary objects being created during
+steady-state logging.
+
+Including location information is done by walking the stacktrace of an
+exception, which creates temporary objects, so the following patterns
+are not garbage-free:
+
+* %C, %class - Class Name
+* %F, %file - File Location
+* %l, %location - Location
+* %L, %line - Line Location
+* %M, %method - Method Location
+
+Also, the pattern converters for formatting Throwables are not
+garbage-free:
+
+* %ex, %exception, %throwable - The Throwable trace bound to the
+LoggingEvent
+* %rEx, %rException %rThrowable - Same as %ex but with wrapping
+exceptions
+* %xEx, %xException, %xThrowable - Same as %ex but with class packaging
+information
+* %u, %uuid - Creates a new random or time-based UUID while formatting
+
+****
+
+[#api]
+=== API Changes
+
+Methods have been added to the `Logger` interface so that no vararg
+array objects are created when logging messages with up to ten
+parameters.
+
+Also, methods have been added to the `Logger` interface to log
+`java.lang.CharSequence` messages. User-defined objects that implement
+the `CharSequence` interface can be logged without creating temporary
+objects: Log4j will try to turn CharSequence messages, Object messages
+and message parameters into text by appending them to a StringBuilder as
+a CharSequence. This avoids calling `toString()` on these objects.
+
+An alternative is to implement the
+http://logging.apache.org/log4j/2.x/log4j-api/xref/org/apache/logging/log4j/util/StringBuilderFormattable.html[`org.apache.logging.log4j.util.StringBuilderFormattable`]
+interface. If an object is logged that implements this interface, its
+`formatTo` method is called instead of `toString()`.
+
+Log4j may call `toString()` on message and parameter objects when
+garbage-free logging is disabled (when system property
+`log4j2.enableThreadlocals` is set to "false".)
+
+[#codeImpact]
+=== Impact on Application Code: Autoboxing
+
+We made an effort to make logging garbage-free without requiring code
+changes in existing applications, but there is one area where this was
+not possible. When logging primitive values (i.e. int, double, boolean,
+etc.) the JVM autoboxes these primitive values to their Object wrapper
+equivalents, creating garbage.
+
+Log4j provides an `Unbox` utility to prevent autoboxing of primitive
+parameters. This utility contains a thread-local pool of reused
+`StringBuilder`s. The `Unbox.box(primitive)` methods write directly into
+a StringBuilder, and the resulting text will be copied into the final
+log message text without creating temporary objects.
+
+[source,java]
+----
+import static org.apache.logging.log4j.util.Unbox.box;
+
+// ...
+public void garbageFree() {
+    logger.debug("Prevent primitive autoboxing {} {}", box(10L), box(2.6d));
+}
+----
+
+****
+NOTE: not all logging is garbage free. Specifically:
+
+* The ThreadContext map is not garbage-free by default, but can be
+configured to be garbage-free by setting system property
+`log4j2.garbagefreeThreadContextMap` to "true".
+* The ThreadContext stack is not garbage-free.
+* Logging more than 10 parameters creates vararg arrays.
+* Logging very large messages (more than 518 characters) when all
+loggers are Async Loggers will cause the internal StringBuilder in the
+RingBuffer to be trimmed back to their max size.
+* Logging messages containing '${': substituting a ${variable} creates
+temporary objects.
+* Logging a lambda _as a parameter_
+(`logger.info("lambda value is {}", () -> callExpensiveMethod())`)
+creates a vararg array. Logging a lambda expression by itself is
+garbage-free: `logger.debug(() -> callExpensiveMethod())`.
+* The `Logger.traceEntry` and `Logger.traceExit` methods create
+temporary objects.
+****
+
+[#Performance]
+== Performance
+
+[#Latency]
+=== Response Time Latency
+
+Response time is how long it takes to log a message under a certain
+load. What is often reported as latency is actually _service time_: how
+long it took to perform the operation. This hides the fact that a single
+spike in service time adds queueing delay for many of the subsequent
+operations. Service time is easy to measure (and often looks good on
+paper) but is irrelevant for users since it omits the time spent waiting
+for service. For this reason we report response time: service time plus
+wait time. See the link:../performance.html#responseTime[response time
+section] of the performance page for more detail.
+
+The response time test results below were all derived from running the
+ResponseTimeTest class which can be found in the Log4j 2 unit test
+source directory. If you want to run these tests yourself, here are the
+command line options we used:
+
+* -Xms1G -Xmx1G (prevent heap resizing during the test)
+* -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
+-DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin
+wait strategy reduces some jitter.)
+* *classic mode:* -Dlog4j2.enable.threadlocals=false
+-Dlog4j2.enable.direct.encoders=false +
+*garbage-free mode:* -Dlog4j2.enable.threadlocals=true
+-Dlog4j2.enable.direct.encoders=true
+* -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
+* -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps
+-XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime
+-XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses)
+
+=== Async Loggers
+
+The graph below compares "classic" logging to garbage-free logging
+response time behaviour for Log4j's Async Loggers. In the graph, "100k"
+means logging at a sustained load of 100,000 messages/second, "800k" is
+a sustained load of 800,000 messages/second.
+
+image:../images/ResponseTimeAsyncClassicVsGcFree-label.png[image]
+
+In *classic* mode we see numerous minor garbage collections which pause
+the application threads for 3 milliseconds or more. This quickly adds up
+to response time delays of almost 10 milliseconds. As you can see in the
+graph, increasing the load shifts the curve to the left (there are more
+spikes). This makes sense: logging more means more pressure on the
+garbage collector resulting in more minor GC pauses. We experimented a
+little with reducing the load to 50,000 or even 5000 messages/second,
+but this did not eliminate the 3 millisecond pauses, it just made them
+occur less frequently. Note that all GC pauses in this test are minor GC
+pauses. We did not see any full garbage collections.
+
+In *garbage-free* mode, maximum response time remains well below 1
+millisecond under a wide range of loads. (Max 780 us at 800,000
+messages/sec, max 407 us at 600,000 messages/sec, with the 99% around 5
+us for all loads up to 800,000 messages/sec.) Increasing or decreasing
+the load does not change the response time behaviour. We did not
+investigate the cause of the 200-300 microsecond pauses we saw in these
+tests.
+
+When we increased the load further we begin to see larger response time
+pauses for both classic and garbage-free logging. At sustained loads of
+1 million messages/second or more we start to approach the maximum
+throughput of the underlying RandomAccessFile Appender (see the
+synchronous logging throughput chart below). At these loads the
+ringbuffer starts to fill up and backpressure kicks in: attempting to
+add another message when the ringbuffer is full will block until a free
+slot becomes available. We start to see response times of tens of
+milliseconds or more; and attempting to increase the load even more
+results in larger and larger response time spikes.
+
+=== Synchronous File Logging
+
+With synchronous file logging, garbage-free logging still performs
+better than classic logging, but the difference is less pronounced.
+
+At a workload of 100,000 messages/second, classic logging max response
+time was a little over 2 milliseconds where garbage-free logging was a
+little over 1 millisecond. When the workload is increased to 300,000
+messages/second, classic logging shows response time pauses of 6
+milliseconds where the garbage-free response times were less than 3
+milliseconds. It may be possible to improve on this, we did not
+investigate further yet.
+
+image:../images/ResponseTimeSyncClassicVsGcFree.png[image]
+
+The above results are obtained with the ResponseTimeTest class which can
+be found in the Log4j 2 unit test source directory, running on JDK
+1.8.0_45 on RHEL 6.5 (Linux 2.6.32-573.1.1.el6.x86_64) with 10-core Xeon
+CPU E5-2660 v3 @2.60GHz with hyperthreading switched on (20 virtual
+cores).
+
+[#Throughput]
+=== Classic Logging has Slightly Higher Throughput
+
+Throughput is slightly worse for garbage-free logging, compared to
+classic logging. This is true for both synchronous and asynchronous
+logging. The graph below compares the sustained throughput of
+synchronous logging to a file with Log4j 2.6 in garbage-free mode,
+classic mode and Log4j 2.5.
+
+image:../images/garbage-free2.6-SyncThroughputLinux.png[Throughput of
+Log4j 2.6 in garbage-free mode is slightly worse than in classic mode,
+but on par with 2.5 and much better than alternatives logging libraries]
+
+The results above are obtained with the
+http://openjdk.java.net/projects/code-tools/jmh/[JMH] Java benchmark
+harness. See the FileAppenderBenchmark source code in the log4j-perf
+module.
+
+[#UnderTheHood]
+== Under the Hood
+
+Custom Message implementations that implement
+`org.apache.logging.log4j.util.StringBuilderFormattable` can be
+converted to text by garbage-free Layouts without creating temporary
+objects. PatternLayout uses this mechanism and other layouts that
+convert LogEvents to text will likely also look for this interface.
+
+Custom Layouts that want to be garbage-free should implement the
+`Encoder<LogEvent>` interface. For custom Layouts that convert a
+LogEvent to a text representation, the
+`org.apache.logging.log4j.core.layout.StringBuilderEncoder` class may be
+useful to convert this text to bytes in a garbage-free manner.
+
+Custom Appenders that want to be garbage-free should provide their
+Layout with a `ByteBufferDestination` implementation that the Layout can
+directly write into.
+
+`AbstractOutputStreamAppender` has been modified to make the
+ConsoleAppender, (Rolling)FileAppender,
+(Rolling)RandomAccessFileAppender and MemoryMappedFileAppender
+garbage-free. An effort has been made to minimize impact on custom
+Appenders that extend `AbstractOutputStreamAppender`, but it is
+impossible to guarantee that changing the superclass will not impact any
+and all subclasses. Custom Appenders that extend
+`AbstractOutputStreamAppender` should verify that they still function
+correctly. In case there is a problem, system property
+`log4j2.enable.direct.encoders` can be set to "false" to revert to the
+pre-Log4j 2.6 behaviour.
+
+////
+TODO Applications that wish to reuse custom Message instances with Async Loggers should let
+their Message classes implement the `org.apache.logging.log4j.message.ReusableMessage` interface.
+TODO This is not sufficient: see LOG4J2-1342, would be nice if we could solve this in a generic way.
+////

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/59a9c2d4/src/site/xdoc/manual/garbagefree.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/garbagefree.xml b/src/site/xdoc/manual/garbagefree.xml
deleted file mode 100644
index b0852bc..0000000
--- a/src/site/xdoc/manual/garbagefree.xml
+++ /dev/null
@@ -1,598 +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>Garbage-free Steady State Logging</title>
-    <author email="rpopma@apache.org">Remko Popma</author>
-  </properties>
-  <body>
-    <section name="Garbage-free Steady State Logging">
-      <!--
-      <p>
-        Different applications have different performance requirements.
-        Some only need to worry about throughput, but for many
-        the most important performance consideration is latency (response time).
-        Users of such applications would consider it a serious problem
-        if the system becomes unresponsive for more than a few seconds, or even milliseconds in some cases.
-        In financial trading for example predictable low latency is so important that it is often considered
-        worthwhile to trade off some throughput in return for a consistent response time.
-      </p>
-      -->
-      <p>
-        Garbage collection pauses are a common cause of latency spikes and for many systems
-        significant effort is spent on controlling these pauses.
-      </p>
-      <p>
-        Many logging libraries, including previous versions of Log4j, allocate temporary objects like
-        log event objects, Strings, char arrays, byte arrays and more during steady state logging.
-        This contributes to pressure on the garbage collector and increases the frequency with which GC pauses occur.
-      </p>
-      <p>
-        From version 2.6, Log4j runs in "garbage free" mode by default
-        where objects and buffers are reused and no temporary objects are allocated as much as possible.
-        There is also a "low garbage" mode which is not completely garbage free but does not use ThreadLocal fields.
-        This is the default mode when Log4j <a href="#Config">detects</a> it is running in a web application.
-        <!--
-      </p>
-      <p>
-      -->
-        Finally, it is possible to switch off all garbage-free logic and run in "classic mode" instead.
-        For details, see the <a href="#Config">Configuration</a> section below.
-      </p>
-      <a name="jfr" />
-      <subsection name="A Contrived Example">
-        <p>
-          To highlight the difference that garbage-free logging can make, we used Java Flight Recorder
-          to measure a simple application that does nothing but log a simple string as often as possible
-          for about 12 seconds.
-        </p>
-        <p>
-          The application was configured to use Async Loggers, a RandomAccessFile appender and a
-          "%d %p %c{1.} [%t] %m %ex%n" pattern layout. (Async Loggers used the Yield WaitStrategy.)
-        </p>
-        <p>
-          Mission Control shows that with Log4j 2.5 this application allocates memory at a rate of about 809 MB/sec,
-          resulting in 141 minor collections.
-          Log4j 2.6 does not allocate temporary objects in this configuration, and as a result
-          the same application with Log4j 2.6 has a memory allocation rate of 1.6 MB/sec and
-          was GC-free with 0 (zero) garbage collections.
-        </p>
-        <table>
-          <tr>
-            <td>
-        <a href="../images/log4j-2.5-FlightRecording.png"><img
-            src="../images/log4j-2.5-FlightRecording-thumbnail40pct.png" /></a><br />
-              With Log4j 2.5: memory allocation rate 809 MB/sec, 141 minor collections.
-            </td>
-            <td>
-              <a href="../images/log4j-2.6-FlightRecording.png"><img
-                  src="../images/log4j-2.6-FlightRecording-thumbnail40pct.png" /></a>
-              <br />
-              Log4j 2.6 did not allocate temporary objects: 0 (zero) garbage collections.
-            </td>
-          </tr>
-        </table>
-      </subsection>
-
-      <a name="Config" />
-      <subsection name="Configuration">
-        <p>Garbage-free logging in Log4j 2.6 is partially implemented by reusing objects in ThreadLocal fields,
-          and partially by reusing buffers when converting text to bytes.
-        </p>
-        <p>
-          ThreadLocal fields holding non-JDK classes can cause memory leaks in
-          web applications when the application server's thread pool continues to reference
-          these fields after the web application is undeployed.
-          To avoid causing memory leaks, Log4j will not use these ThreadLocals when
-          it detects that it is used in a web application
-          (when the <tt>javax.servlet.Servlet</tt> class is in the classpath,
-          or when system property <tt>log4j2.isWebapp</tt> is set to "true").
-        </p>
-          <p>
-            Some garbage-reducing functionality does not rely on ThreadLocals and is
-            enabled by default for all applications:
-            in Log4j 2.6, converting log events to text and text to bytes can be done by directly encoding text
-            into a reused ByteBuffer without creating intermediary Strings, char arrays and byte arrays.
-            So while logging is not completely garbage-free for web applications yet,
-            the pressure on the garbage collector can still be significantly reduced.
-          </p>
-          <table><tr><td><p>
-            <b>Note 1:</b> as of version 2.6, a Log4j configuration containing a <tt>&lt;Properties&gt;</tt> section
-            will result in temporary objects being created during steady-state logging.
-            </p>
-            <p>
-              <b>Note 2:</b> the Async Logger Timeout wait strategy (the default) and the Block wait strategy
-              cause <tt>java.util.concurrent.locks.AbstractQueuedSynchronizer$Node</tt> objects to be created.
-              The Yield and Sleep wait strategies are garbage-free. (See
-              <a href="async.html#SysPropsAllAsync">here</a> and
-              <a href="async.html#SysPropsMixedSync-Async">here</a>.)
-            </p>
-          </td></tr></table>
-          <h4>Disabling Garbage-free Logging</h4>
-          <p>
-            There are two separate system properties for manually controlling the mechanisms Log4j uses to avoid
-            creating temporary objects:
-          </p>
-          <ul>
-            <li><tt>log4j2.enableThreadlocals</tt> - if "true" (the default for non-web applications)
-              objects are stored in ThreadLocal fields and reused, otherwise new
-              objects are created for each log event.</li>
-            <li><tt>log4j2.enableDirectEncoders</tt> - if "true" (the default) log events are converted to text and this
-              text is converted to bytes without creating temporary objects. Note:
-              <em>synchronous</em> logging performance may be worse for multi-threaded applications in this mode due to
-              synchronization on the shared buffer. If your application is multi-threaded and logging performance
-              is important, consider using Async Loggers.
-              </li>
-            <li>The ThreadContext map is <em>not</em> garbage-free by default, but from Log4j 2.7 it can be configured
-              to be garbage-free by setting system property <tt>log4j2.garbagefreeThreadContextMap</tt> to "true".</li>
-          </ul>
-          <p>
-            Instead of system properties, the above properties can also be specified in a file named
-            <tt>log4j2.component.properties</tt> by including this file in the classpath of the application.
-            See the <a href="configuration.html#SystemProperties">manual regarding system properties</a> for more info.
-          </p>
-        <a name="Appenders" />
-          <h4>Supported Appenders</h4>
-          <p>
-            The following <a href="appenders.html">appenders</a> are garbage-free during steady-state logging:
-          </p>
-          <ul>
-            <li>Console</li>
-            <li>File</li>
-            <li>RollingFile (some temporary objects are created during file rollover)</li>
-            <li>RandomAccessFile</li>
-            <li>RollingRandomAccessFile (some temporary objects are created during file rollover)</li>
-            <li>MemoryMappedFile</li>
-          </ul>
-          <p>
-            Any other appenders not in the above list (including AsyncAppender) create temporary objects
-            during steady-state logging. Instead of AsyncAppender, use <a href="async.html">Async Loggers</a>
-            to log asynchronously in a garbage-free manner.
-          </p>
-
-        <a name="Filters" />
-        <h4>Supported Filters</h4>
-        <p>
-          The following <a href="filters.html">filters</a> are garbage-free during steady-state logging:
-        </p>
-        <ul>
-          <li>CompositeFilter (adding and removing element filters creates temporary objects for thread safety)</li>
-          <li>DynamicThresholdFilter</li>
-          <li>LevelRangeFilter (garbage free since 2.8)</li>
-          <li>MapFilter (garbage free since 2.8)</li>
-          <li>MarkerFilter (garbage free since 2.8)</li>
-          <li>StructuredDataFilter (garbage free since 2.8)</li>
-          <li>ThreadContextMapFilter (garbage free since 2.8)</li>
-          <li>ThresholdFilter (garbage free since 2.8)</li>
-          <li>TimeFilter (garbage free since 2.8)</li>
-        </ul>
-        <p>
-          Other filters like BurstFilter, RegexFilter and ScriptFilter are not trivial to make garbage free,
-          and there is currently no plan to change them.
-        </p>
-        <a name="Layouts" />
-          <h4>Supported Layouts</h4>
-
-          <h5>GelfLayout</h5>
-          <p>GelfLayout is garbage-free when used with compressionType="OFF",
-            as long as no additional field contains '${' (variable substitution).</p>
-
-          <h5>PatternLayout</h5>
-          <p>
-            PatternLayout with the following limited set of conversion patterns is garbage-free.
-            Format modifiers to control such things as field width, padding, left and right justification will not
-            generate garbage.
-          </p>
-          <table style="width: 80%">
-            <tr>
-              <th>Conversion Pattern</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>%c{precision}, %logger{precision}</td>
-              <td>Logger name</td>
-            </tr>
-            <tr>
-              <td>%d, %date</td>
-              <td>Note: Only the predefined date formats are garbage-free: (millisecond separator may be either
-                a comma ',' or a period '.')
-                <table>
-                  <tr>
-                    <th>Pattern</th>
-                    <th>Example</th>
-                  </tr>
-                  <tr>
-                    <td>%d{DEFAULT}</td>
-                    <td>2012-11-02 14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{ISO8601}</td>
-                    <td>2012-11-02T14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{ISO8601_BASIC}</td>
-                    <td>20121102T143402,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{ABSOLUTE}</td>
-                    <td>14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{DATE}</td>
-                    <td>02 Nov 2012 14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{COMPACT}</td>
-                    <td>20121102143402781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{HH:mm:ss,SSS}</td>
-                    <td>14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{dd MMM yyyy HH:mm:ss,SSS}</td>
-                    <td>02 Nov 2012 14:34:02,781</td>
-                  </tr>
-                  <tr>
-                    <td>%d{HH:mm:ss}{GMT+0}</td>
-                    <td>18:34:02</td>
-                  </tr>
-                  <tr>
-                    <td>%d{UNIX}</td>
-                    <td>1351866842</td>
-                  </tr>
-                  <tr>
-                    <td>%d{UNIX_MILLIS}</td>
-                    <td>1351866842781</td>
-                  </tr>
-                </table>
-              </td>
-            </tr>
-            <tr>
-              <td>%enc{pattern},
-                %encode{pattern}</td>
-              <td>Encodes special characters such as '\n' and HTML characters to help prevent
-                log forging and some XSS attacks that could occur when displaying logs in
-                a web browser - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%equals{pattern}{test}{substitution},
-                %equalsIgnoreCase{pattern}{test}{substitution}</td>
-              <td>Replaces occurrences of 'test', a string, with its replacement 'substitution'
-                in the string resulting from evaluation of the pattern - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%highlight{pattern}{style}</td>
-              <td>Adds ANSI colors - garbage-free since 2.7 (unless nested pattern is not garbage free)</td>
-            </tr>
-            <tr>
-              <td>K{key}, map{key}, MAP{key}
-              </td>
-              <td>Outputs the entries in a
-                <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html">MapMessage</a>,
-                if one is present in the event  - garbage-free since 2.8.</td>
-            </tr>
-            <tr>
-              <td>%m, %msg, %message</td>
-              <td>Log message (garbage-free unless message text contains '${')</td>
-            </tr>
-            <tr>
-              <td>%marker</td>
-              <td>The full name of the marker (including parents) - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%markerSimpleName</td>
-              <td>The simple name of the marker (not including parents)</td>
-            </tr>
-            <tr>
-              <td>%maxLen, %maxLength</td>
-              <td>Truncates another pattern to some max number of characters - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%n</td>
-              <td>The platform dependent line separator</td>
-            </tr>
-            <tr>
-              <td>%N, %nano</td>
-              <td>System.nanoTime() when the event was logged</td>
-            </tr>
-            <tr>
-              <td>%notEmpty{pattern},
-                %varsNotEmpty{pattern},
-                %variablesNotEmpty{pattern}
-              </td>
-              <td>Outputs the result of evaluating the pattern if and only if
-                all variables in the pattern are not empty - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%p, %level</td>
-              <td>The level of the logging event</td>
-            </tr>
-            <tr>
-              <td>%r,
-                %relative</td>
-              <td>The number of milliseconds elapsed since the JVM was started until the creation of the logging event
-                  - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%sn, %sequenceNumber</td>
-              <td>A sequence number that will be incremented in every event - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>%style{pattern}{ANSI style}</td>
-              <td>Style the message - garbage-free since 2.7 (unless nested pattern is not garbage free)</td>
-            </tr>
-            <tr>
-              <td>%T, %tid, %threadId</td>
-              <td>The ID of the thread that generated the logging event</td>
-            </tr>
-            <tr>
-              <td>%t, %tn, %thread, %threadName</td>
-              <td>The name of the thread that generated the logging event</td>
-            </tr>
-            <tr>
-              <td>%tp</td>
-              <td>The priority of the thread that generated the logging event</td>
-            </tr>
-            <tr>
-              <td>%X{key[,key2...]},
-                %mdc{key[,key2...]},
-                %MDC{key[,key2...]}</td>
-              <td>Outputs the Thread Context Map (also known as the Mapped Diagnostic Context or MDC)
-                associated with the thread that generated the logging event - garbage-free since 2.8</td>
-            </tr>
-            <tr>
-              <td>literal text</td>
-              <td>Garbage-free unless literal contains '${' (variable substitution)</td>
-            </tr>
-          </table>
-          <p>
-            Other PatternLayout conversion patterns, and other Layouts may be updated
-            to avoid creating temporary objects in future releases. (Patches welcome!)
-          </p>
-          <p>
-            <em>Note</em>: Logging exceptions and stack traces will create temporary objects with any layout.
-            (However, Layouts will only create these temporary objects when an exception actually occurs.)
-            We haven't figured out a way to log exceptions and stack traces without creating temporary objects.
-            That is unfortunate, but you probably still want to log them when they happen.
-          </p>
-          <table><tr><td><b>Note:</b> patterns containing regular expressions and lookups for property substitution
-            will result in temporary objects being created during steady-state logging.
-            <p>
-              Including location information is done by walking the stacktrace of an exception, which creates temporary
-              objects, so the following patterns are not garbage-free:
-            </p>
-            <ul>
-              <li>%C, %class - Class Name</li>
-              <li>%F, %file - File Location</li>
-              <li>%l, %location - Location</li>
-              <li>%L, %line - Line Location</li>
-              <li>%M, %method - Method Location</li>
-            </ul>
-            Also, the pattern converters for formatting Throwables are not garbage-free:
-            <ul>
-              <li>%ex, %exception, %throwable - The Throwable trace bound to the LoggingEvent</li>
-              <li>%rEx, %rException %rThrowable - Same as %ex but with wrapping exceptions</li>
-              <li>%xEx, %xException, %xThrowable - Same as %ex but with class packaging information</li>
-              <li>%u, %uuid - Creates a new random or time-based UUID while formatting</li>
-            </ul>
-
-          </td></tr></table>
-        <a name="api" />
-          <h4>API Changes</h4>
-          <p>
-            Methods have been added to the <tt>Logger</tt> interface so that no vararg array objects are created
-            when logging messages with up to ten parameters.
-          </p>
-          <p>
-            Also, methods have been added to the <tt>Logger</tt> interface to log <tt>java.lang.CharSequence</tt> messages.
-            User-defined objects that implement the <tt>CharSequence</tt> interface can be logged without creating
-            temporary objects: Log4j will try to turn CharSequence messages,
-            Object messages and message parameters
-            into text by appending them to a StringBuilder as a CharSequence.
-            This avoids calling <tt>toString()</tt> on these objects.
-          </p>
-          <p>
-            An alternative is to implement the
-            <a href="http://logging.apache.org/log4j/2.x/log4j-api/xref/org/apache/logging/log4j/util/StringBuilderFormattable.html"><tt>org.apache.logging.log4j.util.StringBuilderFormattable</tt></a>
-            interface.
-            If an object is logged that implements this interface, its <tt>formatTo</tt> method is called instead of
-            <tt>toString()</tt>.
-          </p>
-          <p>
-            Log4j may call <tt>toString()</tt> on message and parameter objects when garbage-free logging
-            is disabled (when system property <tt>log4j2.enableThreadlocals</tt> is set to "false".)
-          </p>
-        <a name="codeImpact" />
-        <h4>Impact on Application Code: Autoboxing</h4>
-        <p>
-          We made an effort to make logging garbage-free without requiring code changes in existing applications,
-          but there is one area where this was not possible.
-          When logging primitive values (i.e. int, double, boolean, etc.) the JVM
-          autoboxes these primitive values to their Object wrapper equivalents, creating garbage.
-        </p>
-        <p>
-          Log4j provides an <tt>Unbox</tt> utility to prevent autoboxing of primitive parameters.
-          This utility contains a thread-local pool of reused <tt>StringBuilder</tt>s.
-          The <tt>Unbox.box(primitive)</tt> methods write directly into a StringBuilder, and
-          the resulting text will be copied into the final log message text without creating temporary objects.
-        </p>
-        <pre class="prettyprint linenums">import static org.apache.logging.log4j.util.Unbox.box;
-
-...
-public void garbageFree() {
-    logger.debug("Prevent primitive autoboxing {} {}", box(10L), box(2.6d));
-}
-</pre>
-          <table><tr><td>
-            <p>
-              <b>Note:</b> not all logging is garbage free. Specifically:
-            </p>
-            <ul>
-              <li>The ThreadContext map is not garbage-free by default, but can be configured to be garbage-free
-              by setting system property <tt>log4j2.garbagefreeThreadContextMap</tt> to "true".</li>
-              <li>The ThreadContext stack is not garbage-free.</li>
-              <li>Logging more than 10 parameters creates vararg arrays.</li>
-              <li>Logging very large messages (more than 518 characters) when all loggers are Async Loggers
-                will cause the internal StringBuilder in the RingBuffer to be trimmed back to their max size.
-              </li>
-              <li>Logging messages containing '${': substituting a ${variable} creates temporary objects.</li>
-              <li>Logging a lambda <em>as a parameter</em>
-                (<tt>logger.info("lambda value is {}", () -> callExpensiveMethod())</tt>) creates a vararg array.
-                Logging a lambda expression by itself is garbage-free:
-                <tt>logger.debug(() -> callExpensiveMethod())</tt>.
-              </li>
-              <li>The <tt>Logger.traceEntry</tt> and <tt>Logger.traceExit</tt> methods create temporary objects.</li>
-            </ul>
-          </td></tr></table>
-        <p>
-        </p>
-        <p>
-        </p>
-      </subsection>
-      <a name="Performance" />
-      <subsection name="Performance">
-        <a name="Latency" />
-        <h4>Response Time Latency</h4>
-        <p>Response time is how long it takes to log a message under a certain load.
-          What is often reported as latency is actually <em>service time</em>: how long it took to perform the operation.
-          This hides the fact that a single spike in service time adds queueing delay for many of the subsequent operations.
-          Service time is easy to measure (and often looks good on paper) but is irrelevant for users since it
-          omits the time spent waiting for service.
-          For this reason we report response time: service time plus wait time.
-          See the <a href="../performance.html#responseTime">response time section</a> of the performance page for more detail.
-        </p>
-        <p>The response time test results below were all derived from running the ResponseTimeTest class
-          which can be found in the Log4j 2 unit test source directory. If you want to run these tests yourself,
-          here are the command line options we used:
-        </p>
-        <ul>
-          <li>-Xms1G -Xmx1G (prevent heap resizing during the test)</li>
-          <!--
-          <li>-XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=500000 (by default Hotspot schedules a
-            safepoint pause every second. Reduce jitter by postponing this for the duration of the test.)</li>
-            -->
-          <li>-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-            -DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin wait strategy reduces some jitter.)</li>
-          <li><b>classic mode: </b>-Dlog4j2.enable.threadlocals=false -Dlog4j2.enable.direct.encoders=false<br />
-            <b>garbage-free mode: </b>-Dlog4j2.enable.threadlocals=true -Dlog4j2.enable.direct.encoders=true</li>
-          <li>-XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle</li>
-          <li>-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution
-            -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses)</li>
-        </ul>
-        <!--
-        <pre style="overflow: auto; white-space: pre-wrap; word-wrap: normal;">java -Xms1G -Xmx1G -XX:+UnlockDiagnosticVMOptions -verbose:gc -XX:+PrintGCDetails
-          -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution -XX:+PrintGCApplicationConcurrentTime
-          -XX:+PrintGCApplicationStoppedTime -XX:GuaranteedSafepointInterval=500000
-          -XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle
-          -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
-          -Dlog4j2.enable.threadlocals=false -Dlog4j2.enable.direct.encoders=false -DAsyncLogger.WaitStrategy=busyspin
-          -cp .:HdrHistogram-2.1.8.jar:disruptor-3.3.4.jar:log4j-1.2.17.jar:slf4j-api-1.7.13.jar:slf4j-ext-1.7.13.jar:
-          logback-core-1.1.3.jar:logback-classic-1.1.3.jar:log4j-api-2.6-SNAPSHOT.jar:log4j-core-2.6-SNAPSHOT.jar:
-          log4j-core-2.6-SNAPSHOT-tests.jar org.apache.logging.log4j.core.async.perftest.ResponseTimeTest 1 50000</pre>
-        -->
-        <h4>Async Loggers</h4>
-        <p>The graph below compares "classic" logging to
-          garbage-free logging response time behaviour for Log4j's Async Loggers.
-          In the graph, "100k" means logging at a sustained load of 100,000 messages/second, "800k" is
-          a sustained load of 800,000 messages/second.
-        </p>
-        <p><img src="../images/ResponseTimeAsyncClassicVsGcFree-label.png" /></p>
-        <p>In <b>classic</b> mode we see numerous minor garbage collections which pause the application threads
-          for 3 milliseconds or more. This quickly adds up to response time delays of almost 10
-          milliseconds.
-          As you can see in the graph, increasing the load shifts the curve to the left (there are more spikes).
-          This makes sense: logging more means more pressure on the garbage collector resulting in more minor GC pauses.
-          We experimented a little with reducing the load to 50,000 or even 5000 messages/second,
-          but this did not eliminate the 3 millisecond pauses, it just made them occur less frequently.
-          Note that all GC pauses in this test are minor GC pauses. We did not see any full garbage collections.</p>
-        <p>In <b>garbage-free</b> mode, maximum response time remains well below 1 millisecond under a wide range of loads.
-          (Max 780 us at 800,000 messages/sec, max 407 us at 600,000 messages/sec, with the 99% around 5 us for
-          all loads up to 800,000 messages/sec.) Increasing or decreasing the load does not change the response time
-          behaviour. We did not investigate the cause of the 200-300 microsecond pauses we saw in these tests.
-        </p>
-        <p>
-          When we increased the load further we begin to see larger response time pauses for both classic and
-          garbage-free logging.
-          At sustained loads of 1 million messages/second or more we start to approach the maximum throughput of
-          the underlying RandomAccessFile Appender (see the synchronous logging throughput chart below).
-          At these loads the ringbuffer starts to fill up and backpressure kicks in: attempting to add another message
-          when the ringbuffer is full will block until a free slot becomes available. We start to see response times
-          of tens of milliseconds or more; and attempting to increase the load even more results in larger and larger
-          response time spikes.
-        </p>
-        <h4>Synchronous File Logging</h4>
-        <p>With synchronous file logging, garbage-free logging still performs better than classic logging,
-          but the difference is less pronounced.
-        </p>
-        <p>At a workload of 100,000 messages/second, classic logging max response time was a little over 2 milliseconds
-          where garbage-free logging was a little over 1 millisecond.
-          When the workload is increased to 300,000 messages/second, classic logging shows response time pauses of 6
-          milliseconds where the garbage-free response times were less than 3 milliseconds.
-          It may be possible to improve on this, we did not investigate further yet.</p>
-        <p><img src="../images/ResponseTimeSyncClassicVsGcFree.png" /></p>
-        <p>The above results are obtained with the ResponseTimeTest class which can be found in the Log4j 2
-          unit test source directory, running on JDK 1.8.0_45 on RHEL 6.5 (Linux 2.6.32-573.1.1.el6.x86_64)
-          with 10-core Xeon CPU E5-2660 v3 @2.60GHz with hyperthreading switched on (20 virtual cores).</p>
-
-        <a name="Throughput" />
-        <h4>Classic Logging has Slightly Higher Throughput</h4>
-        <p>Throughput is slightly worse for garbage-free logging, compared to classic logging.
-          This is true for both synchronous and asynchronous logging.
-          The graph below compares the sustained throughput of synchronous logging to a file with Log4j 2.6 in
-          garbage-free mode, classic mode and Log4j 2.5.</p>
-        <p><img src="../images/garbage-free2.6-SyncThroughputLinux.png"
-            alt="Throughput of Log4j 2.6 in garbage-free mode is slightly worse than in classic mode, but on par with 2.5 and much better than alternatives logging libraries" /></p>
-        <p>The results above are obtained with the
-          <a href="http://openjdk.java.net/projects/code-tools/jmh/">JMH</a> Java benchmark harness.
-          See the FileAppenderBenchmark source code in the log4j-perf module.</p>
-      </subsection>
-      <a name="UnderTheHood" />
-      <subsection name="Under the Hood">
-        <p>
-          Custom Message implementations that implement <tt>org.apache.logging.log4j.util.StringBuilderFormattable</tt>
-          can be converted to text by garbage-free Layouts without creating temporary objects.
-          PatternLayout uses this mechanism and other layouts that convert LogEvents to text
-          will likely also look for this interface.
-        </p>
-        <p>
-          Custom Layouts that want to be garbage-free should implement the <tt>Encoder&lt;LogEvent&gt;</tt> interface.
-          For custom Layouts that convert a LogEvent to a text representation,
-          the <tt>org.apache.logging.log4j.core.layout.StringBuilderEncoder</tt> class may be useful to convert this
-          text to bytes in a garbage-free manner.
-        </p>
-        <p>
-          Custom Appenders that want to be garbage-free should provide their Layout with a
-          <tt>ByteBufferDestination</tt> implementation that the Layout can directly write into.
-        </p>
-        <p>
-          <tt>AbstractOutputStreamAppender</tt> has been modified to make the ConsoleAppender, (Rolling)FileAppender,
-          (Rolling)RandomAccessFileAppender and MemoryMappedFileAppender garbage-free.
-          An effort has been made to minimize impact on custom Appenders that extend
-          <tt>AbstractOutputStreamAppender</tt>, but it is impossible to guarantee that changing the superclass
-          will not impact any and all subclasses. Custom Appenders that extend
-          <tt>AbstractOutputStreamAppender</tt> should verify that they still function correctly.
-          In case there is a problem, system property <tt>log4j2.enable.direct.encoders</tt> can be set to "false"
-          to revert to the pre-Log4j 2.6 behaviour.
-        </p>
-        <!--
-        <p>
-          TODO Applications that wish to reuse custom Message instances with Async Loggers should let
-          their Message classes implement the <tt>org.apache.logging.log4j.message.ReusableMessage</tt> interface.
-          TODO This is not sufficient: see LOG4J2-1342, would be nice if we could solve this in a generic way.
-        </p>
-        -->
-      </subsection>
-    </section>
-  </body>
-</document>


[3/8] logging-log4j2 git commit: LOG4J2-1802: Convert custom log levels manual page to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert custom log levels manual page 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/fe2601c1
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/fe2601c1
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/fe2601c1

Branch: refs/heads/master
Commit: fe2601c101070b69503ac94ba63758995384a1b2
Parents: a15df80
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 18:23:54 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/customloglevels.adoc | 323 +++++++++++++++++++
 src/site/xdoc/manual/customloglevels.xml.vm   | 347 ---------------------
 2 files changed, 323 insertions(+), 347 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe2601c1/src/site/asciidoc/manual/customloglevels.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/customloglevels.adoc b/src/site/asciidoc/manual/customloglevels.adoc
new file mode 100644
index 0000000..e633b52
--- /dev/null
+++ b/src/site/asciidoc/manual/customloglevels.adoc
@@ -0,0 +1,323 @@
+////
+    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
+
+        https://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.
+////
+= Custom Log Levels
+Remko Popma <rp...@apache.org>
+
+[[top]]
+
+[#DefiningLevelsInCode]
+== Defining Custom Log Levels in Code
+
+Log4j 2 supports custom log levels. Custom log levels can be defined in
+code or in configuration. To define a custom log level in code, use the
+`Level.forName()` method. This method creates a new level for the
+specified name. After a log level is defined you can log messages at
+this level by calling the `Logger.log()` method and passing the custom log
+level:
+
+[source,java]
+----
+// This creates the "VERBOSE" level if it does not exist yet.
+final Level VERBOSE = Level.forName("VERBOSE", 550);
+
+final Logger logger = LogManager.getLogger();
+logger.log(VERBOSE, "a verbose message"); // use the custom VERBOSE level
+
+// Create and use a new custom level "DIAG".
+logger.log(Level.forName("DIAG", 350), "a diagnostic message");
+
+// Use (don't create) the "DIAG" custom level.
+// Only do this *after* the custom level is created!
+logger.log(Level.getLevel("DIAG"), "another diagnostic message");
+
+// Using an undefined level results in an error: Level.getLevel() returns null,
+// and logger.log(null, "message") throws an exception.
+logger.log(Level.getLevel("FORGOT_TO_DEFINE"), "some message"); // throws exception!
+----
+
+When defining a custom log level, the `intLevel` parameter (550 and 350
+in the example above) determines where the custom level exists in
+relation to the standard levels built-in to Log4j 2. For reference, the
+table below shows the `intLevel` of the built-in log levels.
+
+.Standard log levels built-in to Log4j
+[cols=",>",options="header"]
+|========================
+|Standard Level |intLevel
+|OFF |0
+|FATAL |100
+|ERROR |200
+|WARN |300
+|INFO |400
+|DEBUG |500
+|TRACE |600
+|ALL |`Integer.MAX_VALUE`
+|========================
+
+[#DefiningLevelsInConfiguration]
+== Defining Custom Log Levels in Configuration
+
+Custom log levels can also be defined in configuration. This is
+convenient for using a custom level in a logger filter or an appender
+filter. Similar to defining log levels in code, a custom level must be
+defined first, before it can be used. If a logger or appender is
+configured with an undefined level, that logger or appender will be
+invalid and will not process any log events.
+
+The *CustomLevel* configuration element creates a custom level.
+Internally it calls the same `Level.forName()` method discussed above.
+
+.CustomLevel Parameters
+[cols="m,,4",options="header"]
+|===
+|Parameter Name |Type |Description
+
+|name
+|String
+|The name of the custom level. Note that level names are
+case sensitive. The convention is to use all upper-case names.
+
+|intLevel
+|integer
+|Determines where the custom level exists in relation
+to the standard levels built-in to Log4j 2 (see the table above).
+|===
+
+The following example shows a configuration that defines some custom log
+levels and uses a custom log level to filter log events sent to the
+console.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <!-- Define custom levels before using them for filtering below. -->
+  <CustomLevels>
+    <CustomLevel name="DIAG" intLevel="350" />
+    <CustomLevel name="NOTICE" intLevel="450" />
+    <CustomLevel name="VERBOSE" intLevel="550" />
+  </CustomLevels>
+
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
+    </Console>
+    <File name="MyFile" fileName="logs/app.log">
+      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
+    </File>
+  </Appenders>
+  <Loggers>
+    <Root level="trace">
+      <!-- Only events at DIAG level or more specific are sent to the console. -->
+      <AppenderRef ref="Console" level="diag" />
+      <AppenderRef ref="MyFile" level="trace" />
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#StandardLoggerInterface]
+== Convenience Methods for the Built-in Log Levels
+
+The built-in log levels have a set of convenience methods on the Logger
+interface that makes them easier to use. For example, the Logger
+interface has 24 `debug()` methods that support the DEBUG level:
+
+[source,java]
+----
+// convenience methods for the built-in DEBUG level
+debug(Marker, Message)
+debug(Marker, Message, Throwable)
+debug(Marker, Object)
+debug(Marker, Object, Throwable)
+debug(Marker, String)
+debug(Marker, String, Object...)
+debug(Marker, String, Throwable)
+debug(Message)
+debug(Message, Throwable)
+debug(Object)
+debug(Object, Throwable)
+debug(String)
+debug(String, Object...)
+debug(String, Throwable)
+// lambda support methods added in 2.4
+debug(Marker, MessageSupplier)
+debug(Marker, MessageSupplier, Throwable)
+debug(Marker, String, Supplier<?>...)
+debug(Marker, Supplier<?>)
+debug(Marker, Supplier<?>, Throwable)
+debug(MessageSupplier)
+debug(MessageSupplier, Throwable)
+debug(String, Supplier<?>...)
+debug(Supplier<?>)
+debug(Supplier<?>, Throwable)
+----
+
+Similar methods exist for the other built-in levels. Custom levels, in
+contrast, need to pass in the log level as an extra parameter.
+
+[source,java]
+----
+// need to pass the custom level as a parameter
+logger.log(VERBOSE, "a verbose message");
+logger.log(Level.forName("DIAG", 350), "another message");
+----
+
+It would be nice to have the same ease of use with custom levels, so
+that after declaring the custom VERBOSE/DIAG levels, we could use code
+like this:
+
+[source,java]
+----
+// nice to have: descriptive methods and no need to pass the level as a parameter
+logger.verbose("a verbose message");
+logger.diag("another message");
+logger.diag("java 8 lambda expression: {}", () -> someMethod());
+----
+
+The standard Logger interface cannot provide convenience methods for
+custom levels, but the next few sections introduce a code generation
+tool to create loggers that aim to make custom levels as easy to use as
+built-in levels.
+
+[#AddingOrReplacingLevels]
+== Adding or Replacing Log Levels
+
+We assume that most users want to _add_ custom level methods to the
+Logger interface, in addition to the existing `trace()`, `debug()`, `info()`,
+... methods for the built-in log levels.
+
+There is another use case, Domain Specific Language loggers, where we
+want to _replace_ the existing `trace()`, `debug()`, `info()`, ... methods
+with all-custom methods.
+
+For example, for medical devices we could have only `critical()`,
+`warning()`, and `advisory()` methods. Another example could be a game
+that has only `defcon1()`, `defcon2()`, and `defcon3()` levels.
+
+If it were possible to hide existing log levels, users could customize
+the Logger interface to match their requirements. Some people may not
+want to have a FATAL or a TRACE level, for example. They would like to
+be able to create a custom Logger that only has `debug()`, `info()`, `warn()`
+and `error()` methods.
+
+[#CustomLoggers]
+== Generating Source Code for a Custom Logger Wrapper
+
+Common Log4j usage is to get an instance of the `Logger` interface from
+the `LogManager` and call the methods on this interface. However, the
+custom log Levels are not known in advance, so Log4j cannot provide an
+interface with convenience methods for these custom log Levels.
+
+To solve this, Log4j ships with a tool that generates source code for a
+Logger wrapper. The generated wrapper class has convenience methods for
+each custom log level, making custom levels just as easy to use as the
+built-in levels.
+
+There are two flavors of wrappers: ones that _*extend*_ the Logger API
+(adding methods to the built-in levels) and ones that _*customize*_ the
+Logger API (replacing the built-in methods).
+
+When generating the source code for a wrapper class, you need to
+specify:
+
+* the fully qualified name of the class to generate
+* the list of custom levels to support and their `intLevel` relative
+strength
+* whether to extend `Logger` (and keep the existing built-in methods) or
+have only methods for the custom log levels
+
+You would then include the generated source code in the project where
+you want to use custom log levels.
+
+[#ExampleUsage]
+== Example Usage of a Generated Logger Wrapper
+
+Here is an example of how one would use a generated logger wrapper with
+custom levels DIAG, NOTICE and VERBOSE:
+
+[source,java]
+----
+// ExtLogger is a generated logger wrapper
+import com.mycompany.myproject.ExtLogger;
+
+public class MyService {
+    // instead of Logger logger = LogManager.getLogger(MyService.class):
+    private static final ExtLogger logger = ExtLogger.create(MyService.class);
+
+    public void demoExtendedLogger() {
+        // ...
+        logger.trace("the built-in TRACE level");
+        logger.verbose("a custom level: a VERBOSE message");
+        logger.debug("the built-in DEBUG level");
+        logger.notice("a custom level: a NOTICE message");
+        logger.info("the built-in INFO level");
+        logger.diag("a custom level: a DIAG message");
+        logger.warn("the built-in WARN level");
+        logger.error("the built-in ERROR level");
+        logger.fatal("the built-in FATAL level");
+        logger.notice("java 8 lambda expression only executed if NOTICE is enabled: {}", () -> someMethod());
+        // ...
+    }
+    ...
+}
+----
+
+[#CodeGen]
+== Generating Extended Loggers
+
+Use the following command to generate a logger wrapper that adds methods
+to the built-in ones:
+
+[source,sh,subs="attributes"]
+----
+java -cp log4j-core-{Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator \
+        com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 > com/mycomp/ExtLogger.java
+----
+
+This will generate source code for a logger wrapper that has the
+convenience methods for the built-in levels _as well as_ the specified
+custom levels. The tool prints the generated source code to the console.
+By appending " > _filename_" the output can be redirected to a file.
+
+NOTE: Prior to log4j-2.9, this tool was an inner class
+`Generate$ExtendedLogger`. +
+Under the bash shell on Unix/Mac/Linux the dollar character $ needs to
+be escaped, so the class name should be between single quotes
+'org.apache.logging.log4j.core.tools.Generate$ExtendedLogger’.
+
+== Generating Custom Loggers
+
+Use the following command to generate a logger wrapper that hides the
+built-in levels and has only custom levels:
+
+[source,sh,subs="attributes"]
+----
+java -cp log4j-core-{Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.CustomLoggerGenerator \
+        com.mycomp.MyLogger DEFCON1=350 DEFCON2=450 DEFCON3=550 > com/mycomp/MyLogger.java
+----
+
+This will generate source code for a logger wrapper that _only_ has
+convenience methods for the specified custom levels, _not_ for the
+built-in levels. The tool prints the generated source code to the
+console. By appending " > _filename_" the output can be redirected to a
+file.
+
+NOTE: Prior to log4j-2.9, this tool was an inner class `Generate$ExtendedLogger`.
+Under the bash shell on Unix/Mac/Linux the dollar character $ needs to
+be escaped, so the class name should be between single quotes
+'org.apache.logging.log4j.core.tools.Generate$CustomLogger’.

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/fe2601c1/src/site/xdoc/manual/customloglevels.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/customloglevels.xml.vm b/src/site/xdoc/manual/customloglevels.xml.vm
deleted file mode 100644
index 7a74a1c..0000000
--- a/src/site/xdoc/manual/customloglevels.xml.vm
+++ /dev/null
@@ -1,347 +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.
--->
-#set($dollar = '$')
-
-<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>Custom Log Levels</title>
-        <author email="rpopma@apache.org">Remko Popma</author>
-    </properties>
-
-    <body>
-      <a name="top" />
-      <section name="Custom Log Levels">
-        <a name="DefiningLevelsInCode" />
-        <subsection name="Defining Custom Log Levels in Code">
-        <p>
-          Log4J 2 supports custom log levels. Custom log levels can be defined in code
-          or in configuration. To define a custom log level in code, use the
-          <tt>Level.forName()</tt> method. This method creates a new
-          level for the specified name. After a log level is defined you can log
-          messages at this level by calling the Logger.log() method and passing
-          the custom log level:
-        </p>
-            <pre class="prettyprint">
-// This creates the "VERBOSE" level if it does not exist yet.
-final Level VERBOSE = Level.forName("VERBOSE", 550);
-
-final Logger logger = LogManager.getLogger();
-logger.log(VERBOSE, "a verbose message"); // use the custom VERBOSE level
-
-// Create and use a new custom level "DIAG".
-logger.log(Level.forName("DIAG", 350), "a diagnostic message");
-
-// Use (don't create) the "DIAG" custom level.
-// Only do this *after* the custom level is created!
-logger.log(Level.getLevel("DIAG"), "another diagnostic message");
-
-// Using an undefined level results in an error: Level.getLevel() returns null,
-// and logger.log(null, "message") throws an exception.
-logger.log(Level.getLevel("FORGOT_TO_DEFINE"), "some message"); // throws exception!</pre>
-        <p>When defining a custom log level, the <tt>intLevel</tt> parameter (550 and 350 in the example above) determines
-           where the custom level exists in relation to the standard levels built-in to Log4J 2.
-           For reference, the table below shows the <tt>intLevel</tt> of the built-in log levels.
-         </p>
-         <table style="width: 30%">
-          <caption align="top">Standard log levels built-in to Log4J</caption>
-          <tr>
-            <th>Standard Level</th>
-            <th>intLevel</th>
-          </tr>
-          <tr>
-            <td>OFF</td>
-            <td align="right">0</td>
-          </tr>
-          <tr>
-            <td>FATAL</td>
-            <td align="right">100</td>
-          </tr>
-          <tr>
-            <td>ERROR</td>
-            <td align="right">200</td>
-          </tr>
-          <tr>
-            <td>WARN</td>
-            <td align="right">300</td>
-          </tr>
-          <tr>
-            <td>INFO</td>
-            <td align="right">400</td>
-          </tr>
-          <tr>
-            <td>DEBUG</td>
-            <td align="right">500</td>
-          </tr>
-          <tr>
-            <td>TRACE</td>
-            <td align="right">600</td>
-          </tr>
-          <tr>
-            <td>ALL</td>
-            <td align="right"><tt>Integer.MAX_VALUE</tt></td>
-          </tr>
-        </table>
-        </subsection>
-        <a name="DefiningLevelsInConfiguration" />
-        <subsection name="Defining Custom Log Levels in Configuration">
-          <p>
-          Custom log levels can also be defined in configuration.
-          This is convenient for using a custom level in a logger filter
-          or an appender filter. Similar to defining log levels in code,
-          a custom level must be defined first, before it can be used.
-          If a logger or appender is configured with an undefined level,
-          that logger or appender will be invalid and will not process any log events.
-          </p>
-          <p>
-            The <b>CustomLevel</b> configuration element creates a custom level.
-            Internally it calls the same <tt>Level.forName()</tt> method discussed above.
-          </p>
-          <table>
-            <caption align="top">CustomLevel Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>name</td>
-              <td>String</td>
-              <td>The name of the custom level. Note that level names are case sensitive.
-                The convention is to use all upper-case names.</td>
-            </tr>
-            <tr>
-              <td>intLevel</td>
-              <td>integer</td>
-              <td>Determines where the custom level exists in relation to the
-                standard levels built-in to Log4J 2 (see the table above).</td>
-            </tr>
-          </table>
-          <p>
-          The following example shows a configuration that defines some custom
-          log levels and uses a custom log level to filter log events sent to the console.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-  <!-- Define custom levels before using them for filtering below. -->
-  <CustomLevels>
-    <CustomLevel name="DIAG" intLevel="350" />
-    <CustomLevel name="NOTICE" intLevel="450" />
-    <CustomLevel name="VERBOSE" intLevel="550" />
-  </CustomLevels>
-
-  <Appenders>
-    <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
-    </Console>
-    <File name="MyFile" fileName="logs/app.log">
-      <PatternLayout pattern="%d %-7level %logger{36} - %msg%n"/>
-    </File>
-  </Appenders>
-  <Loggers>
-    <Root level="trace">
-      <!-- Only events at DIAG level or more specific are sent to the console. -->
-      <AppenderRef ref="Console" level="diag" />
-      <AppenderRef ref="MyFile" level="trace" />
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-          <a name="StandardLoggerInterface" />
-          <subsection name="Convenience Methods for the Built-in Log Levels">
-            <p>
-              The built-in log levels have a set of convenience methods on the Logger
-              interface that makes them easier to use. For example, the Logger interface
-              has 24 <tt>debug()</tt> methods that support the DEBUG level:
-            </p>
-            <pre class="prettyprint">
-// convenience methods for the built-in DEBUG level
-debug(Marker, Message)
-debug(Marker, Message, Throwable)
-debug(Marker, Object)
-debug(Marker, Object, Throwable)
-debug(Marker, String)
-debug(Marker, String, Object...)
-debug(Marker, String, Throwable)
-debug(Message)
-debug(Message, Throwable)
-debug(Object)
-debug(Object, Throwable)
-debug(String)
-debug(String, Object...)
-debug(String, Throwable)
-// lambda support methods added in 2.4
-debug(Marker, MessageSupplier)
-debug(Marker, MessageSupplier, Throwable)
-debug(Marker, String, Supplier&lt;?&gt;...)
-debug(Marker, Supplier&lt;?&gt;)
-debug(Marker, Supplier&lt;?&gt;, Throwable)
-debug(MessageSupplier)
-debug(MessageSupplier, Throwable)
-debug(String, Supplier&lt;?&gt;...)
-debug(Supplier&lt;?&gt;)
-debug(Supplier&lt;?&gt;, Throwable)</pre>
-            <p>
-              Similar methods exist for the other built-in levels.
-              Custom levels, in contrast, need to pass in the log level as an extra parameter.
-            </p>
-            <pre class="prettyprint">
-// need to pass the custom level as a parameter
-logger.log(VERBOSE, "a verbose message");
-logger.log(Level.forName("DIAG", 350), "another message");</pre>
-            <p>It would be nice to have the same ease of use with custom levels,
-               so that after declaring the custom VERBOSE/DIAG levels, we could
-               use code like this:
-            </p>
-            <pre class="prettyprint">
-// nice to have: descriptive methods and no need to pass the level as a parameter
-logger.verbose("a verbose message");
-logger.diag("another message");
-logger.diag("java 8 lambda expression: {}", () -> someMethod());</pre>
-            <p>The standard Logger interface cannot provide convenience methods for
-              custom levels, but the next few sections introduce a code generation tool
-              to create loggers that aim to make custom levels as easy to use
-              as built-in levels.</p>
-          </subsection>
-          <a name="AddingOrReplacingLevels" />
-          <subsection name="Adding or Replacing Log Levels">
-            <p>
-              We assume that most users want to <em>add</em> custom level methods to the Logger interface,
-               in addition to the existing trace(), debug(), info(), ... methods for the built-in log levels.
-            </p>
-            <p>There is another use case, Domain Specific Language loggers, where we want to <em>replace</em>
-               the existing trace(), debug(), info(), ... methods with all-custom methods.
-            </p>
-            <p>
-              For example, for medical devices we could have only <tt>critical()</tt>, <tt>warning()</tt>,
-              and <tt>advisory()</tt> methods.
-              Another example could be a game that has only <tt>defcon1()</tt>, <tt>defcon2()</tt>,
-              and <tt>defcon3()</tt> levels.
-            </p>
-            <p>
-              If it were possible to hide existing log levels, users could customize the
-              Logger interface to match their requirements. Some people may not want to
-              have a FATAL or a TRACE level, for example. They would like to be able to
-              create a custom Logger that only has debug(), info(), warn() and error() methods.
-            </p>
-          </subsection>
-          <a name="CustomLoggers" />
-          <subsection name="Generating Source Code for a Custom Logger Wrapper">
-            <p>
-              Common Log4J usage is to get an instance of the <tt>Logger</tt> interface from the
-              <tt>LogManager</tt> and call the methods on this interface.
-              However, the custom log Levels are not known in advance, so Log4J cannot provide
-              an interface with convenience methods for these custom log Levels.
-            </p>
-            <p>
-              To solve this, Log4J ships with a tool that generates source code for a
-              Logger wrapper. The generated wrapper class has convenience methods for each
-              custom log level, making custom levels just as easy to use as the built-in levels.
-            </p>
-            <p>
-              There are two flavors of wrappers: ones that <em><b>extend</b></em> the Logger
-              API (adding methods to the built-in levels) and ones that <em><b>customize</b></em>
-              the Logger API (replacing the built-in methods).
-            </p>
-            <p>When generating the source code for a wrapper class, you need to specify:</p>
-            <ul>
-              <li>the fully qualified name of the class to generate
-              </li>
-              <li>the list of custom levels to support and their <tt>intLevel</tt> relative strength
-              </li>
-              <li>whether to extend <tt>Logger</tt> (and keep the existing built-in methods)
-                or have only methods for the custom log levels
-              </li>
-            </ul>
-            <p>You would then include the generated source code in the project
-              where you want to use custom log levels.</p>
-          </subsection>
-          <a name="ExampleUsage" />
-          <subsection name="Example Usage of a Generated Logger Wrapper">
-            <p>
-              Here is an example of how one would use a generated logger wrapper with
-              custom levels DIAG, NOTICE and VERBOSE:
-            </p>
-            <pre class="prettyprint linenums">
-// ExtLogger is a generated logger wrapper
-import com.mycompany.myproject.ExtLogger;
-
-public class MyService {
-    // instead of Logger logger = LogManager.getLogger(MyService.class):
-    private static final ExtLogger logger = ExtLogger.create(MyService.class);
-
-    public void demoExtendedLogger() {
-        // ...
-        logger.trace("the built-in TRACE level");
-        logger.verbose("a custom level: a VERBOSE message");
-        logger.debug("the built-in DEBUG level");
-        logger.notice("a custom level: a NOTICE message");
-        logger.info("the built-in INFO level");
-        logger.diag("a custom level: a DIAG message");
-        logger.warn("the built-in WARN level");
-        logger.error("the built-in ERROR level");
-        logger.fatal("the built-in FATAL level");
-        logger.notice("java 8 lambda expression only executed if NOTICE is enabled: {}", () -> someMethod());
-        // ...
-    }
-    ...
-}</pre>
-          </subsection>
-          <a name="CodeGen" />
-          <subsection name="Generating Extended Loggers">
-            <p>
-              Use the following command to generate a logger wrapper that adds methods to the built-in ones:
-            </p>
-            <pre class="prettyprint">
-java -cp log4j-core-${Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.ExtendedLoggerGenerator \
-        com.mycomp.ExtLogger DIAG=350 NOTICE=450 VERBOSE=550 > com/mycomp/ExtLogger.java</pre>
-            <p>
-              This will generate source code for a logger wrapper that has the convenience methods
-              for the built-in levels <em>as well as</em> the specified custom levels. The tool prints the
-              generated source code to the console.
-              By appending " &gt; <em>filename</em>" the output can be redirected to a file.
-            </p><p>
-              NOTE: Prior to log4j-2.9, this tool was an inner class <tt>Generate${dollar}ExtendedLogger</tt>.<br/>
-               Under the bash shell on Unix/Mac/Linux the dollar character ${dollar} needs to be escaped, so the class name should
-               be between single quotes 'org.apache.logging.log4j.core.tools.Generate${dollar}ExtendedLogger’.
-            </p>
-          </subsection>
-          <subsection name="Generating Custom Loggers">
-            <p>
-              Use the following command to generate a logger wrapper that hides the built-in levels and has only custom levels:
-            </p>
-            <pre class="prettyprint">
-java -cp log4j-core-${Log4jReleaseVersion}.jar org.apache.logging.log4j.core.tools.CustomLoggerGenerator \
-        com.mycomp.MyLogger DEFCON1=350 DEFCON2=450 DEFCON3=550 > com/mycomp/MyLogger.java</pre>
-            <p>
-              This will generate source code for a logger wrapper that <em>only</em> has convenience
-              methods for the specified custom levels, <em>not</em> for the built-in levels.
-              The tool prints the generated source code to the console.
-              By appending " &gt; <em>filename</em>" the output can be redirected to a file.
-            </p><p>
-              NOTE: Prior to log4j-2.9, this tool was an inner class <tt>Generate${dollar}ExtendedLogger</tt>.<br/>
-               Under the bash shell on Unix/Mac/Linux the dollar character ${dollar} needs to be escaped, so the class name should
-               be between single quotes 'org.apache.logging.log4j.core.tools.Generate${dollar}CustomLogger’.
-            </p>
-          </subsection>
-      </section>
-
-    </body>
-</document>


[4/8] logging-log4j2 git commit: LOG4J2-1802: Convert JMX manual page to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert JMX manual page 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/a15df802
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/a15df802
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/a15df802

Branch: refs/heads/master
Commit: a15df802c4fd253e9cddac18e8674cddca806213
Parents: 86e8caa
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 16:16:29 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/jmx.adoc | 208 +++++++++++++++++++++++++++++++++
 src/site/xdoc/manual/jmx.xml.vm   | 189 ------------------------------
 2 files changed, 208 insertions(+), 189 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a15df802/src/site/asciidoc/manual/jmx.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/jmx.adoc b/src/site/asciidoc/manual/jmx.adoc
new file mode 100644
index 0000000..057134f
--- /dev/null
+++ b/src/site/asciidoc/manual/jmx.adoc
@@ -0,0 +1,208 @@
+////
+    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
+
+        https://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.
+////
+= JMX
+Remko Popma <re...@yahoo.com>
+
+Log4j 2 has built-in support for JMX. The StatusLogger, ContextSelector,
+and all LoggerContexts, LoggerConfigs and Appenders are instrumented
+with MBeans and can be remotely monitored and controlled.
+
+Also included is a simple client GUI that can be used to monitor the
+StatusLogger output, as well as to remotely reconfigure Log4j with a
+different configuration file, or to edit the current configuration
+directly.
+
+[#Enabling_JMX]
+== Enabling JMX
+
+JMX support is enabled by default. When Log4j initializes, the
+StatusLogger, ContextSelector, and all LoggerContexts, LoggerConfigs and
+Appenders are instrumented with MBeans. To disable JMX completely, and
+prevent these MBeans from being created, specify system property
+`log4j2.disableJmx` to `true` when you start the Java VM.
+
+[#Local]
+== Local Monitoring and Management
+
+To perform local monitoring you don't need to specify any system
+properties. The JConsole tool that is included in the Java JDK can be
+used to monitor your application. Start JConsole by typing
+`$JAVA_HOME/bin/jconsole` in a command shell. For more details,
+see Oracle's documentation on
+https://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html[how
+to use JConsole].
+
+[#Remote]
+== Remote Monitoring and Management
+
+To enable monitoring and management from remote systems, set the
+following system property when starting the Java VM.
+
+`com.sun.management.jmxremote.port=portNum`
+
+In the property above, `portNum` is the port number through which you
+want to enable JMX RMI connections.
+
+For more details, see Oracle's documentation on
+https://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl[Remote
+Monitoring and Management].
+
+[#RMI_GC]
+== RMI impact on Garbage Collection
+
+Be aware that RMI by default triggers a full GC every hour. See the
+https://docs.oracle.com/javase/7/docs/technotes/guides/rmi/sunrmiproperties.html[Oracle
+documentation] for the `sun.rmi.dgc.server.gcInterval` and
+`sun.rmi.dgc.client.gcInterval` properties. The default value of both
+properties is 3600000 milliseconds (one hour). Before Java 6, it was one
+minute.
+
+The two sun.rmi arguments reflect whether your JVM is running in server
+or client mode. If you want to modify the GC interval time it may be
+best to specify both properties to ensure the argument is picked up by
+the JVM.
+
+An alternative may be to disable explicit calls to `System.gc()`
+altogether with `-XX:+DisableExplicitGC`, or (if you are using the CMS
+or G1 collector) add `-XX:+ExplicitGCInvokesConcurrent` to ensure the
+full GCs are done concurrently in parallel with your application instead
+of forcing a stop-the-world collection.
+
+[#Log4j_MBeans]
+== Log4j Instrumented Components
+
+The best way to find out which methods and attributes of the various
+Log4j components are accessible via JMX is to look at the
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/jmx/package-summary.html[Javadoc]
+or by exploring directly in JConsole.
+
+The screenshot below shows the Log4j MBeans in JConsole.
+
+image:../images/jmx-jconsole-mbeans.png[JConsole screenshot of the
+MBeans tab]
+
+[#ClientGUI]
+== Client GUI
+
+Log4j includes a basic client GUI that can be used to monitor the
+StatusLogger output and to remotely modify the Log4j configuration. The
+client GUI can be run as a stand-alone application or as a JConsole
+plug-in.
+
+=== Running the Client GUI as a JConsole Plug-in
+
+To run the Log4j JMX Client GUI as a JConsole Plug-in, start JConsole
+with the following command:
+
+`$JAVA_HOME/bin/jconsole -pluginpath /path/to/log4j-api-{Log4jReleaseVersion}.jar:/path/to/log4j-core-{Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-{Log4jReleaseVersion}.jar`
+
+or on Windows:
+
+`%JAVA_HOME%\bin\jconsole -pluginpath \path\to\log4j-api-{Log4jReleaseVersion}.jar;\path\to\log4j-core-{Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-{Log4jReleaseVersion}.jar`
+
+If you execute the above command and connect to your application, you
+will see an extra "Log4j 2" tab in the JConsole window. This tab
+contains the client GUI, with the StatusLogger selected. The screenshot
+below shows the StatusLogger panel in JConsole.
+
+image:../images/jmx-jconsole-statuslogger.png[JConsole screenshot of the
+StatusLogger display]
+
+=== Remotely Editing the Log4j Configuration
+
+The client GUI also contains a simple editor that can be used to
+remotely change the Log4j configuration.
+
+The screenshot below shows the configuration edit panel in JConsole.
+
+image:../images/jmx-jconsole-editconfig.png[JConsole screenshot of the
+configuration file editor]
+
+The configuration edit panel provides two ways to modify the Log4j
+configuration: specifying a different configuration location URI, or
+modifying the configuration XML directly in the editor panel.
+
+If you specify a different configuration location URI and click the
+"Reconfigure from Location" button, the specified file or resource must
+exist and be readable by the application, or an error will occur and the
+configuration will not change. If an error occurred while processing the
+contents of the specified resource, Log4j will keep its original
+configuration, but the editor panel will show the contents of the file
+you specified.
+
+The text area showing the contents of the configuration file is
+editable, and you can directly modify the configuration in this editor
+panel. Clicking the "Reconfigure with XML below" button will send the
+configuration text to the remote application where it will be used to
+reconfigure Log4j on the fly. This will not overwrite any configuration
+file. Reconfiguring with text from the editor happens in memory only and
+the text is not permanently stored anywhere.
+
+[#ClientStandAlone]
+=== Running the Client GUI as a Stand-alone Application
+
+To run the Log4j JMX Client GUI as a stand-alone application, run the
+following command:
+
+`$JAVA_HOME/bin/java -cp /path/to/log4j-api-{Log4jReleaseVersion}.jar:/path/to/log4j-core-{Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-{Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui <options>`
+
+or on Windows:
+
+`%JAVA_HOME%\bin\java -cp \path\to\log4j-api-{Log4jReleaseVersion}.jar;\path\to\log4j-core-{Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-{Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui <options>`
+
+Where `options` are one of the following:
+
+* `<host>:<port>`
+* `service:jmx:rmi:///jndi/rmi://<host>:<port>/jmxrmi`
+* `service:jmx:rmi://<host>:<port>/jndi/rmi://<host>:<port>/jmxrmi`
+
+The port number must be the same as the portNum specified when you
+started the application you want to monitor.
+
+For example, if you started your application with these options:
+
+....
+com.sun.management.jmxremote.port=33445
+com.sun.management.jmxremote.authenticate=false
+com.sun.management.jmxremote.ssl=false
+....
+
+*(Note that this disables _all_ security so this is not recommended for
+production environments. Oracle's documentation on
+https://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl[Remote
+Monitoring and Management] provides details on how to configure JMX more
+securely with password authentication and SSL.)*
+
+Then you can run the client with this command:
+
+`$JAVA_HOME/bin/java -cp /path/to/log4j-api-{Log4jReleaseVersion}.jar:/path/to/log4j-core-{Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-{Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui localhost:33445`
+
+or on Windows:
+
+`%JAVA_HOME%\bin\java -cp \path\to\log4j-api-{Log4jReleaseVersion}.jar;\path\to\log4j-core-{Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-{Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui localhost:33445`
+
+The screenshot below shows the StatusLogger panel of the client GUI when
+running as a stand-alone application.
+
+image:../images/jmx-standalone-statuslogger.png[JMX GUI screenshot of
+StatusLogger display]
+
+The screenshot below shows the configuration editor panel of the client
+GUI when running as a stand-alone application.
+
+image:../images/jmx-standalone-editconfig.png[JMX GUI screenshot of
+configuration editor]

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/a15df802/src/site/xdoc/manual/jmx.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/jmx.xml.vm b/src/site/xdoc/manual/jmx.xml.vm
deleted file mode 100644
index 89eef0e..0000000
--- a/src/site/xdoc/manual/jmx.xml.vm
+++ /dev/null
@@ -1,189 +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.
--->
-#set($dollar = '$')
-<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>JMX</title>
-		<author email="remkop@yahoo.com">Remko Popma</author>
-    </properties>
-
-    <body>
-      <section name="JMX">
-        <p>
-          Log4j 2 has built-in support for JMX.
-          The StatusLogger, ContextSelector, and all LoggerContexts,
-          LoggerConfigs and Appenders are instrumented with MBeans and can
-          be remotely monitored and controlled.
-        </p>
-        <p>Also included is a simple client GUI that can be used to
-        monitor the StatusLogger output, as well as to remotely reconfigure
-        Log4j with a different configuration file, or to edit the
-        current configuration directly.
-        </p>
-      </section>
-      <section name="Enabling JMX">
-        <a name="Enabling_JMX" />
-        <p>JMX support is enabled by default. When Log4j initializes,
-        the StatusLogger, ContextSelector, and all LoggerContexts,
-          LoggerConfigs and Appenders are instrumented with MBeans.
-        To disable JMX completely, and prevent these MBeans from being created,
-        specify system property <tt>log4j2.disableJmx</tt> to <tt>true</tt> when you start
-        the Java VM.
-        </p>
-		<subsection name="Local Monitoring and Management">
-      <a name="Local" />
-      <p>To perform local monitoring you don't need to specify any system
-        properties. The JConsole tool that is included in the Java JDK can be
-        used to monitor your application. Start JConsole by typing
-        <code>${dollar}JAVA_HOME/bin/jconsole</code> in a command shell.
-        For more details, see Oracle's documentation on
-        <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/management/jconsole.html">how to use JConsole</a>.</p>
-        </subsection>
-		<subsection name="Remote Monitoring and Management">
-      <a name="Remote" />
-      <p>To enable monitoring and management from remote systems, set the following system property when starting the Java VM.
-		</p><p>
-        <code>com.sun.management.jmxremote.port=portNum</code>
-		</p><p>
-        In the property above, <code>portNum</code> is the port number through
-        which you want to enable JMX RMI connections.
-        </p><p>
-        For more details, see Oracle's documentation on
-        <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl">Remote
-        Monitoring and Management</a>.</p>
-        </subsection>
-		<subsection name="RMI impact on Garbage Collection">
-      <a name="RMI_GC" />
-      <p>
-      	Be aware that RMI by default triggers a full GC every hour.
-        See the <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/rmi/sunrmiproperties.html">Oracle
-        documentation</a> for the <code>sun.rmi.dgc.server.gcInterval</code> and <code>sun.rmi.dgc.client.gcInterval</code> properties.
-        The default value of both properties is 3600000 milliseconds (one hour). Before Java 6, it was one minute.
-		  </p><p>
-		    The two sun.rmi arguments reflect whether your JVM is running in server or client mode. 
-		    If you want to modify the GC interval time it may be best to specify both properties to ensure the argument is picked up by the JVM.
-		  </p><p>
-		    An alternative may be to disable explicit calls to <code>System.gc()</code> altogether with 
-		    <code>-XX:+DisableExplicitGC</code>, or (if you are using the CMS or G1 collector)
-		    add <code>-XX:+ExplicitGCInvokesConcurrent</code> to ensure the full GCs are done
-		    concurrently in parallel with your application instead of forcing a stop-the-world collection.
-      </p>
-        </subsection>
-      </section>
-      <section name="Log4j Instrumented Components">
-        <a name="Log4j_MBeans" />
-        <p>The best way to find out which methods and attributes of the various
-      Log4j components are accessible via JMX is to look at the
-      <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/jmx/package-summary.html"
-      >Javadoc</a> or by exploring directly in JConsole.</p>
-      <p>The screenshot below shows the Log4j MBeans in JConsole.</p>
-      <p><img src="../images/jmx-jconsole-mbeans.png" alt="JConsole screenshot of the MBeans tab" /></p>
-      </section>
-      <section name="Client GUI">
-        <a name="ClientGUI" />
-        <p>Log4j includes a basic client GUI that can be used to
-        monitor the StatusLogger output and to remotely modify the Log4j
-        configuration. The client GUI can be run as a stand-alone application
-        or as a JConsole plug-in.</p>
-		<subsection name="Running the Client GUI as a JConsole Plug-in">
-		<p>To run the Log4j JMX Client GUI as a JConsole Plug-in,
-		start JConsole with the following command:
-		</p>
-		<p><code>${dollar}JAVA_HOME/bin/jconsole -pluginpath /path/to/log4j-api-${Log4jReleaseVersion}.jar:/path/to/log4j-core-${Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-${Log4jReleaseVersion}.jar</code></p>
-		<p>or on Windows:</p>
-		<p><code>%JAVA_HOME%\bin\jconsole -pluginpath \path\to\log4j-api-${Log4jReleaseVersion}.jar;\path\to\log4j-core-${Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-${Log4jReleaseVersion}.jar</code></p>
-		<p>If you execute the above command and connect to your application,
-		you will see an extra "Log4j 2" tab in the JConsole window.
-		This tab contains the client GUI, with the StatusLogger selected.
-		The screenshot below shows the StatusLogger panel in JConsole.
-		</p>
-        <p><img src="../images/jmx-jconsole-statuslogger.png" alt="JConsole screenshot of the StatusLogger display" /></p>
-		</subsection>
-		<subsection name="Remotely Editing the Log4j Configuration">
-		<p>The client GUI also contains a simple editor that can be used
-		to remotely change the Log4j configuration.
-		</p><p>
-		The screenshot below shows the configuration edit panel in JConsole.
-		</p>
-        <p><img src="../images/jmx-jconsole-editconfig.png" alt="JConsole screenshot of the configuration file editor" /></p>
-        <p>The configuration edit panel provides two ways to modify
-        the Log4j configuration: specifying a different configuration location
-        URI, or modifying the configuration XML directly in the editor panel.</p>
-        <p>If you specify a different configuration location URI and
-        click the "Reconfigure from Location" button, the specified file
-        or resource must exist and be readable by the application,
-        or an error will occur and the configuration will not change.
-        If an error occurred while processing the contents of the specified resource,
-        Log4j will keep its original configuration, but the editor panel
-        will show the contents of the file you specified. </p>
-        <p>
-        The text area showing the contents of the configuration file is
-        editable, and you can directly modify the configuration in this
-        editor panel. Clicking the "Reconfigure with XML below" button will
-        send the configuration text to the remote application where it
-        will be used to reconfigure Log4j on the fly.
-        This will not overwrite any configuration file.
-        Reconfiguring with text from the editor happens in memory only and
-        the text is not permanently stored anywhere.
-        </p>
-		</subsection>
-		<subsection name="Running the Client GUI as a Stand-alone Application">
-      <a name="ClientStandAlone" />
-      <p>To run the Log4j JMX Client GUI as a stand-alone application,
-		run the following command:
-		</p>
-		<p><code>${dollar}JAVA_HOME/bin/java -cp /path/to/log4j-api-${Log4jReleaseVersion}.jar:/path/to/log4j-core-${Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui &lt;options&gt;</code></p>
-		<p>or on Windows:</p>
-		<p><code>%JAVA_HOME%\bin\java -cp \path\to\log4j-api-${Log4jReleaseVersion}.jar;\path\to\log4j-core-${Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui &lt;options&gt;</code></p>
-		<p>Where <code>options</code> are one of the following:</p>
-		<ul>
-		<li><code>&lt;host&gt;:&lt;port&gt;</code></li>
-		<li><code>service:jmx:rmi:///jndi/rmi://&lt;host&gt;:&lt;port&gt;/jmxrmi</code></li>
-		<li><code>service:jmx:rmi://&lt;host&gt;:&lt;port&gt;/jndi/rmi://&lt;host&gt;:&lt;port&gt;/jmxrmi</code></li>
-		</ul>
-		<p>The port number must be the same as the portNum specified when
-		you started the application you want to monitor.
-		</p>
-		<p>For example, if you started your application with these options:</p>
-		<pre>com.sun.management.jmxremote.port=33445
-com.sun.management.jmxremote.authenticate=false
-com.sun.management.jmxremote.ssl=false</pre>
-		<p><b>(Note that this disables <em>all</em> security so this is not recommended
-		for production environments.
-		Oracle's documentation on
-        <a href="http://docs.oracle.com/javase/7/docs/technotes/guides/management/agent.html#gdenl">Remote
-        Monitoring and Management</a> provides details on how to configure
-        JMX more securely with password authentication and SSL.)</b></p>
-		<p>Then you can run the client with this command:</p>
-		<p><code>${dollar}JAVA_HOME/bin/java -cp /path/to/log4j-api-${Log4jReleaseVersion}.jar:/path/to/log4j-core-${Log4jReleaseVersion}.jar:/path/to/log4j-jmx-gui-${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui localhost:33445</code></p>
-		<p>or on Windows:</p>
-		<p><code>%JAVA_HOME%\bin\java -cp \path\to\log4j-api-${Log4jReleaseVersion}.jar;\path\to\log4j-core-${Log4jReleaseVersion}.jar;\path\to\log4j-jmx-gui-${Log4jReleaseVersion}.jar org.apache.logging.log4j.jmx.gui.ClientGui localhost:33445</code></p>
-		<p>The screenshot below shows the StatusLogger panel of the client
-		GUI when running as a stand-alone application.</p>
-        <p><img src="../images/jmx-standalone-statuslogger.png" alt="JMX GUI screenshot of StatusLogger display" /></p>
-		<p>The screenshot below shows the configuration editor panel of the
-		client GUI when running as a stand-alone application.</p>
-        <p><img src="../images/jmx-standalone-editconfig.png" alt="JMX GUI screenshot of configuration editor" /></p>
-
-		</subsection>
-      </section>
-
-    </body>
-</document>


[8/8] logging-log4j2 git commit: LOG4J2-1802: Convert filters manual page to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert filters manual page 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/0a60a4ad
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/0a60a4ad
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/0a60a4ad

Branch: refs/heads/master
Commit: 0a60a4ad7480e03d1f26bbcaa45a6fad69d9b7c4
Parents: b53b811
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 19:36:02 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/filters.adoc | 848 ++++++++++++++++++++++++++++
 src/site/xdoc/manual/filters.xml      | 879 -----------------------------
 2 files changed, 848 insertions(+), 879 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0a60a4ad/src/site/asciidoc/manual/filters.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/filters.adoc b/src/site/asciidoc/manual/filters.adoc
new file mode 100644
index 0000000..4796c90
--- /dev/null
+++ b/src/site/asciidoc/manual/filters.adoc
@@ -0,0 +1,848 @@
+////
+    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
+
+        https://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.
+////
+= Filters
+Ralph Goers <rg...@apache.org>
+
+Filters allow Log Events to be evaluated to determine if or how they
+should be published. A Filter will be called on one of its `filter`
+methods and will return a `Result`, which is an Enum that has one of 3
+values - `ACCEPT`, `DENY` or `NEUTRAL`.
+
+Filters may be configured in one of four locations:
+
+1.  Context-wide Filters are configured directly in the configuration.
+Events that are rejected by these filters will not be passed to loggers
+for further processing. Once an event has been accepted by a
+Context-wide filter it will not be evaluated by any other Context-wide
+Filters nor will the Logger's Level be used to filter the event. The
+event will be evaluated by Logger and Appender Filters however.
+2.  Logger Filters are configured on a specified Logger. These are
+evaluated after the Context-wide Filters and the Log Level for the
+Logger. Events that are rejected by these filters will be discarded and
+the event will not be passed to a parent Logger regardless of the
+additivity setting.
+3.  Appender Filters are used to determine if a specific Appender should
+handle the formatting and publication of the event.
+4.  Appender Reference Filters are used to determine if a Logger should
+route the event to an appender.
+
+[#BurstFilter]
+== BurstFilter
+
+The BurstFilter provides a mechanism to control the rate at which
+LogEvents are processed by silently discarding events after the maximum
+limit has been reached.
+
+.Burst Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|level
+|String
+|Level of messages to be filtered. Anything at or below
+this level will be filtered out if `maxBurst` has been exceeded. The
+default is WARN meaning any messages that are higher than warn will be
+logged regardless of the size of a burst.
+
+|rate
+|float
+|The average number of events per second to allow.
+
+|maxBurst
+|integer
+|The maximum number of events that can occur before
+events are filtered for exceeding the average rate. The default is 10
+times the rate.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A configuration containing the BurstFilter 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">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#CompositeFilter]
+== CompositeFilter
+
+The CompositeFilter provides a way to specify more than one filter. It
+is added to the configuration as a filters element and contains other
+filters to be evaluated. The filters element accepts no parameters.
+
+A configuration containing the CompositeFilter might look like:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <Filters>
+    <MarkerFilter marker="EVENT" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
+    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
+                            onMatch="ACCEPT" onMismatch="NEUTRAL">
+      <KeyValuePair key="User1" value="DEBUG"/>
+    </DynamicThresholdFilter>
+  </Filters>
+  <Appenders>
+    <File name="Audit" fileName="logs/audit.log">
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+    </File>
+    <RollingFile name="RollingFile" fileName="logs/app.log"
+                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Logger name="EventLogger" level="info">
+      <AppenderRef ref="Audit"/>
+    </Logger>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#DynamicThresholdFilter]
+== DynamicThresholdFilter
+
+The DynamicThresholdFilter allows filtering by log level based on
+specific attributes. For example, if the user's loginId is being
+captured in the ThreadContext Map then it is possible to enable debug
+logging for only that user. If the log event does not contain the
+specified ThreadContext item NEUTRAL will be returned.
+
+.Dynamic Threshold Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|key
+|String
+|The name of the item in the ThreadContext Map to compare.
+
+|defaultThreshold
+|String
+|Level of messages to be filtered. The default
+threshold only applies if the log event contains the specified
+ThreadContext Map item and its value does not match any key in the
+key/value pairs.
+
+|keyValuePair
+|KeyValuePair[]
+|One or more KeyValuePair elements that
+define the matching value for the key and the Level to evaluate when the
+key matches.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+Here is a sample configuration containing the DynamicThresholdFilter:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
+                          onMatch="ACCEPT" onMismatch="NEUTRAL">
+    <KeyValuePair key="User1" value="DEBUG"/>
+  </DynamicThresholdFilter>
+  <Appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log"
+                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#MapFilter]
+== MapFilter
+
+The MapFilter allows filtering against data elements that are in a
+MapMessage.
+
+.Map Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|keyValuePair
+|KeyValuePair[]
+|One or more KeyValuePair elements that
+define the key in the map and the value to match on. If the same key is
+specified more than once then the check for that key will automatically
+be an "or" since a Map can only contain a single value.
+
+|operator
+|String
+|If the operator is "or" then a match by any one of
+the key/value pairs will be considered to be a match, otherwise all the
+key/value pairs must match.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+As in this configuration, the MapFilter can be used to log particular
+events:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+    <KeyValuePair key="eventId" value="Login"/>
+    <KeyValuePair key="eventId" value="Logout"/>
+  </MapFilter>
+  <Appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log"
+                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+This sample configuration will exhibit the same behavior as the
+preceding example since the only logger configured is the root.
+
+[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">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+        <KeyValuePair key="eventId" value="Login"/>
+        <KeyValuePair key="eventId" value="Logout"/>
+      </MapFilter>
+      <AppenderRef ref="RollingFile">
+      </AppenderRef>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+This third sample configuration will exhibit the same behavior as the
+preceding examples since the only logger configured is the root and the
+root is only configured with a single appender reference.
+
+[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">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile">
+        <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+          <KeyValuePair key="eventId" value="Login"/>
+          <KeyValuePair key="eventId" value="Logout"/>
+        </MapFilter>
+      </AppenderRef>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#MarkerFilter]
+== MarkerFilter
+
+The MarkerFilter compares the configured Marker value against the Marker
+that is included in the LogEvent. A match occurs when the Marker name
+matches either the Log Event's Marker or one of its parents.
+
+.Marker Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|marker
+|String
+|The name of the Marker to compare.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A sample configuration that only allows the event to be written by the
+appender if the Marker matches:
+
+[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">
+      <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#RegexFilter]
+== RegexFilter
+
+The RegexFilter allows the formatted or unformatted message to be
+compared against a regular expression.
+
+.Regex Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|regex
+|String
+|The regular expression.
+
+|useRawMsg
+|boolean
+|If true the unformatted message will be used,
+otherwise the formatted message will be used. The default value is
+false.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A sample configuration that only allows the event to be written by the
+appender if it contains the word "test":
+
+[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">
+      <RegexFilter regex=".* test .*" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[[Script]]
+
+The ScriptFilter executes a script that returns true or false.
+
+.Script Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|script
+|Script, ScriptFile or ScriptRef
+|The Script element that specifies the logic to be executed.
+
+|onMatch
+|String
+|Action to take when the script returns true. May be
+ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter returns false. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+.Script Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|configuration
+|Configuration
+|The Configuration that owns this
+ScriptFilter.
+
+|level
+|Level
+|The logging Level associated with the event. Only present
+when configured as a global filter.
+
+|loggerName
+|String
+|The name of the logger. Only present when
+configured as a global filter.
+
+|logEvent
+|LogEvent
+|The LogEvent being processed. Not present when
+configured as a global filter.
+
+|marker
+|Marker
+|The Marker passed on the logging call, if any. Only
+present when configured as a global filter.
+
+|message
+|Message
+|The Message associated with the logging call. Only
+present when configured as a global filter.
+
+|parameters
+|Object[]
+|The parameters passed to the logging call. Only
+present when configured as a global filter. Some Messages include the
+parameters as part of the Message.
+
+|throwable
+|Throwable
+|The Throwable passed to the logging call, if any.
+Only present when configured as a global filter. Som Messages include
+Throwable as part of the Message.
+
+|substitutor
+|StrSubstitutor
+|The StrSubstitutor used to replace lookup variables.
+|===
+
+The sample below shows how to declare script fields and then reference
+them in specific components. See
+link:appenders.html#ScriptCondition[ScriptCondition] for an example of
+how the `Script` element can be used to embed script code directly in
+the configuration.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="ERROR">
+  <Scripts>
+    <ScriptFile name="filter.js" language="JavaScript" path="src/test/resources/scripts/filter.js" charset="UTF-8" />
+    <ScriptFile name="filter.groovy" language="groovy" path="src/test/resources/scripts/filter.groovy" charset="UTF-8" />
+  </Scripts>
+  <Appenders>
+    <List name="List">
+      <PatternLayout pattern="[%-5level] %c{1.} %msg%n"/>
+    </List>
+  </Appenders>
+  <Loggers>
+    <Logger name="TestJavaScriptFilter" level="trace" additivity="false">
+      <AppenderRef ref="List">
+        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
+          <ScriptRef ref="filter.js" />
+        </ScriptFilter>
+      </AppenderRef>
+    </Logger>
+    <Logger name="TestGroovyFilter" level="trace" additivity="false">
+      <AppenderRef ref="List">
+        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
+          <ScriptRef ref="filter.groovy" />
+        </ScriptFilter>
+      </AppenderRef>
+    </Logger>
+    <Root level="trace">
+      <AppenderRef ref="List" />
+    </Root>
+  </Loggers>
+</Configuration>
+          
+----
+
+[#StructuredDataFilter]
+== StructuredDataFilter
+
+The StructuredDataFilter is a MapFilter that also allows filtering on
+the event id, type and message.
+
+.StructuredData Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|keyValuePair
+|KeyValuePair[]
+|One or more KeyValuePair elements that
+define the key in the map and the value to match on. "id", "id.name",
+"type", and "message" should be used to match on the StructuredDataId,
+the name portion of the StructuredDataId, the type, and the formatted
+message respectively. If the same key is specified more than once then
+the check for that key will automatically be an "or" since a Map can
+only contain a single value.
+
+|operator
+|String
+|If the operator is "or" then a match by any one of
+the key/value pairs will be considered to be a match, otherwise all the
+key/value pairs must match.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+As in this configuration, the StructuredDataFilter can be used to log
+particular events:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <StructuredDataFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+    <KeyValuePair key="id" value="Login"/>
+    <KeyValuePair key="id" value="Logout"/>
+  </StructuredDataFilter>
+  <Appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log"
+                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#ThreadContextMapFilter]
+== ThreadContextMapFilter
+
+The ThreadContextMapFilter or ContextMapFilter allows filtering against
+data elements that are in the current context. By default this is the
+ThreadContext Map.
+
+.Context Map Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|keyValuePair
+|KeyValuePair[]
+|One or more KeyValuePair elements that
+define the key in the map and the value to match on. If the same key is
+specified more than once then the check for that key will automatically
+be an "or" since a Map can only contain a single value.
+
+|operator
+|String
+|If the operator is "or" then a match by any one of
+the key/value pairs will be considered to be a match, otherwise all the
+key/value pairs must match.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A configuration containing the ContextMapFilter might look like:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="warn" name="MyApp" packages="">
+  <ContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+    <KeyValuePair key="User1" value="DEBUG"/>
+    <KeyValuePair key="User2" value="WARN"/>
+  </ContextMapFilter>
+  <Appenders>
+    <RollingFile name="RollingFile" fileName="logs/app.log"
+                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+The ContextMapFilter can also be applied to a logger for filtering:
+
+[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">
+      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+      <ContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
+        <KeyValuePair key="foo" value="bar"/>
+        <KeyValuePair key="User2" value="WARN"/>
+      </ContextMapFilter>
+    </Root>
+  </Loggers>
+</Configuration>
+  
+----
+
+[#ThresholdFilter]
+== ThresholdFilter
+
+This filter returns the onMatch result if the level in the LogEvent is
+the same or more specific than the configured level and the onMismatch
+value otherwise. For example, if the ThresholdFilter is configured with
+Level ERROR and the LogEvent contains Level DEBUG then the onMismatch
+value will be returned since ERROR events are more specific than DEBUG.
+
+.Threshold Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|level
+|String
+|A valid Level name to match on.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A sample configuration that only allows the event to be written by the
+appender if the level matches:
+
+[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">
+      <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+[#TimeFilter]
+== TimeFilter
+
+The time filter can be used to restrict filter to only a certain portion
+of the day.
+
+.Time Filter Parameters
+[cols="1m,1,4"]
+|===
+|Parameter Name |Type |Description
+
+|start
+|String
+|A time in HH:mm:ss format.
+
+|end
+|String
+|A time in HH:mm:ss format. Specifying an end time less
+than the start time will result in no log entries being written.
+
+|timezone
+|String
+|The timezone to use when comparing to the event
+timestamp.
+
+|onMatch
+|String
+|Action to take when the filter matches. May be ACCEPT,
+DENY or NEUTRAL. The default value is NEUTRAL.
+
+|onMismatch
+|String
+|Action to take when the filter does not match. May
+be ACCEPT, DENY or NEUTRAL. The default value is DENY.
+|===
+
+A sample configuration that only allows the event to be written by the
+appender from 5:00 to 5:30 am each day using the default timezone:
+
+[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">
+      <TimeFilter start="05:00:00" end="05:30:00" onMatch="ACCEPT" onMismatch="DENY"/>
+      <PatternLayout>
+        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+      <TimeBasedTriggeringPolicy />
+    </RollingFile>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="RollingFile"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/0a60a4ad/src/site/xdoc/manual/filters.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/filters.xml b/src/site/xdoc/manual/filters.xml
deleted file mode 100644
index b70bc00..0000000
--- a/src/site/xdoc/manual/filters.xml
+++ /dev/null
@@ -1,879 +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 Filters</title>
-        <author email="rgoers@apache.org">Ralph Goers</author>
-    </properties>
-
-    <body>
-      <section name="Filters">
-        <p>
-          Filters allow Log Events to be evaluated to determine if or how they should be published. A Filter
-          will be called on one of its filter methods and will return a Result, which is an Enum that has
-          one of 3 values - ACCEPT, DENY or NEUTRAL.
-        </p>
-        <p>
-          Filters may be configured in one of four locations:
-        </p>
-        <ol>
-          <li>Context-wide Filters are configured directly in the configuration. Events that are
-            rejected by these filters will not be passed to loggers for further processing. Once an
-            event has been accepted by a Context-wide filter it will not be evaluated by any other
-            Context-wide Filters nor will the Logger's Level be used to filter the event. The event
-            will be evaluated by Logger and Appender Filters however.
-          </li>
-          <li>Logger Filters are configured on a specified Logger. These are evaluated after the
-            Context-wide Filters and the Log Level for the Logger. Events that are rejected by these
-            filters will be discarded and the event will not be passed to a parent Logger regardless
-            of the additivity setting.
-          </li>
-          <li>Appender Filters are used to determine if a specific Appender should handle the
-            formatting and publication of the event.
-          </li>
-          <li>Appender Reference Filters are used to determine if a Logger should route the event to
-            an appender.
-          </li>
-        </ol>
-        <a name="BurstFilter"/>
-        <subsection name="BurstFilter">
-          <p>
-            The BurstFilter provides a mechanism to control the rate at which LogEvents are processed by
-            silently discarding events after the maximum limit has been reached.
-          </p>
-          <table>
-            <caption align="top">Burst Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>level</td>
-              <td>String</td>
-              <td>Level of messages to be filtered. Anything at or below this level will be
-                filtered out if <code>maxBurst</code> has been exceeded. The default is
-                WARN meaning any messages that are higher than warn will be logged
-                regardless of the size of a burst.
-              </td>
-            </tr>
-            <tr>
-              <td>rate</td>
-              <td>float</td>
-              <td>The average number of events per second to allow.</td>
-            </tr>
-            <tr>
-              <td>maxBurst</td>
-              <td>integer</td>
-              <td>The maximum number of events that can occur before events are filtered for exceeding the
-                average rate. The default is 10 times the rate.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A configuration containing the BurstFilter 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">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="CompositeFilter"/>
-        <subsection name="CompositeFilter">
-          <p>
-            The CompositeFilter provides a way to specify more than one filter. It is added to the
-            configuration as a filters element and contains other filters to be evaluated. The filters
-            element accepts no parameters.
-          </p>
-          <p>
-            A configuration containing the CompositeFilter might look like:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
-  <Filters>
-    <MarkerFilter marker="EVENT" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
-    <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
-                            onMatch="ACCEPT" onMismatch="NEUTRAL">
-      <KeyValuePair key="User1" value="DEBUG"/>
-    </DynamicThresholdFilter>
-  </Filters>
-  <Appenders>
-    <File name="Audit" fileName="logs/audit.log">
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-    </File>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Logger name="EventLogger" level="info">
-      <AppenderRef ref="Audit"/>
-    </Logger>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="DynamicThresholdFilter"/>
-        <subsection name="DynamicThresholdFilter">
-          <p>
-            The DynamicThresholdFilter allows filtering by log level based on specific attributes. For example,
-            if the user's loginId is being captured in the ThreadContext Map then it is possible to enable
-            debug logging for only that user. If the log event does not contain the specified ThreadContext item
-            NEUTRAL will be returned.
-          </p>
-          <table>
-            <caption align="top">Dynamic Threshold Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>key</td>
-              <td>String</td>
-              <td>The name of the item in the ThreadContext Map to compare.</td>
-            </tr>
-            <tr>
-              <td>defaultThreshold</td>
-              <td>String</td>
-              <td>Level of messages to be filtered. The default threshold only applies if the log event contains
-                the specified ThreadContext Map item and its value does not match any key in
-                the key/value pairs.
-              </td>
-            </tr>
-            <tr>
-              <td>keyValuePair</td>
-              <td>KeyValuePair[]</td>
-              <td>One or more KeyValuePair elements that define the matching value for the key and the Level
-                to evaluate when the key matches.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            Here is a sample configuration containing the DynamicThresholdFilter:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
-  <DynamicThresholdFilter key="loginId" defaultThreshold="ERROR"
-                          onMatch="ACCEPT" onMismatch="NEUTRAL">
-    <KeyValuePair key="User1" value="DEBUG"/>
-  </DynamicThresholdFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="MapFilter"/>
-        <subsection name="MapFilter">
-          <p>
-            The MapFilter allows filtering against data elements that are in a MapMessage.
-          </p>
-          <table>
-            <caption align="top">Map Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>keyValuePair</td>
-              <td>KeyValuePair[]</td>
-              <td>One or more KeyValuePair elements that define the key in the map and the value to match on. If the
-              same key is specified more than once then the check for that key will automatically be an "or" since
-              a Map can only contain a single value.</td>
-            </tr>
-            <tr>
-              <td>operator</td>
-              <td>String</td>
-              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
-                a match, otherwise all the key/value pairs must match.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            As in this configuration, the MapFilter can be used to log particular events:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
-  <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-    <KeyValuePair key="eventId" value="Login"/>
-    <KeyValuePair key="eventId" value="Logout"/>
-  </MapFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-          <p>
-            This sample configuration will exhibit the same behavior as the preceding example since the only
-            logger configured is the root.
-          </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">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-        <KeyValuePair key="eventId" value="Login"/>
-        <KeyValuePair key="eventId" value="Logout"/>
-      </MapFilter>
-      <AppenderRef ref="RollingFile">
-      </AppenderRef>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-          <p>
-            This third sample configuration will exhibit the same behavior as the preceding examples since the only
-            logger configured is the root and the root is only configured with a single appender reference.
-          </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">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile">
-        <MapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-          <KeyValuePair key="eventId" value="Login"/>
-          <KeyValuePair key="eventId" value="Logout"/>
-        </MapFilter>
-      </AppenderRef>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="MarkerFilter"/>
-        <subsection name="MarkerFilter">
-          <p>
-            The MarkerFilter compares the configured Marker value against the Marker that is included
-            in the LogEvent. A match occurs when the Marker name matches either the Log Event's Marker
-            or one of its parents.
-          </p>
-          <table>
-            <caption align="top">Marker Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>marker</td>
-              <td>String</td>
-              <td>
-                The name of the Marker to compare.
-              </td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A sample configuration that only allows the event to be written by the appender if the Marker matches:
-          </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">
-      <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="DENY"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="RegexFilter"/>
-        <subsection name="RegexFilter">
-           <p>
-            The RegexFilter allows the formatted or unformatted message to be compared against a regular expression.
-          </p>
-          <table>
-            <caption align="top">Regex Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>regex</td>
-              <td>String</td>
-              <td>
-                The regular expression.
-              </td>
-            </tr>
-            <tr>
-              <td>useRawMsg</td>
-              <td>boolean</td>
-              <td>If true the unformatted message will be used, otherwise the formatted message will be used. The
-                default value is false.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A sample configuration that only allows the event to be written by the appender if it contains the word
-            "test":
-          </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">
-      <RegexFilter regex=".* test .*" onMatch="ACCEPT" onMismatch="DENY"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="Script"/>
-        <subsection name="Script">
-          <p>
-            The ScriptFilter executes a script that returns true or false.
-          </p>
-          <table>
-            <caption align="top">Script Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>script</td>
-              <td>Script, ScriptFile or ScriptRef</td>
-              <td>The Script element that specifies the logic to be executed.
-              </td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the script returns true. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter returns false. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <table>
-            <caption align="top">Script Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>configuration</td>
-              <td>Configuration</td>
-              <td>The Configuration that owns this ScriptFilter.</td>
-            </tr>
-            <tr>
-              <td>level</td>
-              <td>Level</td>
-              <td>The logging Level associated with the event. Only present when configured as a global filter.</td>
-            </tr>
-            <tr>
-              <td>loggerName</td>
-              <td>String</td>
-              <td>The name of the logger. Only present when configured as a global filter.</td>
-            </tr>
-            <tr>
-              <td>logEvent</td>
-              <td>LogEvent</td>
-              <td>The LogEvent being processed. Not present when configured as a global filter.</td>
-            </tr>
-            <tr>
-              <td>marker</td>
-              <td>Marker</td>
-              <td>The Marker passed on the logging call, if any. Only present when configured as a global filter.</td>
-            </tr>
-            <tr>
-              <td>message</td>
-              <td>Message</td>
-              <td>The Message associated with the logging call. Only present when configured as a global filter.</td>
-            </tr>
-            <tr>
-              <td>parameters</td>
-              <td>Object[]</td>
-              <td>The parameters passed to the logging call. Only present when configured as a global filter.
-                Some Messages include the parameters as part of the Message.
-              </td>
-            </tr>
-            <tr>
-              <td>throwable</td>
-              <td>Throwable</td>
-              <td>The Throwable passed to the logging call, if any. Only present when configured as a global filter.
-                Som Messages include Throwable as part of the Message.
-              </td>
-            </tr>
-            <tr>
-              <td>substitutor</td>
-              <td>StrSubstitutor</td>
-              <td>The StrSubstitutor used to replace lookup variables.</td>
-            </tr>
-          </table>
-          <p>
-            The sample below shows how to declare script fields and then reference them in specific components.
-            See <a href="appenders.html#ScriptCondition">ScriptCondition</a> for an example of how the
-            <tt>Script</tt> element can be used to embed script code directly in the configuration.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="ERROR">
-  <Scripts>
-    <ScriptFile name="filter.js" language="JavaScript" path="src/test/resources/scripts/filter.js" charset="UTF-8" />
-    <ScriptFile name="filter.groovy" language="groovy" path="src/test/resources/scripts/filter.groovy" charset="UTF-8" />
-  </Scripts>
-  <Appenders>
-    <List name="List">
-      <PatternLayout pattern="[%-5level] %c{1.} %msg%n"/>
-    </List>
-  </Appenders>
-  <Loggers>
-    <Logger name="TestJavaScriptFilter" level="trace" additivity="false">
-      <AppenderRef ref="List">
-        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
-          <ScriptRef ref="filter.js" />
-        </ScriptFilter>
-      </AppenderRef>
-    </Logger>
-    <Logger name="TestGroovyFilter" level="trace" additivity="false">
-      <AppenderRef ref="List">
-        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
-          <ScriptRef ref="filter.groovy" />
-        </ScriptFilter>
-      </AppenderRef>
-    </Logger>
-    <Root level="trace">
-      <AppenderRef ref="List" />
-    </Root>
-  </Loggers>
-</Configuration>
-          ]]></pre>
-        </subsection>
-        <a name="StructuredDataFilter"/>
-        <subsection name="StructuredDataFilter">
-          <p>
-            The StructuredDataFilter is a MapFilter that also allows filtering on the event id, type and message.
-          </p>
-          <table>
-            <caption align="top">StructuredData Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>keyValuePair</td>
-              <td>KeyValuePair[]</td>
-              <td>One or more KeyValuePair elements that define the key in the map and the value to match on. "id",
-                "id.name", "type", and "message" should be used to match on the StructuredDataId, the name
-                portion of the StructuredDataId, the type, and the formatted message respectively. If the
-                same key is specified more than once then the check for that key will automatically be an "or" since
-                a Map can only contain a single value.
-              </td>
-            </tr>
-            <tr>
-              <td>operator</td>
-              <td>String</td>
-              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
-                a match, otherwise all the key/value pairs must match.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            As in this configuration, the StructuredDataFilter can be used to log particular events:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
-  <StructuredDataFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-    <KeyValuePair key="id" value="Login"/>
-    <KeyValuePair key="id" value="Logout"/>
-  </StructuredDataFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="ThreadContextMapFilter"/>
-        <subsection name="ThreadContextMapFilter (or ContextMapFilter)">
-          <p>
-            The ThreadContextMapFilter or ContextMapFilter allows filtering against data elements that are in the
-            current context. By default this is the ThreadContext Map.
-          </p>
-          <table>
-            <caption align="top">Context Map Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>keyValuePair</td>
-              <td>KeyValuePair[]</td>
-              <td>One or more KeyValuePair elements that define the key in the map and the value to match on. If the
-                same key is specified more than once then the check for that key will automatically be an "or" since
-                a Map can only contain a single value.</td>
-            </tr>
-            <tr>
-              <td>operator</td>
-              <td>String</td>
-              <td>If the operator is "or" then a match by any one of the key/value pairs will be considered to be
-                a match, otherwise all the key/value pairs must match.</td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A configuration containing the ContextMapFilter might look like:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="warn" name="MyApp" packages="">
-  <ContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-    <KeyValuePair key="User1" value="DEBUG"/>
-    <KeyValuePair key="User2" value="WARN"/>
-  </ContextMapFilter>
-  <Appenders>
-    <RollingFile name="RollingFile" fileName="logs/app.log"
-                 filePattern="logs/app-%d{MM-dd-yyyy}.log.gz">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-          <p>
-            The ContextMapFilter can also be applied to a logger for filtering:
-          </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">
-      <BurstFilter level="INFO" rate="16" maxBurst="100"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-      <ContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
-        <KeyValuePair key="foo" value="bar"/>
-        <KeyValuePair key="User2" value="WARN"/>
-      </ContextMapFilter>
-    </Root>
-  </Loggers>
-</Configuration>
-  ]]></pre>
-        </subsection>
-        <a name="ThresholdFilter"/>
-        <subsection name="ThresholdFilter">
-           <p>
-            This filter returns the onMatch result if the level in the LogEvent is the same or more specific
-            than the configured level and the onMismatch value otherwise. For example, if the ThresholdFilter
-            is configured with Level ERROR and the LogEvent contains Level DEBUG then the onMismatch value will
-            be returned since ERROR events are more specific than DEBUG.
-          </p>
-          <table>
-            <caption align="top">Threshold Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>level</td>
-              <td>String</td>
-              <td>
-                A valid Level name to match on.
-              </td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A sample configuration that only allows the event to be written by the appender if the level matches:
-          </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">
-      <ThresholdFilter level="TRACE" onMatch="ACCEPT" onMismatch="DENY"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-        <a name="TimeFilter"/>
-        <subsection name="TimeFilter">
-           <p>
-            The time filter can be used to restrict filter to only a certain portion of the day.
-          </p>
-          <table>
-            <caption align="top">Time Filter Parameters</caption>
-            <tr>
-              <th>Parameter Name</th>
-              <th>Type</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>start</td>
-              <td>String</td>
-              <td>
-                A time in HH:mm:ss format.
-              </td>
-            </tr>
-            <tr>
-              <td>end</td>
-              <td>String</td>
-              <td>
-                A time in HH:mm:ss format. Specifying an end time less than the start time will result in no
-                log entries being written.
-              </td>
-            </tr>
-            <tr>
-              <td>timezone</td>
-              <td>String</td>
-              <td>
-                The timezone to use when comparing to the event timestamp.
-              </td>
-            </tr>
-            <tr>
-              <td>onMatch</td>
-              <td>String</td>
-              <td>Action to take when the filter matches. May be ACCEPT, DENY or NEUTRAL. The default value is NEUTRAL.</td>
-            </tr>
-            <tr>
-              <td>onMismatch</td>
-              <td>String</td>
-              <td>Action to take when the filter does not match. May be ACCEPT, DENY or NEUTRAL. The default value is
-                DENY.</td>
-            </tr>
-          </table>
-          <p>
-            A sample configuration that only allows the event to be written by the appender from 5:00 to 5:30 am each
-            day using the default timezone:
-          </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">
-      <TimeFilter start="05:00:00" end="05:30:00" onMatch="ACCEPT" onMismatch="DENY"/>
-      <PatternLayout>
-        <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-      <TimeBasedTriggeringPolicy />
-    </RollingFile>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="RollingFile"/>
-    </Root>
-  </Loggers>
-</Configuration>]]></pre>
-        </subsection>
-      </section>
-    </body>
-</document>


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

Posted by ma...@apache.org.
http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b53b8118/src/site/xdoc/manual/configuration.xml.vm
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/configuration.xml.vm b/src/site/xdoc/manual/configuration.xml.vm
deleted file mode 100644
index 8acdd40..0000000
--- a/src/site/xdoc/manual/configuration.xml.vm
+++ /dev/null
@@ -1,2383 +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.
--->
-
-#set($dollar = '$')
-
-<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>Configuring Log4j 2</title>
-        <author email="rgoers@apache.org">Ralph Goers</author>
-    </properties>
-
-    <body>
-      <section name="Configuration">
-        #if (!$alignedFileName)
-            #set ($isPDF = true)
-        #else
-            #set ($isPDF = false)
-        #end
-        <p>Inserting log requests into the application code requires a fair
-          amount of planning and effort. Observation shows that approximately 4
-          percent of code is dedicated to logging. Consequently, even moderately
-          sized applications will have thousands of logging statements embedded
-          within their code.  Given their number, it becomes imperative to
-          manage these log statements without the need to modify them manually.
-        </p>
-        <p>
-          Configuration of Log4j 2 can be accomplished in 1 of 4 ways:
-        </p>
-          <ol>
-            <li>Through a configuration file written in XML, JSON, YAML, or properties format.</li>
-            <li>Programmatically, by creating a ConfigurationFactory and Configuration implementation.</li>
-            <li>Programmatically, by calling the APIs exposed in the Configuration interface to add
-              components to the default configuration.</li>
-            <li>Programmatically, by calling methods on the internal Logger class.</li>
-          </ol>
-        <p>
-          This page focuses primarily on configuring Log4j through a configuration file. Information on
-          programmatically configuring Log4j can be found at <a href="./extending.html">Extending Log4j 2</a>
-          and <a href="customconfig.html">Programmatic Log4j Configuration</a>.
-        </p>
-        <p>
-          Note that unlike Log4j 1.x, the public Log4j 2 API does not expose methods to add, modify or remove
-          appenders and filters or manipulate the configuration in any way.
-        </p>
-        <a name="AutomaticConfiguration"/>
-        <subsection name="Automatic Configuration">
-          <p>
-            Log4j has the ability to automatically configure itself during initialization.
-            When Log4j starts it will locate all the ConfigurationFactory plugins and arrange them in weighted
-            order from highest to lowest. As delivered, Log4j contains four ConfigurationFactory implementations:
-            one for JSON, one for YAML, one for properties, and one for XML.
-          </p>
-            <ol>
-              <li>Log4j will inspect the <code>"log4j.configurationFile"</code> system property and, if set,  will attempt to
-                load the configuration using the <code>ConfigurationFactory</code> that matches the file
-                extension.</li>
-              <li>If no system property is set the properties ConfigurationFactory will look for
-                <code>log4j2-test.properties</code> in the classpath.</li>
-              <li>If no such file is found the YAML ConfigurationFactory will look for
-                <code>log4j2-test.yaml</code> or <code>log4j2-test.yml</code> in the classpath.</li>
-              <li>If no such file is found the JSON ConfigurationFactory will look for
-                <code>log4j2-test.json</code> or <code>log4j2-test.jsn</code> in the classpath.</li>
-              <li>If no such file is found the XML ConfigurationFactory will look for
-                <code>log4j2-test.xml</code> in the classpath.</li>
-              <li>If a test file cannot be located the properties ConfigurationFactory will look for
-                <code>log4j2.properties</code> on the classpath.</li>
-              <li>If a properties file cannot be located the YAML ConfigurationFactory will look for
-                <code>log4j2.yaml</code> or <code>log4j2.yml</code> on the classpath.</li>
-              <li>If a YAML file cannot be located the JSON ConfigurationFactory will look for
-                <code>log4j2.json</code> or <code>log4j2.jsn</code> on the classpath.</li>
-              <li>If a JSON file cannot be located the XML ConfigurationFactory will try to locate
-                <code>log4j2.xml</code> on the classpath.</li>
-              <li>If no configuration file could be located the <code>DefaultConfiguration</code> will
-                be used. This will cause logging output to go to the console.</li>
-            </ol>
-          <p>An example application named <code>MyApp</code> that uses log4j can be used to illustrate how
-            this is done.
-          </p>
-<pre class="prettyprint linenums"><![CDATA[
-import com.foo.Bar;
-
-// Import log4j classes.
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-public class MyApp {
-
-    // Define a static logger variable so that it references the
-    // Logger instance named "MyApp".
-    private static final Logger logger = LogManager.getLogger(MyApp.class);
-
-    public static void main(final String... args) {
-
-        // Set up a simple configuration that logs on the console.
-
-        logger.trace("Entering application.");
-        Bar bar = new Bar();
-        if (!bar.doIt()) {
-            logger.error("Didn't do it.");
-        }
-        logger.trace("Exiting application.");
-    }
-}
-]]></pre>
-          <p>
-            <code>MyApp</code> begins by importing log4j related classes. It
-            then defines a static logger variable with the name <code>MyApp</code>
-            which happens to be the fully qualified name of the class.
-          </p>
-          <p>
-            <code>MyApp</code> uses the <code>Bar</code> class defined in the package<code>com.foo</code>.
-          </p>
-<pre class="prettyprint linenums"><![CDATA[
-package com.foo;
-import org.apache.logging.log4j.Logger;
-import org.apache.logging.log4j.LogManager;
-
-public class Bar {
-  static final Logger logger = LogManager.getLogger(Bar.class.getName());
-
-  public boolean doIt() {
-    logger.entry();
-    logger.error("Did it again!");
-    return logger.exit(false);
-  }
-}
-]]></pre>
-          <p>
-            Log4j will provide a default configuration if it cannot locate a configuration file. The default
-            configuration, provided in the DefaultConfiguration class, will set up:
-          </p>
-            <ul>
-              <li>A <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/appender/ConsoleAppender.html">ConsoleAppender</a>
-                attached to the root logger.</li>
-              <li>A <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html">PatternLayout</a>
-                set to the pattern "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" attached to the ConsoleAppender</li>
-            </ul>
-          <p>
-            Note that by default Log4j assigns the root logger to <code>Level.ERROR</code>.
-          </p>
-          <p>The output of MyApp would be similar to:
-          </p>
-<pre><![CDATA[
-17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
-17:13:01.540 [main] ERROR MyApp - Didn't do it.
-]]></pre>
-          <p>
-            As was described previously, Log4j will first attempt to configure itself from configuration files. A
-            configuration equivalent to the default would look like:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-  <Appenders>
-    <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Root level="error">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
-]]></pre>
-          <p>
-            Once the file above is placed into the classpath as log4j2.xml you will get results identical to
-            those listed above. Changing the root level to trace will result in results similar to:
-          </p>
-          <pre><![CDATA[
-17:13:01.540 [main] TRACE MyApp - Entering application.
-17:13:01.540 [main] TRACE com.foo.Bar - entry
-17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
-17:13:01.540 [main] TRACE com.foo.Bar - exit with (false)
-17:13:01.540 [main] ERROR MyApp - Didn't do it.
-17:13:01.540 [main] TRACE MyApp - Exiting application.
-]]></pre>
-          <p>
-            Note that status logging is disabled when the default configuration is used.
-          </p>
-        </subsection>
-        <a name="Additivity"/>
-        <subsection name="Additivity">
-          <p>
-            Perhaps it is desired to eliminate all the TRACE output from everything except <code>com.foo.Bar</code>.
-            Simply changing the log level would not accomplish the task. Instead, the solution is to
-            add a new logger definition to the configuration:
-          </p>
-            <pre class="prettyprint linenums"><![CDATA[
-<Logger name="com.foo.Bar" level="TRACE"/>
-<Root level="ERROR">
-  <AppenderRef ref="STDOUT">
-</Root>
-]]></pre>
-          <p>
-            With this configuration all log events from <code>com.foo.Bar</code> will be recorded while only error
-            events will be recorded from all other components.
-          </p>
-          <p>
-            In the previous example all the events from <code>com.foo.Bar</code> were still written to the Console. This is
-            because the logger for <code>com.foo.Bar</code> did not have any appenders configured while its parent did. In fact,
-            the following configuration
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-  <Appenders>
-    <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Logger name="com.foo.Bar" level="trace">
-      <AppenderRef ref="Console"/>
-    </Logger>
-    <Root level="error">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
-]]></pre>
-          <p>would result in</p>
-          <pre><![CDATA[
-17:13:01.540 [main] TRACE com.foo.Bar - entry
-17:13:01.540 [main] TRACE com.foo.Bar - entry
-17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
-17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
-17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
-17:13:01.540 [main] ERROR MyApp - Didn't do it.
-]]></pre>
-          <p>Notice that the trace messages from <code>com.foo.Bar</code> appear twice. This is because the appender associated
-            with logger <code>com.foo.Bar</code> is first used, which writes the first instance to the Console. Next, the parent
-            of <code>com.foo.Bar</code>, which in this case is the root logger, is referenced. The event is then passed to its
-            appender, which is also writes to the Console, resulting in the second instance. This is known as
-            additivity. While additivity can be quite a convenient feature (as in the first previous example where
-            no appender reference needed to be configured), in many cases this behavior is considered undesirable
-            and so it is possible to disable it by setting the additivity attribute on the logger to false:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="WARN">
-  <Appenders>
-    <Console name="Console" target="SYSTEM_OUT">
-      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
-    </Console>
-  </Appenders>
-  <Loggers>
-    <Logger name="com.foo.Bar" level="trace" additivity="false">
-      <AppenderRef ref="Console"/>
-    </Logger>
-    <Root level="error">
-      <AppenderRef ref="Console"/>
-    </Root>
-  </Loggers>
-</Configuration>
-]]></pre>
-          <p>
-            Once an event reaches a logger with its additivity set to false the event will not be passed to
-            any of its parent loggers, regardless of their additivity setting.
-          </p>
-        </subsection>
-        <a name="AutomaticReconfiguration"/>
-        <subsection name="Automatic Reconfiguration">
-          <p>
-            When configured from a File, Log4j has the ability to automatically detect changes to the configuration
-            file and reconfigure itself. If the <code>monitorInterval</code> attribute is specified on the configuration
-            element and is set to a non-zero value then the file will be checked the next time a log event is evaluated
-            and/or logged and the monitorInterval has elapsed since the last check. The example below shows how
-            to configure the attribute so that the configuration file will be checked for changes only after at
-            least 30 seconds have elapsed.  The minimum interval is 5 seconds.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration monitorInterval="30">
-...
-</Configuration>
-]]></pre>
-        </subsection>
-        <a name="ChainsawSupport"/>
-        <subsection name="Chainsaw can automatically process your log files (Advertising appender configurations)">
-          <p>
-            Log4j provides the ability to 'advertise' appender configuration details for all file-based appenders as well
-            as socket-based appenders.  For example, for file-based appenders, the file location and the pattern layout in the file
-            are included in the advertisement.  Chainsaw and other external systems can discover these advertisements and
-            use that information to intelligently process the log file.
-          </p>
-          <p>
-            The mechanism by which an advertisement is exposed, as well as the advertisement format, is specific to each
-            Advertiser implementation.  An external system which would like to work with a specific Advertiser implementation
-            must understand how to locate the advertised configuration as well as the format of the advertisement.  For example,
-            a 'database' Advertiser may store configuration details in a database table.  An external system can read
-            that database table in order to discover the file location and the file format.
-          </p>
-          <p>
-            Log4j provides one Advertiser implementation, a 'multicastdns' Advertiser, which advertises appender configuration
-            details via IP multicast using the <a href="http://jmdns.sourceforge.net">http://jmdns.sourceforge.net</a> library.
-          </p>
-          <p>
-            Chainsaw automatically discovers log4j's multicastdns-generated advertisements and displays those discovered
-            advertisements in Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's classpath).  To begin parsing and tailing
-            a log file provided in an advertisement, just double-click the advertised entry in Chainsaw's Zeroconf tab.
-            Currently, Chainsaw only supports FileAppender advertisements.
-          </p>
-          <p>
-            To advertise an appender configuration:
-          </p>
-            <ul>
-              <li>Add the JmDns library from <a href="http://jmdns.sourceforge.net">http://jmdns.sourceforge.net</a> to the application classpath</li>
-              <li>Set the 'advertiser' attribute of the configuration element to 'multicastdns'</li>
-              <li>Set the 'advertise' attribute on the appender element to 'true'</li>
-              <li>If advertising a FileAppender-based configuration, set the 'advertiseURI' attribute on the appender element to an appropriate URI</li>
-            </ul>
-          <p>
-            FileAppender-based configurations require an additional 'advertiseURI' attribute to be specified on the appender.
-            The 'advertiseURI' attribute provides Chainsaw with information on how the file can be accessed.
-            For example, the file may be remotely accessible to Chainsaw via ssh/sftp by specifying a Commons VFS
-            (<a href="http://commons.apache.org/proper/commons-vfs/">http://commons.apache.org/proper/commons-vfs/</a>) sftp:// URI,
-            an http:// URI may be used if the file is accessible through a web server, or a file:// URI can be specified
-            if accessing the file from a locally-running instance of Chainsaw.
-          </p>
-          <p>
-            Here is an example advertisement-enabled appender configuration which can be used by a locally-running Chainsaw to
-            automatically tail the log file (notice the file:// advertiseURI):
-          </p>
-          <p>
-            <b>Please note, you must add the JmDns library from <a href="http://jmdns.sourceforge.net">http://jmdns.sourceforge.net</a>
-            to your application classpath in order to advertise with the 'multicastdns' advertiser.</b>
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration advertiser="multicastdns">
-...
-</Configuration>
-<Appenders>
-  <File name="File1" fileName="output.log" bufferedIO="false" advertiseURI="file://path/to/output.log" advertise="true">
-  ...
-  </File>
-</Appenders>
-]]></pre>
-</subsection>
-        <a name="ConfigurationSyntax"/>
-        <subsection name="Configuration Syntax">
-          <p>
-            As of version 2.9, for security reasons, Log4j does not process DTD in XML files.
-            If you want to split the configuration in multiple files, use <a href="#XInclude">XInclude</a> or
-            <a href="#CompositeConfiguration">Composite Configuration</a>.
-          </p>
-          <p>
-            As the previous examples have shown as well as those to follow, Log4j allows you to easily
-            redefine logging behavior without needing to modify your application. It is possible to
-            disable logging for certain parts of the application, log only when specific criteria are met such
-            as the action being performed for a specific user, route output to Flume or a log reporting system,
-            etc. Being able to do this requires understanding the syntax of the configuration files.
-          </p>
-          <p>
-            The configuration element in the XML file accepts several attributes:
-          </p>
-            <table>
-              <tr>
-                <th>Attribute Name</th>
-                <th>Description</th>
-              </tr>
-              <tr>
-                <td>advertiser</td>
-                <td>(Optional) The Advertiser plugin name which will be used to advertise individual
-                FileAppender or SocketAppender configurations.  The only Advertiser plugin provided is 'multicastdns".</td>
-              </tr>
-              <tr>
-                <td>dest</td>
-                <td>Either "err", which will send output to stderr, or a file path or URL.</td>
-              </tr>
-
-              <tr>
-                <td>monitorInterval</td>
-                <td>The minimum amount of time, in seconds, that must elapse before the file configuration
-                  is checked for changes.</td>
-              </tr>
-              <tr>
-                <td>name</td>
-                <td>The name of the configuration.</td>
-              </tr>
-              <tr>
-                <td>packages</td>
-                <td>A comma separated list of package names to search for plugins. Plugins are only loaded
-                  once per classloader so changing this value may not have any effect upon reconfiguration.</td>
-              </tr>
-              <tr>
-                <td>schema</td>
-                <td>Identifies the location for the classloader to located the XML Schema to use to validate
-                  the configuration. Only valid when strict is set to true. If not set no schema validation
-                  will take place.</td>
-              </tr>
-              <tr>
-                 <td>shutdownHook</td>
-                 <td>Specifies whether or not Log4j should automatically shutdown when the JVM shuts down. The
-                 shutdown hook is enabled by default but may be disabled by setting this attribute to "disable"</td>
-              </tr>
-              <tr>
-                 <td>shutdownTimeout</td>
-                 <td>Specifies how many milliseconds appenders and background tasks will get to shutdown when the JVM shuts
-                 down. Default is zero which mean that each appender uses its default timeout, and don't wait for background
-                 tasks. Not all appenders will honor this, it is a hint and not an absolute guarantee that the shutdown
-                 procedure will not take longer. Setting this too low increase the risk of losing outstanding log events
-                 not yet written to the final destination. See <a class="javadoc"
-                 href="../log4j-core/target/site/apidocs/org/apache/logging/log4j/core/LoggerContext.html${esc.hash}stop(long, java.util.concurrent.TimeUnit)">LoggerContext.stop(long,
-                     java.util.concurrent.TimeUnit)</a>.
-                  (Not used if <tt>shutdownHook</tt> is set to "disable".)</td>
-              </tr>
-              <tr>
-                <td>status</td>
-                <td><p>The level of internal Log4j events that should be logged to the console.
-                Valid values for this attribute are "trace", "debug", "info", "warn", "error" and "fatal".
-                Log4j will log details about initialization, rollover and other internal actions to the status logger.
-                Setting <tt>status="trace"</tt> is one of the first tools available to you if you need to
-                troubleshoot log4j.
-                </p><p>
-                  (Alternatively, setting system property <tt>log4j2.debug</tt> will also print internal Log4j2 logging
-                  to the console, including internal logging that took place before the configuration file was found.)
-                </p></td>
-              </tr>
-              <tr>
-                <td>strict</td>
-                <td>Enables the use of the strict XML format. Not supported in JSON configurations.</td>
-              </tr>
-              <tr>
-                <td>verbose</td>
-                <td>Enables diagnostic information while loading plugins.</td>
-              </tr>
-            </table>
-          <a name="XML"/>
-          <p>
-            Log4j can be configured using two XML flavors; concise and strict. The concise format makes
-            configuration very easy as the element names match the components they represent however it
-            cannot be validated with an XML schema. For example, the ConsoleAppender is configured by
-            declaring an XML element named Console under its parent appenders element. However, element
-            and attribute names are are not case sensitive. In addition, attributes can either be specified
-            as an XML attribute or as an XML element that has no attributes and has a text value. So
-          </p>
-          <pre class="prettyprint"><![CDATA[<PatternLayout pattern="%m%n"/>]]></pre>
-          <p>and</p>
-          <pre class="prettyprint"><![CDATA[
-<PatternLayout>
-  <Pattern>%m%n</Pattern>
-</PatternLayout>]]></pre>
-          <p>
-            are equivalent.
-          </p>
-          <p>
-            The file below represents the structure of an XML configuration, but note
-            that the elements in italics below represent the concise element names that would appear in their place.
-          </p>
-
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>;
-<Configuration>
-  <Properties>
-    <Property name="name1">value</property>
-    <Property name="name2" value="value2"/>
-  </Properties>
-  <]]><i>filter</i>  ... <![CDATA[/>
-  <Appenders>
-    <]]><i>appender</i> ... <![CDATA[>
-      <]]><i>filter</i>  ... <![CDATA[/>
-    </]]><i>appender</i><![CDATA[>
-    ...
-  </Appenders>
-  <Loggers>
-    <Logger name="name1">
-      <]]><i>filter</i>  ... <![CDATA[/>
-    </Logger>
-    ...
-    <Root level="level">
-      <AppenderRef ref="name"/>
-    </Root>
-  </Loggers>
-</Configuration>
-]]></pre>
-          <p>
-            See the many examples on this page for sample appender, filter and logger declarations.
-          </p>
-            <h5>Strict XML</h5>
-          <p>
-            In addition to the concise XML format above, Log4j allows configurations to be specified in a
-            more "normal" XML manner that can be validated using an XML Schema. This is accomplished by
-            replacing the friendly element names above with their object type as shown below. For example,
-            instead of the ConsoleAppender being configuerd using an element named Console it is instead
-            configured as an appender element with a type attribute containing "Console".
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>;
-<Configuration>
-  <Properties>
-    <Property name="name1">value</property>
-    <Property name="name2" value="value2"/>
-  </Properties>
-  <Filter type="type" ... />
-  <Appenders>
-    <Appender type="type" name="name">
-      <Filter type="type" ... />
-    </Appender>
-    ...
-  </Appenders>
-  <Loggers>
-    <Logger name="name1">
-      <Filter type="type" ... />
-    </Logger>
-    ...
-    <Root level="level">
-      <AppenderRef ref="name"/>
-    </Root>
-  </Loggers>
-</Configuration>
-]]></pre>
-          <p>
-            Below is a sample configuration using the strict format.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="debug" strict="true" name="XMLConfigTest"
-               packages="org.apache.logging.log4j.test">
-  <Properties>
-    <Property name="filename">target/test.log</Property>
-  </Properties>
-  <Filter type="ThresholdFilter" level="trace"/>
-
-  <Appenders>
-    <Appender type="Console" name="STDOUT">
-      <Layout type="PatternLayout" pattern="%m MDC%X%n"/>
-      <Filters>
-        <Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
-        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
-      </Filters>
-    </Appender>
-    <Appender type="Console" name="FLOW">
-      <Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
-      <Filters>
-        <Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
-        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
-      </Filters>
-    </Appender>
-    <Appender type="File" name="File" fileName="${dollar}{filename}">
-      <Layout type="PatternLayout">
-        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
-      </Layout>
-    </Appender>
-  </Appenders>
-
-  <Loggers>
-    <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
-      <Filter type="ThreadContextMapFilter">
-        <KeyValuePair key="test" value="123"/>
-      </Filter>
-      <AppenderRef ref="STDOUT"/>
-    </Logger>
-
-    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
-      <AppenderRef ref="File"/>
-    </Logger>
-
-    <Root level="trace">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-
-</Configuration>
-]]></pre>
-        <a name="JSON"/>
-          <h4>Configuration with JSON</h4>
-          <p>
-            In addition to XML, Log4j can be configured using JSON. The JSON format is very similar to the
-            concise XML format. Each key represents the name of a plugin and the key/value pairs associated
-            with it are its attributes. Where a key contains more than a simple value it itself will be a
-            subordinate plugin. In the example below, ThresholdFilter, Console, and PatternLayout are all
-            plugins while the Console plugin will be assigned a value of STDOUT for its name attribute and the
-            ThresholdFilter will be assigned a level of debug.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-{ "configuration": { "status": "error", "name": "RoutingTest",
-                     "packages": "org.apache.logging.log4j.test",
-      "properties": {
-        "property": { "name": "filename",
-                      "value" : "target/rolling1/rollingtest-${dollar}${dollar}{sd:type}.log" }
-      },
-    "ThresholdFilter": { "level": "debug" },
-    "appenders": {
-      "Console": { "name": "STDOUT",
-        "PatternLayout": { "pattern": "%m%n" },
-        "ThresholdFilter": { "level": "debug" }
-      },
-      "Routing": { "name": "Routing",
-        "Routes": { "pattern": "${dollar}${dollar}{sd:type}",
-          "Route": [
-            {
-              "RollingFile": {
-                "name": "Rolling-${dollar}{sd:type}", "fileName": "${dollar}{filename}",
-                "filePattern": "target/rolling1/test1-${dollar}{sd:type}.%i.log.gz",
-                "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
-                "SizeBasedTriggeringPolicy": { "size": "500" }
-              }
-            },
-            { "AppenderRef": "STDOUT", "key": "Audit"}
-          ]
-        }
-      }
-    },
-    "loggers": {
-      "logger": { "name": "EventLogger", "level": "info", "additivity": "false",
-                  "AppenderRef": { "ref": "Routing" }},
-      "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
-    }
-  }
-}
-]]></pre>
-           <p>
-            Note that in the RoutingAppender the Route element has been declared as an array. This is
-            valid because each array element will be a Route component. This won't work for elements such as
-            appenders and filters, where each element has a different name in the concise format. Appenders and
-            filters can be defined as array elements if each appender or filter declares an attribute named "type"
-            that contains the type of the appender. The following example illustrates this as well as how to
-            declare multiple loggers as an array.
-          </p>
-           <pre class="prettyprint linenums"><![CDATA[
-{ "configuration": { "status": "debug", "name": "RoutingTest",
-                      "packages": "org.apache.logging.log4j.test",
-      "properties": {
-        "property": { "name": "filename",
-                      "value" : "target/rolling1/rollingtest-${dollar}${dollar}{sd:type}.log" }
-      },
-    "ThresholdFilter": { "level": "debug" },
-    "appenders": {
-      "appender": [
-         { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }},
-         { "type": "Routing",  "name": "Routing",
-          "Routes": { "pattern": "${dollar}${dollar}{sd:type}",
-            "Route": [
-              {
-                "RollingFile": {
-                  "name": "Rolling-${dollar}{sd:type}", "fileName": "${dollar}{filename}",
-                  "filePattern": "target/rolling1/test1-${dollar}{sd:type}.%i.log.gz",
-                  "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
-                  "SizeBasedTriggeringPolicy": { "size": "500" }
-                }
-              },
-              { "AppenderRef": "STDOUT", "key": "Audit"}
-            ]
-          }
-        }
-      ]
-    },
-    "loggers": {
-      "logger": [
-        { "name": "EventLogger", "level": "info", "additivity": "false",
-          "AppenderRef": { "ref": "Routing" }},
-        { "name": "com.foo.bar", "level": "error", "additivity": "false",
-          "AppenderRef": { "ref": "STDOUT" }}
-      ],
-      "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
-    }
-  }
-}
-]]></pre>
-          <p>
-            Additional <a href="../runtime-dependencies.html">runtime dependencies</a> are required for using
-            JSON configuration files.
-          </p>
-          <a name="YAML"/>
-          <h4>Configuration with YAML</h4>
-          <p>
-            Log4j also supports using YAML for configuration files. The structure follows the same pattern as both the
-            XML and YAML configuration formats. For example:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-Configuration:
-  status: warn
-  name: YAMLConfigTest
-  properties:
-    property:
-      name: filename
-      value: target/test-yaml.log
-  thresholdFilter:
-    level: debug
-  appenders:
-    Console:
-      name: STDOUT
-      PatternLayout:
-        Pattern: "%m%n"
-    File:
-      name: File
-      fileName: ${dollar}{filename}
-      PatternLayout:
-        Pattern: "%d %p %C{1.} [%t] %m%n"
-      Filters:
-        ThresholdFilter:
-          level: error
-
-  Loggers:
-    logger:
-      -
-        name: org.apache.logging.log4j.test1
-        level: debug
-        additivity: false
-        ThreadContextMapFilter:
-          KeyValuePair:
-            key: test
-            value: 123
-        AppenderRef:
-          ref: STDOUT
-      -
-        name: org.apache.logging.log4j.test2
-        level: debug
-        additivity: false
-        AppenderRef:
-          ref: File
-    Root:
-      level: error
-      AppenderRef:
-        ref: STDOUT
-          ]]></pre>
-          <p>
-            Additional <a href="../runtime-dependencies.html">runtime dependencies</a> are required for using
-            YAML configuration files.
-          </p>
-        <a name="Loggers"/>
-          <h4>Configuring loggers</h4>
-          <p>
-            An understanding of how loggers work in Log4j is critical before trying to configure them.
-            Please reference the Log4j <a href="./architecture.html">architecture</a> if more information is
-            required. Trying to configure Log4j without understanding those concepts will lead to frustration.
-          </p>
-          <p>
-            A LoggerConfig is configured using the <code>logger</code> element. The <code>logger</code> element
-            must have a name attribute specified, will usually have a level attribute specified and may
-            also have an additivity attribute specified.  The level may be configured with one of TRACE,
-            DEBUG, INFO, WARN, ERROR, ALL or OFF. If no level is specified it will default to ERROR. The
-            additivity attribute may be assigned a value of true or false. If the attribute is omitted
-            the default value of true will be used.
-          </p>
-          <p>
-            A LoggerConfig (including the root LoggerConfig) can be configured with properties that will be added
-            to the properties copied from the ThreadContextMap. These properties can be referenced from Appenders,
-            Filters, Layouts, etc just as if they were part of the ThreadContext Map. The properties can contain
-            variables that will be resolved either when the configuration is parsed or dynamically when each
-            event is logged. See <a href="#PropertySubstitution">Property Substitution</a> for more information on
-            using variables.
-          </p>
-          <p>
-            The LoggerConfig may also be configured with one or more AppenderRef elements. Each appender
-            referenced will become associated with the specified LoggerConfig. If multiple appenders
-            are configured on the LoggerConfig each of them be called when processing logging events.
-          </p>
-          <p>
-            <b><em>Every configuration must have a root logger</em></b>. If one is not configured the default root LoggerConfig,
-            which has a level of ERROR and has a Console appender attached, will be used. The main differences
-            between the root logger and other loggers are
-          </p>
-            <ol>
-              <li>The root logger does not have a name attribute.</li>
-              <li>The root logger does not support the additivity attribute since it has no parent.</li>
-            </ol>
-        <a name="Appenders"/>
-          <h4>Configuring Appenders</h4>
-          <p>
-            An appender is configured either using the specific appender plugin's name or with an appender
-            element and the type attibute containing the appender plugin's name. In addition each appender
-            must have a name attribute specified with a value that is unique within the set of appenders.
-            The name will be used by loggers to reference the appender as described in the previous section.
-          </p>
-          <p>
-            Most appenders also support a layout to be configured (which again may be specified either
-            using the specific Layout plugin's name as the element or with "layout" as the element name
-            along with a type attribute that contains the layout plugin's name. The various appenders
-            will contain other attributes or elements that are required for them to function properly.
-          </p>
-        <a name="Filters"/>
-          <h4>Configuring Filters</h4>
-          <p>
-            Log4j allows a filter to be specified in any of 4 places:
-          </p>
-            <ol>
-              <li>At the same level as the appenders, loggers and properties elements. These filters can accept
-              or reject events before they have been passed to a LoggerConfig.</li>
-              <li>In a logger element. These filters can accept or reject events for specific loggers.</li>
-              <li>In an appender element. These filters can prevent or cause events to be processed by
-                the appender.</li>
-              <li>In an appender reference element. These filters are used to determine if a Logger should route
-                the event to an appender.</li>
-            </ol>
-          <p>
-            Although only a single <code>filter</code> element can be configured, that element may be the
-            <code>filters</code> element which represents the CompositeFilter. The <code>filters</code> element
-            allows any number of <code>filter</code> elements to be configured within it. The following example
-            shows how multiple filters can be configured on the ConsoleAppender.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
-  <Properties>
-    <Property name="filename">target/test.log</Property>
-  </Properties>
-  <ThresholdFilter level="trace"/>
-
-  <Appenders>
-    <Console name="STDOUT">
-      <PatternLayout pattern="%m MDC%X%n"/>
-    </Console>
-    <Console name="FLOW">
-      <!-- this pattern outputs class name and line number -->
-      <PatternLayout pattern="%C{1}.%M %m %ex%n"/>
-      <filters>
-        <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
-        <MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
-      </filters>
-    </Console>
-    <File name="File" fileName="${dollar}{filename}">
-      <PatternLayout>
-        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
-      </PatternLayout>
-    </File>
-  </Appenders>
-
-  <Loggers>
-    <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
-      <ThreadContextMapFilter>
-        <KeyValuePair key="test" value="123"/>
-      </ThreadContextMapFilter>
-      <AppenderRef ref="STDOUT"/>
-    </Logger>
-
-    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
-      <Property name="user">${dollar}{sys:user.name}</Property>
-      <AppenderRef ref="File">
-        <ThreadContextMapFilter>
-          <KeyValuePair key="test" value="123"/>
-        </ThreadContextMapFilter>
-      </AppenderRef>
-      <AppenderRef ref="STDOUT" level="error"/>
-    </Logger>
-
-    <Root level="trace">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-
-</Configuration>
-]]></pre>
-          <a name="Properties"/>
-          <h4>Configuration with Properties</h4>
-            <p>
-              As of version 2.4, Log4j now supports configuration via properties files. Note that the property
-              syntax is NOT the same as the syntax used in Log4j 1. Like the XML and JSON configurations, properties
-              configurations define the configuration in terms of plugins and attributes to the plugins.
-            </p>
-            <p>
-              Prior to version 2.6,
-              the properties configuration requires that you list the identifiers of the appenders, filters and loggers,
-              in a comma separated list in properties with those names. Each of those components will then be expected
-              to be defined in sets of properties that begin with <i>component.&lt;.identifier&gt;.</i>. The identifier does not
-              have to match the name of the component being defined but must uniquely identify all the attributes and
-              subcomponents that are part of the component. If the list of identifiers is not present the
-              identier must not contain a '.'. Each individual component MUST have a "type" attribute
-              specified that identifies the component's Plugin type.
-            </p>
-            <p>
-              As of version 2.6, this list of identifiers is no longer required as names are inferred upon first usage,
-              however if you wish to use more complex identifies you must still use the list. If the list is present
-              it will be used.
-            </p>
-            <p>
-              Unlike the base components, when creating subcomponents you cannot specify an element containing a list of
-              identifiers. Instead, you must define the wrapper element with its type as is shown in the policies
-              definition in the rolling file appender below. You then define each of the subcomponents below that
-              wrapper element, as the TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined below.
-            </p>
-            <p>
-              Properties configuration files support the advertiser, monitorInterval, name, packages, shutdownHook,
-              shutdownTimeout, status, verbose, and dest attrbutes. See <a href="#ConfigurationSyntax">Configuration Syntax</a>
-              for the definitions of these attributes.
-            </p>
-          <pre class="prettyprint linenums">
-status = error
-dest = err
-name = PropertiesConfig
-
-property.filename = target/rolling/rollingtest.log
-
-filter.threshold.type = ThresholdFilter
-filter.threshold.level = debug
-
-appender.console.type = Console
-appender.console.name = STDOUT
-appender.console.layout.type = PatternLayout
-appender.console.layout.pattern = %m%n
-appender.console.filter.threshold.type = ThresholdFilter
-appender.console.filter.threshold.level = error
-
-appender.rolling.type = RollingFile
-appender.rolling.name = RollingFile
-appender.rolling.fileName = ${filename}
-appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
-appender.rolling.layout.type = PatternLayout
-appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
-appender.rolling.policies.type = Policies
-appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
-appender.rolling.policies.time.interval = 2
-appender.rolling.policies.time.modulate = true
-appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
-appender.rolling.policies.size.size=100MB
-appender.rolling.strategy.type = DefaultRolloverStrategy
-appender.rolling.strategy.max = 5
-
-logger.rolling.name = com.example.my.app
-logger.rolling.level = debug
-logger.rolling.additivity = false
-logger.rolling.appenderRef.rolling.ref = RollingFile
-
-rootLogger.level = info
-rootLogger.appenderRef.stdout.ref = STDOUT
-          </pre>
-        </subsection>
-        <a name="PropertySubstitution"/>
-        <subsection name="Property Substitution">
-          <p>
-            Log4j 2 supports the ability to specify tokens in the configuration as references to properties defined
-            elsewhere. Some of these properties will be resolved when the configuration file is interpreted while
-            others may be passed to components where they will be evaluated at runtime. To accomplish this, Log4j
-            uses variations of <a href="https://commons.apache.org/proper/commons-lang/">Apache Commons Lang</a>'s
-            <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrSubstitutor.html">StrSubstitutor</a>
-            and <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a>
-            classes. In a manner similar to Ant or Maven, this allows variables declared as <code>${dollar}{name}</code>
-            to be resolved using properties declared in the configuration itself. For example, the following example
-            shows the filename for the rolling file appender being declared as a property.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="debug" name="RoutingTest" packages="org.apache.logging.log4j.test">
-  <Properties>
-    <Property name="filename">target/rolling1/rollingtest-${dollar}${dollar}{sd:type}.log</Property>
-  </Properties>
-  <ThresholdFilter level="debug"/>
-
-  <Appenders>
-    <Console name="STDOUT">
-      <PatternLayout pattern="%m%n"/>
-      <ThresholdFilter level="debug"/>
-    </Console>
-    <Routing name="Routing">
-      <Routes pattern="${dollar}${dollar}{sd:type}">
-        <Route>
-          <RollingFile name="Rolling-${dollar}{sd:type}" fileName="${dollar}{filename}"
-                       filePattern="target/rolling1/test1-${dollar}{sd:type}.%i.log.gz">
-            <PatternLayout>
-              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-            </PatternLayout>
-            <SizeBasedTriggeringPolicy size="500" />
-          </RollingFile>
-        </Route>
-        <Route ref="STDOUT" key="Audit"/>
-      </Routes>
-    </Routing>
-  </Appenders>
-
-  <Loggers>
-    <Logger name="EventLogger" level="info" additivity="false">
-      <AppenderRef ref="Routing"/>
-    </Logger>
-
-    <Root level="error">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-
-</Configuration>
-]]></pre>
-          <p>
-            While this is useful, there are many more places properties can originate from. To accommodate this,
-            Log4j also supports the syntax <code>${dollar}{prefix:name}</code> where the prefix identifies tells Log4j
-            that variable name should be evaluated in a specific context.
-            See the <a href="lookups.html">Lookups</a> manual page for more details.
-            The contexts that are built in to Logj4 are:
-          </p>
-            <table>
-              <tr>
-                <th>Prefix</th>
-                <th>Context</th>
-              </tr>
-              <tr>
-                <td>bundle</td>
-                <td>
-                  Resource bundle. The format is <code>${dollar}{bundle:BundleName:BundleKey}</code>.
-                  The bundle name follows package naming conventions, for example:
-                  <code>${dollar}{bundle:com.domain.Messages:MyKey}</code>.
-                </td>
-              </tr>
-              <tr>
-                <td>ctx</td>
-                <td>Thread Context Map (MDC)</td>
-              </tr>
-              <tr>
-                <td>date</td>
-                <td>Inserts the current date and/or time using the specified format</td>
-              </tr>
-              <tr>
-                <td>env</td>
-                <td>System environment variables. The formats are <code>${dollar}{env:ENV_NAME}</code> and <code>${dollar}{env:ENV_NAME:-default_value}</code>.</td>
-              </tr>
-              <tr>
-                <td>jndi</td>
-                <td>A value set in the default JNDI Context.</td>
-              </tr>
-              <tr>
-                <td>jvmrunargs</td>
-                <td>
-                  A JVM input argument accessed through JMX, but not a main argument;
-                  see <a class="javadoc" href="http://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--">RuntimeMXBean.getInputArguments()</a>.
-                  Not available on Android.</td>
-              </tr>
-              <tr>
-                <td>log4j</td>
-                <td>Log4j configuration properties. The expressions <code>${dollar}{log4j:configLocation}</code> and
-                  <code>${dollar}{log4j:configParentLocation}</code> respectively provide the absolute path
-                  to the log4j configuration file and its parent folder.</td>
-              </tr>
-              <tr>
-                <td>main</td>
-                <td>A value set with <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-">MapLookup.setMainArguments(String[])</a></td>
-              </tr>
-              <tr>
-                <td>map</td>
-                <td>A value from a MapMessage</td>
-              </tr>
-              <tr>
-                <td>sd</td>
-                <td>A value from a StructuredDataMessage. The key "id" will return the name of the StructuredDataId
-                  without the enterprise number. The key "type" will return the message type. Other keys will
-                  retrieve individual elements from the Map.</td>
-              </tr>
-              <tr>
-                <td>sys</td>
-                <td>System properties. The formats are <code>${dollar}{sys:some.property}</code> and <code>${dollar}{sys:some.property:-default_value}</code>.</td>
-              </tr>
-            </table>
-          <p>
-            A default property map can be declared in the configuration file. If the value cannot be located in
-            the specified lookup the value in the default property map will be used. The default map is
-            pre-populated with a value for "hostName" that is the current system's host name or IP address and
-            the "contextName" with is the value of the current logging context.
-          </p>
-        </subsection>
-        <a name="RuntimeLookup"/>
-        <subsection name="Lookup Variables with Multiple Leading '$' Characters">
-          <p>
-            An interesting feature of StrLookup processing is that when a variable reference is declared with
-            multiple leading '$' characters each time the variable is resolved the leading '$' is simply removed.
-            In the previous example the "Routes" element is capable of resolving the variable at runtime. To allow
-            this the prefix value is specified as a variable with two leading '$' characters. When the configuration
-            file is first processed the first '$' character is simply removed. Thus, when the Routes element is evaluated
-            at runtime it is the variable declaration "${dollar}{sd:type}" which causes the event to be inspected for a
-            StructuredDataMessage and if one is present the value of its type attribute to be used as the routing key.
-            Not all elements support resolving variables at runtime. Components that do will specifically call that
-            out in their documentation.
-          </p>
-          <p>
-            If no value is found for the key in the Lookup associated with the prefix then the value associated with
-            the key in the properties declaration in the configuration file will be used. If no value is found
-            the variable declaration will be returned as the value. Default values may be declared in the configuration
-            by doing:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration>
-  <Properties>
-    <Property name="type">Audit</property>
-  </Properties>
-  ...
-</Configuration>
-]]></pre>
-          <p>
-            <i>As a footnote, it is worth pointing out that the variables in the RollingFile appender declaration
-            will also not be evaluated when the configuration is processed. This is simply because the resolution
-            of the whole RollingFile element is deferred until a match occurs.
-            See <a href="appenders.html#RoutingAppender">RoutingAppender</a> for more information.</i>
-          </p>
-        </subsection>
-        <a name="Scripts"/>
-        <subsection name="Scripts">
-          <p>
-            Log4j provides support for <a href="http://docs.oracle.com/javase/6/docs/technotes/guides/scripting/">JSR 223</a>
-            scripting languages to be used in some of its components. Any language that provides support for the JSR
-            223 scripting engine may be used. A list of the languages and bindings for them can be found at the
-            <a href="https://java.net/projects/scripting/sources/svn/show/trunk/engines">Scripting Engine</a> web site.
-            However, some of the languages listed there, such as JavaScript, Groovy and Beanshell, directly support the
-            JSR 223 scripting framework and only require that the jars for that language be installed.
-          </p>
-          <p>
-            The components that support using scripts do so by allowing a &lt;script&gt;, &lt;scriptFile&gt;, or
-            &lt;scriptRef&gt; element to be configured on
-            them. The script element contains a name for the script, the language of the script, and the script text.
-            The scriptFile element contains the name of the script, its location, its language, its charset, and
-            whether the file should be watched for changes. The scriptRef element contains the name of the
-            script that is defined in the &lt;scripts&gt; configuration element.
-            The name of the script is used to store the script, along with its ScriptEngine, so it can quickly be
-            located each time the script needs to be run. While the name is not required, providing it will help in
-            debugging problems when the script is running. The language must be provided on the script element and must
-            specify one of the language names that appear in the Configuration status log as described in the next
-            section. If the language is not specified on the scriptFile element the language will be determined by
-            the file extension of the script path. If file monitoring is requested it will only be enabled if
-            a non-zero monitorInterval is specified on the configuration element. That interval will be used to
-            check for changes in the file.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="debug" name="RoutingTest">
-  <Scripts>
-    <Script name="selector" language="javascript"><![CDATA[
-            var result;
-            if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
-                result = "NoLocation";
-            } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
-                result = "Flow";
-            }
-            result;
-            ]]]]><![CDATA[></Script>
-    <ScriptFile name="groovy.filter" path="scripts/filter.groovy"/>
-  </Scripts>
-
-  <Appenders>
-    <Console name="STDOUT">
-      <ScriptPatternSelector defaultPattern="%d %p %m%n">
-        <ScriptRef ref="selector"/>
-          <PatternMatch key="NoLocation" pattern="[%-5level] %c{1.} %msg%n"/>
-          <PatternMatch key="Flow" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/>
-      </ScriptPatternSelector>
-      <PatternLayout pattern="%m%n"/>
-    </Console>
-  </Appenders>
-
-  <Loggers>
-    <Logger name="EventLogger" level="info" additivity="false">
-        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
-          <Script name="GroovyFilter" language="groovy"><![CDATA[
-            if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
-                return true;
-            } else if (logEvent.getContextMap().containsKey("UserId")) {
-                return true;
-            }
-            return false;
-            ]]]]><![CDATA[>
-          </Script>
-        </ScriptFilter>
-      <AppenderRef ref="STDOUT"/>
-    </Logger>
-
-    <Root level="error">
-      <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
-        <ScriptRef ref="groovy.filter"/>
-      </ScriptFilter>
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-
-</Configuration>]]>
-          </pre>
-          <p>
-            If the status attribute on the Configuration element is set to DEBUG the list of script engines currently
-            installed and their attributes will be listed. Although some engines may say they are not thread safe,
-            Log4j takes steps to insure that the scripts will run in a thread-safe manner if the engine advertises
-            that it is not thread safe.
-          </p>
-          <pre>
-2015-09-27 16:13:22,925 main DEBUG Installed script engines
-2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe,
-            Compile: false, Names: {AppleScriptEngine, AppleScript, OSA}
-2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED,
-            Compile: true, Names: {groovy, Groovy}
-2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED,
-            Compile: true, Names: {beanshell, bsh, java}
-2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED,
-            Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript}
-          </pre>
-          <p>
-            When the scripts are executed they will be provided with a set of variables that should allow them to
-            accomplish whatever task they are expected to perform. See the documentation for the individual components
-            for the list of variables that are available to the script.
-          </p>
-          <p>
-            The components that support scripting expect a return value to be passed back to the calling Java code.
-            This is not a problem for several of the scripting languages, but Javascript does not allow a
-            return statement unless it is within a function. However, Javascript will return the value of the last
-            statement executed in the script. As a consequence, code such as that shown below will result in the
-            desired behavior.
-          </p>
-          <pre><![CDATA[
-            var result;
-            if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
-                result = "NoLocation";
-            } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
-                result = "Flow";
-            }
-            result;
-          ]]></pre>
-          <h4>A special note on Beanshell</h4>
-          <p>
-            JSR 223 scripting engines are supposed to identify that they support the Compilable interface if they
-            support compiling their scripts. Beanshell does this. However, whenever the compile method is called it
-            throws an Error (not an Exception). Log4j catches this but will log the warning shown below for each
-            Beanshell script when it tries to compile them. All Beanshell scripts will then be interpreted on each
-            execution.
-          </p>
-          <pre><![CDATA[
-2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable
-2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented
-            at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175)
-            at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154)
-            at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.<init>(ScriptManager.java:125)
-            at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94)
-          ]]></pre>
-        </subsection>
-        <a name="XInclude"/>
-        <subsection name="XInclude">
-          <p>
-            XML configuration files can include other files with <a href="http://www.xml.com/lpt/a/1009">XInclude</a>.
-            Here is an example log4j2.xml file that includes two other files:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<configuration xmlns:xi="http://www.w3.org/2001/XInclude"
-               status="warn" name="XIncludeDemo">
-  <properties>
-    <property name="filename">xinclude-demo.log</property>
-  </properties>
-  <ThresholdFilter level="debug"/>
-  <xi:include href="log4j-xinclude-appenders.xml" />
-  <xi:include href="log4j-xinclude-loggers.xml" />
-</configuration>
-]]></pre>
-          <p>log4j-xinclude-appenders.xml:</p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<appenders>
-  <Console name="STDOUT">
-    <PatternLayout pattern="%m%n" />
-  </Console>
-  <File name="File" fileName="${dollar}{filename}" bufferedIO="true" immediateFlush="true">
-    <PatternLayout>
-      <pattern>%d %p %C{1.} [%t] %m%n</pattern>
-    </PatternLayout>
-  </File>
-</appenders>
-]]></pre>
-          <p>log4j-xinclude-loggers.xml:</p>
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<loggers>
-  <logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
-    <ThreadContextMapFilter>
-      <KeyValuePair key="test" value="123" />
-    </ThreadContextMapFilter>
-    <AppenderRef ref="STDOUT" />
-  </logger>
-
-  <logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
-    <AppenderRef ref="File" />
-  </logger>
-
-  <root level="error">
-    <AppenderRef ref="STDOUT" />
-  </root>
-</loggers>
-]]></pre>
-        </subsection>
-        <a name="CompositeConfiguration"/>
-        <subsection name="Composite Configuration">
-            <p>
-              Log4j allows multiple configuration files to be used by specifying them as a list of comma separated
-              file paths on log4j.configurationFile.  The merge logic can be controlled by specifying a class
-                that implements the MergeStrategy interface on the log4j.mergeStrategy property. The default
-                merge strategy will merge the files using the following rules:
-              <ol>
-                <li>The global configuration attributes are aggregated with those in later configurations replacing
-                  those in previous configurations, with the exception that the highest status level and the lowest
-                  monitorInterval greater than 0 will be used.</li>
-                <li>Properties from all configurations are aggregated. Duplicate properties replace those in previous
-                  configurations.</li>
-                <li>Filters are aggregated under a CompositeFilter if more than one Filter is defined. Since Filters
-                  are not named duplicates may be present.</li>
-                <li>Scripts and ScriptFile references are aggregated. Duplicate definiations replace those in previous
-                  configurations.</li>
-                <li>Appenders are aggregated. Appenders with the same name are replaced by those in later
-                  configurations, including all of the Appender's subcomponents.</li>
-                <li>Loggers are all aggregated. Logger attributes are individually merged with duplicates being
-                  replaced by those in later configurations. Appender references on a Logger are aggregated with
-                  duplicates being replaced by those in later configurations. Filters on a Logger are aggregated
-                  under a CompositeFilter if more than one Filter is defined. Since Filters are not named
-                  duplicates may be present. Filters under Appender references included or discarded depending on
-                  whether their parent Appender reference is kept or discarded.</li>
-                </ol>
-            </p>
-        </subsection>
-        <a name="StatusMessages"/>
-        <subsection name="Status Messages">
-          <table>
-            <tr>
-            <td>
-            <b>Troubleshooting tip for the impatient:</b>
-              <p>From log4j-2.9 onward, log4j2 will print all internal logging to the console if system property
-                <tt>log4j2.debug</tt> is defined (with any or no value).</p>
-              <p>Prior to log4j-2.9, there are two places where internal logging can be controlled:</p>
-            <ul>
-              <li>Before a configuration is found, status logger level can be controlled with system
-              property <code>org.apache.logging.log4j.simplelog.StatusLogger.level</code>.</li>
-              <li>After a configuration is found, status logger level can be controlled in the configuration
-              file with the "status" attribute, for example: <code>&lt;Configuration status="trace"&gt;</code>.</li>
-            </ul>
-            </td>
-            </tr>
-          </table>
-          <p>
-            Just as it is desirable to be able to diagnose problems in applications, it is frequently necessary
-            to be able to diagnose problems in the logging configuration or in the configured components. Since
-            logging has not been configured, "normal" logging cannot be used during initialization. In addition,
-            normal logging within appenders could create infinite recursion which Log4j will detect and cause
-            the recursive events to be ignored. To accomodate this need, the Log4j 2 API includes a
-            <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/status/StatusLogger.html">StatusLogger</a>.
-            Components declare an instance of the StatusLogger similar to:
-          </p>
-          <pre class="prettyprint">protected final static Logger logger = StatusLogger.getLogger();</pre>
-          <p>
-            Since StatusLogger implements the Log4j 2 API's Logger interface, all the normal Logger methods may
-            be used.
-          </p>
-          <p>
-            When configuring Log4j it is sometimes necessary to view the generated status events. This can be
-            accomplished by adding the status attribute to the configuration element or a default value can be
-            provided by setting the "Log4jDefaultStatusLevel" system property.  Valid values of the status attribute are
-            "trace", "debug", "info", "warn", "error" and "fatal". The following
-            configuration has the status attribute set to debug.
-          </p>
-
-          <pre class="prettyprint linenums"><![CDATA[
-<?xml version="1.0" encoding="UTF-8"?>
-<Configuration status="debug" name="RoutingTest">
-  <Properties>
-    <Property name="filename">target/rolling1/rollingtest-${dollar}${dollar}{sd:type}.log</Property>
-  </Properties>
-  <ThresholdFilter level="debug"/>
-
-  <Appenders>
-    <Console name="STDOUT">
-      <PatternLayout pattern="%m%n"/>
-      <ThresholdFilter level="debug"/>
-    </Console>
-    <Routing name="Routing">
-      <Routes pattern="${dollar}${dollar}{sd:type}">
-        <Route>
-          <RollingFile name="Rolling-${dollar}{sd:type}" fileName="${dollar}{filename}"
-                       filePattern="target/rolling1/test1-${dollar}{sd:type}.%i.log.gz">
-            <PatternLayout>
-              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-            </PatternLayout>
-            <SizeBasedTriggeringPolicy size="500" />
-          </RollingFile>
-        </Route>
-        <Route ref="STDOUT" key="Audit"/>
-      </Routes>
-    </Routing>
-  </Appenders>
-
-  <Loggers>
-    <Logger name="EventLogger" level="info" additivity="false">
-      <AppenderRef ref="Routing"/>
-    </Logger>
-
-    <Root level="error">
-      <AppenderRef ref="STDOUT"/>
-    </Root>
-  </Loggers>
-
-</Configuration>
-]]></pre>
-            <p>
-            During startup this configuration produces:
-            </p>
-#if ($isPDF)
-    <pre>
-2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds
-2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.
-       config.Property for element property with params(name="filename",
-       value="target/rolling1/rollingtest-${dollar}{sd:type}.log")
-2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.
-       core.config.plugins.PropertiesPlugin for element properties with
-       params(properties={filename=target/rolling1/rollingtest-${dollar}{sd:type}.log})
-2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds
-2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.
-       filter.ThresholdFilter for element ThresholdFilter with params(level="debug",
-       onMatch="null", onMismatch="null")
-2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.
-       layout.PatternLayout for element PatternLayout with params(pattern="%m%n",
-       Configuration(RoutingTest), null, charset="null")
-2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds
-2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.
-       appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null,
-       target="null", name="STDOUT", ignoreExceptions="null")
-2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.
-       filter.ThresholdFilter for element ThresholdFilter with params(level="debug",
-       onMatch="null", onMismatch="null")
-2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.
-       routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route)
-2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.
-       routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route)
-2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.
-       routing.Routes for element Routes with params(pattern="${dollar}{sd:type}",
-       routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit'))})
-2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.
-       routing.RoutingAppender for element Routing with params(name="Routing",
-      ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static
-       Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null)
-2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.
-       plugins.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing})
-2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.
-       config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing")
-2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.
-       LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger",
-       AppenderRef={Routing}, null)
-2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.
-       config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT")</pre>
-            <pre>
-2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.
-       LoggerConfig${dollar}RootLogger for element root with params(additivity="null", level="error",
-       AppenderRef={STDOUT}, null)
-2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.
-       config.plugins.LoggersPlugin for element loggers with params(loggers={EventLogger, root})
-2011-11-23 17:08:00,834 DEBUG Reconfiguration completed
-2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.
-       layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n",
-       Configuration(RoutingTest), null, charset="null")
-2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.
-       appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with
-       params(size="500")
-2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.
-       appender.RollingFileAppender for element RollingFile with
-       params(fileName="target/rolling1/rollingtest-Unknown.log",
-       filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown",
-       bufferedIO="null", immediateFlush="null",
-       SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null,
-       PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null")
-2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds
-2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.
-       Launcher${dollar}AppClassLoader@37b90b39
-2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds
-2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds
-2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds
-2011-11-23 17:08:00,965 WARN No Loggers were configured, using default
-2011-11-23 17:08:00,976 DEBUG Reconfiguration completed</pre>
-#else
-<pre>
-2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds
-2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${dollar}{sd:type}.log")
-2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${dollar}{sd:type}.log})
-2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds
-2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null")
-2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null")
-2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds
-2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null")
-2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null")
-2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route)
-2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route)
-2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${dollar}{sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')})
-2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null)
-2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing})
-2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing")
-2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null)
-2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT")
-2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig${dollar}RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null)
-2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root})
-2011-11-23 17:08:00,834 DEBUG Reconfiguration completed
-2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null")
-2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500")
-2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null")
-2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds
-2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher${dollar}AppClassLoader@37b90b39
-2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds
-2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds
-2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds
-2011-11-23 17:08:00,965 WARN No Loggers were configured, using default
-2011-11-23 17:08:00,976 DEBUG Reconfiguration completed</pre>
-#end
-          <p>
-            If the status attribute is set to error than only error messages will be written to the console. This
-            makes troubleshooting configuration errors possible. As an example, if the configuration above is changed
-            to have the status set to error and the logger declaration is:</p>
-          <pre class="prettyprint linenums"><![CDATA[
-<logger name="EventLogger" level="info" additivity="false">
-  <AppenderRef ref="Routng"/>
-</logger>
-]]></pre>
-          <p>
-            the following error message will be produced.
-          </p>
-          <pre>2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger</pre>
-          <p>
-            Applications may wish to direct the status output to some other destination. This can be accomplished
-            by setting the dest attribute to either "err" to send the output to stderr or to a file location or URL.
-            This can also be done by insuring the configured status is set to OFF and then configuring the application
-            programmatically such as:
-          </p>
-<pre class="prettyprint linenums"><![CDATA[
-StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
-StatusLogger.getLogger().registerListener(listener);
-]]></pre>
-        </subsection>
-        <a name="UnitTestingInMaven"/>
-        <subsection name="Testing in Maven">
-        <p>
-          Maven can run unit and functional tests during the build cycle. By default, any files placed in
-          <code>src/test/resources</code> are automatically copied to target/test-classes and are included
-          in the classpath during execution of any tests. As such, placing a log4j2-test.xml into this directory
-          will cause it to be used instead of a log4j2.xml or log4j2.json that might be present.  Thus a different
-          log configuration can be used during testing than what is used in production.
-        </p>
-        <p>
-          A second approach, which is extensively used by Log4j 2, is to set the log4j.configurationFile property
-          in the method annotated with @BeforeClass in the junit test class. This will allow an arbitrarily
-          named file to be used during the test.
-        </p>
-          <p>
-            A third approach, also used extensively by Log4j 2, is to use the <code>LoggerContextRule</code>
-            JUnit test rule which provides additional convenience methods for testing. This requires adding the
-            <code>log4j-core</code> <code>test-jar</code> dependency to your test scope dependencies. For example:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-public class AwesomeTest {
-    @Rule
-    public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml");
-
-    @Test
-    public void testSomeAwesomeFeature() {
-        final LoggerContext ctx = init.getContext();
-        final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger");
-        final Configuration cfg = init.getConfiguration();
-        final ListAppender app = init.getListAppender("List");
-        logger.warn("Test message");
-        final List<LogEvent> events = app.getEvents();
-        // etc.
-    }
-}
-]]></pre>
-        </subsection>
-        <a name="SystemProperties"/>
-        <subsection name="System Properties">
-        <p>
-          The Log4j documentation references a number of System Properties that can be used to control various aspects
-          of Log4j 2 behavior. The table below lists these properties along with their default value and a
-          description of what they control.
-          Any spaces present in the property name are for visual flow and should be removed.
-        </p>
-          <p>
-            Note that beginning in Log4j 2.10, all system property names have been normalized to follow a consistent
-            naming scheme. While the old property names are still supported for backwards compatibility, it is
-            recommended to update configurations to use the new style. This system is extensible and is enabled
-            through the
-            <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/util/PropertySource.html">PropertySource</a>
-            interface. Additional property source classes can be added through the standard <code>ServiceLoader</code>
-            mechanism in Java SE.
-          </p>
-          <p>
-            Properties can be overridden by sources with a lower number priority (e.g.., -100 comes before 100). The
-            following sources are all available by default:
-          </p>
-          <table>
-            <caption align="top">PropertySource priorities and descriptions</caption>
-            <tr>
-              <th>Source</th>
-              <th>Priority</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>Environment Variables</td>
-              <td>-100</td>
-              <td>
-                Environment variables are all prefixed with <code>LOG4J_</code>, are in all caps, and words are all
-                separated by underscores. Only this naming scheme is support for environment variables as there were
-                no old naming schemes to maintain compatibility with.
-              </td>
-            </tr>
-            <tr>
-              <td><code>log4j2.component.properties</code> file</td>
-              <td>0</td>
-              <td>
-                Including this file on the classpath can be used as an alternative to providing properties as system
-                properties. This has priority over system properties, but they can be overridden by environment
-                variables as described above.
-              </td>
-            </tr>
-            <tr>
-              <td>System Properties</td>
-              <td>100</td>
-              <td>
-                All properties can be set using normal system property patterns. These have the lowest priority and
-                can be overridden by included properties files or environment variables.
-              </td>
-            </tr>
-          </table>
-          <p>
-            The following is a list of available global configuration properties. Note that these can only be set once
-            per JVM process unlike configuration settings available in configuration files. The <i>Property Name</i>
-            column contains the name used in properties files and system properties; <i>Environemt Variable</i>
-            for the equivalent environment variable; and <i>Legacy Property Name</i> for the pre-2.10 name.
-          </p>
-<style>
-  * { // this works for all but td
-  word-wrap:break-word;
-  }
-
-  table { // this somehow makes it work for td
-  table-layout:fixed;
-  width:100%;
-  }
-</style>
-<table style="table-layout: fixed; width: 100%">
-  <caption align="top">Log4j 2 global configuration properties</caption>
-  <tr>
-    <th>Property Name <br /> (Legacy Property Name)</th>
-    <th>Environment Variable</th>
-    <th>Default Value</th>
-    <th>Description</th>
-  </tr>
-
-  <tr>
-    <td><a name="configurationFile"/>log4j2.configurationFile
-      <br />
-      (<a name="log4j.configurationFile"/>log4j.configurationFile)
-    </td>
-    <td>LOG4J_CONFIGURATION_FILE</td>
-    <td>&nbsp;</td>
-    <td>
-      Path to an Log4j 2 configuration file. May also contain a comma separated list of configuration file names.
-    </td>
-  </tr>
-  <tr>
-    <td><a name="debug"/>log4j2.debug
-      <br />
-      (<a name="log4j2.debug"/>log4j2.debug)
-    </td>
-    <td>LOG4J_DEBUG</td>
-    <td>&nbsp;</td>
-    <td>
-      Log4j2 will print all internal logging to the console if system property
-      <tt>log4j2.debug</tt> is defined (with any or no value).
-    </td>
-  </tr>
-  <tr>
-    <td><a name="mergeFactory"/>log4j2.mergeFactory
-      <br />
-      (<a name="log4j.mergeFactory"/>log4j.mergeFactory)
-    </td>
-    <td>LOG4J_MERGE_FACTORY</td>
-    <td>&nbsp;</td>
-    <td>
-      The name of the class that implements the MergeStrategy interface. If not specified
-      <code>DefaultMergeStrategy</code> will be used when creating a Composi

<TRUNCATED>

[7/8] logging-log4j2 git commit: Make a>code links look nicer

Posted by ma...@apache.org.
Make a>code links look nicer


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

Branch: refs/heads/master
Commit: bd15f9d2f5ff59062e51838b83ac22f2560f28fb
Parents: 1079bef
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 19:49:14 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/resources/css/site.css | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/bd15f9d2/src/site/resources/css/site.css
----------------------------------------------------------------------
diff --git a/src/site/resources/css/site.css b/src/site/resources/css/site.css
index 56381aa..5bda65a 100644
--- a/src/site/resources/css/site.css
+++ b/src/site/resources/css/site.css
@@ -21,8 +21,8 @@ div.clear hr { display: none; }
 /* Tweaks to the bootstrap theme
 --------------------------------- */
 li { line-height: 20px; }
-tt { font: 12px Menlo, Monaco, "Courier New", monospace; -webkit-border-radius: 3px; -moz-border-radius: 3px; border-radius: 3px; padding: 3px 4px; background-color: #f7f7f9; border: 1px solid #e1e1e8; }
-tt, code { color: #4e648e }
+code { color: #4e648e }
+a code { color: #0088cc }
 dt { margin: 15px 0 5px 0; font-size: 1.2em }
 
 .big-red { font-weight: bold; color: #D14 }


[6/8] logging-log4j2 git commit: LOG4J2-1802: Convert configuration manual page to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert configuration manual page 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/b53b8118
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/b53b8118
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/b53b8118

Branch: refs/heads/master
Commit: b53b8118dbcff25b0bc64fab5cab6fe1ea84163b
Parents: fe2601c
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 19:24:00 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/configuration.adoc | 2192 ++++++++++++++++++++
 src/site/xdoc/manual/configuration.xml.vm   | 2383 ----------------------
 2 files changed, 2192 insertions(+), 2383 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/b53b8118/src/site/asciidoc/manual/configuration.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/configuration.adoc b/src/site/asciidoc/manual/configuration.adoc
new file mode 100644
index 0000000..138e3f0
--- /dev/null
+++ b/src/site/asciidoc/manual/configuration.adoc
@@ -0,0 +1,2192 @@
+////
+    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
+
+        https://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.
+////
+= Configuration
+Ralph Goers <rg...@apache.org>
+
+Inserting log requests into the application code requires a fair amount
+of planning and effort. Observation shows that approximately 4 percent
+of code is dedicated to logging. Consequently, even moderately sized
+applications will have thousands of logging statements embedded within
+their code. Given their number, it becomes imperative to manage these
+log statements without the need to modify them manually.
+
+Configuration of Log4j 2 can be accomplished in 1 of 4 ways:
+
+1.  Through a configuration file written in XML, JSON, YAML, or
+properties format.
+2.  Programmatically, by creating a ConfigurationFactory and
+Configuration implementation.
+3.  Programmatically, by calling the APIs exposed in the Configuration
+interface to add components to the default configuration.
+4.  Programmatically, by calling methods on the internal Logger class.
+
+This page focuses primarily on configuring Log4j through a configuration
+file. Information on programmatically configuring Log4j can be found at
+link:extending.html[Extending Log4j 2] and
+link:customconfig.html[Programmatic Log4j Configuration].
+
+Note that unlike Log4j 1.x, the public Log4j 2 API does not expose
+methods to add, modify or remove appenders and filters or manipulate the
+configuration in any way.
+
+[#AutomaticConfiguration]
+== Automatic Configuration
+
+Log4j has the ability to automatically configure itself during
+initialization. When Log4j starts it will locate all the
+ConfigurationFactory plugins and arrange them in weighted order from
+highest to lowest. As delivered, Log4j contains four
+ConfigurationFactory implementations: one for JSON, one for YAML, one
+for properties, and one for XML.
+
+1.  Log4j will inspect the `"log4j.configurationFile"` system property
+and, if set, will attempt to load the configuration using the
+`ConfigurationFactory` that matches the file extension.
+2.  If no system property is set the properties ConfigurationFactory
+will look for `log4j2-test.properties` in the classpath.
+3.  If no such file is found the YAML ConfigurationFactory will look for
+`log4j2-test.yaml` or `log4j2-test.yml` in the classpath.
+4.  If no such file is found the JSON ConfigurationFactory will look for
+`log4j2-test.json` or `log4j2-test.jsn` in the classpath.
+5.  If no such file is found the XML ConfigurationFactory will look for
+`log4j2-test.xml` in the classpath.
+6.  If a test file cannot be located the properties ConfigurationFactory
+will look for `log4j2.properties` on the classpath.
+7.  If a properties file cannot be located the YAML ConfigurationFactory
+will look for `log4j2.yaml` or `log4j2.yml` on the classpath.
+8.  If a YAML file cannot be located the JSON ConfigurationFactory will
+look for `log4j2.json` or `log4j2.jsn` on the classpath.
+9.  If a JSON file cannot be located the XML ConfigurationFactory will
+try to locate `log4j2.xml` on the classpath.
+10. If no configuration file could be located the `DefaultConfiguration`
+will be used. This will cause logging output to go to the console.
+
+An example application named `MyApp` that uses log4j can be used to
+illustrate how this is done.
+
+[source,java]
+----
+import com.foo.Bar;
+
+// Import log4j classes.
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+public class MyApp {
+
+    // Define a static logger variable so that it references the
+    // Logger instance named "MyApp".
+    private static final Logger logger = LogManager.getLogger(MyApp.class);
+
+    public static void main(final String... args) {
+
+        // Set up a simple configuration that logs on the console.
+
+        logger.trace("Entering application.");
+        Bar bar = new Bar();
+        if (!bar.doIt()) {
+            logger.error("Didn't do it.");
+        }
+        logger.trace("Exiting application.");
+    }
+}
+----
+
+`MyApp` begins by importing log4j related classes. It then defines a
+static logger variable with the name `MyApp` which happens to be the
+fully qualified name of the class.
+
+`MyApp` uses the `Bar` class defined in the package`com.foo`.
+
+[source,java]
+----
+package com.foo;
+import org.apache.logging.log4j.Logger;
+import org.apache.logging.log4j.LogManager;
+
+public class Bar {
+  static final Logger logger = LogManager.getLogger(Bar.class.getName());
+
+  public boolean doIt() {
+    logger.entry();
+    logger.error("Did it again!");
+    return logger.exit(false);
+  }
+}
+----
+
+Log4j will provide a default configuration if it cannot locate a
+configuration file. The default configuration, provided in the
+DefaultConfiguration class, will set up:
+
+* A
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/appender/ConsoleAppender.html[`ConsoleAppender`]
+attached to the root logger.
+* A
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`]
+set to the pattern "%d\{HH:mm:ss.SSS} [%t] %-5level %logger\{36} -
+%msg%n" attached to the ConsoleAppender
+
+Note that by default Log4j assigns the root logger to `Level.ERROR`.
+
+The output of MyApp would be similar to:
+
+....
+17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
+17:13:01.540 [main] ERROR MyApp - Didn't do it.
+....
+
+As was described previously, Log4j will first attempt to configure
+itself from configuration files. A configuration equivalent to the
+default would look like:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Root level="error">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+Once the file above is placed into the classpath as log4j2.xml you will
+get results identical to those listed above. Changing the root level to
+trace will result in results similar to:
+
+....
+17:13:01.540 [main] TRACE MyApp - Entering application.
+17:13:01.540 [main] TRACE com.foo.Bar - entry
+17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
+17:13:01.540 [main] TRACE com.foo.Bar - exit with (false)
+17:13:01.540 [main] ERROR MyApp - Didn't do it.
+17:13:01.540 [main] TRACE MyApp - Exiting application.
+....
+
+Note that status logging is disabled when the default configuration is
+used.
+
+[#Additivity]
+== Additivity
+
+Perhaps it is desired to eliminate all the TRACE output from everything
+except `com.foo.Bar`. Simply changing the log level would not accomplish
+the task. Instead, the solution is to add a new logger definition to the
+configuration:
+
+[source,xml]
+----
+<Logger name="com.foo.Bar" level="TRACE"/>
+<Root level="ERROR">
+  <AppenderRef ref="STDOUT">
+</Root>
+----
+
+With this configuration all log events from `com.foo.Bar` will be
+recorded while only error events will be recorded from all other
+components.
+
+In the previous example all the events from `com.foo.Bar` were still
+written to the Console. This is because the logger for `com.foo.Bar` did
+not have any appenders configured while its parent did. In fact, the
+following configuration
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Logger name="com.foo.Bar" level="trace">
+      <AppenderRef ref="Console"/>
+    </Logger>
+    <Root level="error">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+would result in
+
+....
+17:13:01.540 [main] TRACE com.foo.Bar - entry
+17:13:01.540 [main] TRACE com.foo.Bar - entry
+17:13:01.540 [main] ERROR com.foo.Bar - Did it again!
+17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
+17:13:01.540 [main] TRACE com.foo.Bar - exit (false)
+17:13:01.540 [main] ERROR MyApp - Didn't do it.
+....
+
+Notice that the trace messages from `com.foo.Bar` appear twice. This is
+because the appender associated with logger `com.foo.Bar` is first used,
+which writes the first instance to the Console. Next, the parent of
+`com.foo.Bar`, which in this case is the root logger, is referenced. The
+event is then passed to its appender, which is also writes to the
+Console, resulting in the second instance. This is known as additivity.
+While additivity can be quite a convenient feature (as in the first
+previous example where no appender reference needed to be configured),
+in many cases this behavior is considered undesirable and so it is
+possible to disable it by setting the additivity attribute on the logger
+to false:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="WARN">
+  <Appenders>
+    <Console name="Console" target="SYSTEM_OUT">
+      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
+    </Console>
+  </Appenders>
+  <Loggers>
+    <Logger name="com.foo.Bar" level="trace" additivity="false">
+      <AppenderRef ref="Console"/>
+    </Logger>
+    <Root level="error">
+      <AppenderRef ref="Console"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+Once an event reaches a logger with its additivity set to false the
+event will not be passed to any of its parent loggers, regardless of
+their additivity setting.
+
+[#AutomaticReconfiguration]
+== Automatic Reconfiguration
+
+When configured from a File, Log4j has the ability to automatically
+detect changes to the configuration file and reconfigure itself. If the
+`monitorInterval` attribute is specified on the configuration element
+and is set to a non-zero value then the file will be checked the next
+time a log event is evaluated and/or logged and the monitorInterval has
+elapsed since the last check. The example below shows how to configure
+the attribute so that the configuration file will be checked for changes
+only after at least 30 seconds have elapsed. The minimum interval is 5
+seconds.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration monitorInterval="30">
+...
+</Configuration>
+----
+
+[#ChainsawSupport]
+== Chainsaw can automatically process your log files (Advertising appender configurations)
+
+Log4j provides the ability to 'advertise' appender configuration details
+for all file-based appenders as well as socket-based appenders. For
+example, for file-based appenders, the file location and the pattern
+layout in the file are included in the advertisement. Chainsaw and other
+external systems can discover these advertisements and use that
+information to intelligently process the log file.
+
+The mechanism by which an advertisement is exposed, as well as the
+advertisement format, is specific to each Advertiser implementation. An
+external system which would like to work with a specific Advertiser
+implementation must understand how to locate the advertised
+configuration as well as the format of the advertisement. For example, a
+'database' Advertiser may store configuration details in a database
+table. An external system can read that database table in order to
+discover the file location and the file format.
+
+Log4j provides one Advertiser implementation, a 'multicastdns'
+Advertiser, which advertises appender configuration details via IP
+multicast using the http://jmdns.sourceforge.net library.
+
+Chainsaw automatically discovers log4j's multicastdns-generated
+advertisements and displays those discovered advertisements in
+Chainsaw's Zeroconf tab (if the jmdns library is in Chainsaw's
+classpath). To begin parsing and tailing a log file provided in an
+advertisement, just double-click the advertised entry in Chainsaw's
+Zeroconf tab. Currently, Chainsaw only supports FileAppender
+advertisements.
+
+To advertise an appender configuration:
+
+* Add the JmDns library from http://jmdns.sourceforge.net to the
+application classpath
+* Set the 'advertiser' attribute of the configuration element to
+'multicastdns'
+* Set the 'advertise' attribute on the appender element to 'true'
+* If advertising a FileAppender-based configuration, set the
+'advertiseURI' attribute on the appender element to an appropriate URI
+
+FileAppender-based configurations require an additional 'advertiseURI'
+attribute to be specified on the appender. The 'advertiseURI' attribute
+provides Chainsaw with information on how the file can be accessed. For
+example, the file may be remotely accessible to Chainsaw via ssh/sftp by
+specifying a Commons VFS (http://commons.apache.org/proper/commons-vfs/)
+sftp:// URI, an http:// URI may be used if the file is accessible
+through a web server, or a file:// URI can be specified if accessing the
+file from a locally-running instance of Chainsaw.
+
+Here is an example advertisement-enabled appender configuration which
+can be used by a locally-running Chainsaw to automatically tail the log
+file (notice the file:// advertiseURI):
+
+*Please note, you must add the JmDns library from
+http://jmdns.sourceforge.net to your application classpath in order to
+advertise with the 'multicastdns' advertiser.*
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration advertiser="multicastdns">
+  ...
+  <Appenders>
+    <File name="File1" fileName="output.log" bufferedIO="false" advertiseURI="file://path/to/output.log" advertise="true">
+    ...
+    </File>
+  </Appenders>
+</Configuration>
+----
+
+[#ConfigurationSyntax]
+== Configuration Syntax
+
+As of version 2.9, for security reasons, Log4j does not process DTD in
+XML files. If you want to split the configuration in multiple files, use
+link:#XInclude[XInclude] or link:#CompositeConfiguration[Composite
+Configuration].
+
+As the previous examples have shown as well as those to follow, Log4j
+allows you to easily redefine logging behavior without needing to modify
+your application. It is possible to disable logging for certain parts of
+the application, log only when specific criteria are met such as the
+action being performed for a specific user, route output to Flume or a
+log reporting system, etc. Being able to do this requires understanding
+the syntax of the configuration files.
+
+The configuration element in the XML file accepts several attributes:
+
+[cols="1m,5a"]
+|===
+|Attribute Name |Description
+
+|advertiser
+|(Optional) The Advertiser plugin name which will be used to
+advertise individual FileAppender or SocketAppender configurations. The
+only Advertiser plugin provided is "multicastdns".
+
+|dest
+|Either "err", which will send output to stderr, or a file path or URL.
+
+|monitorInterval
+|The minimum amount of time, in seconds, that must
+elapse before the file configuration is checked for changes.
+
+|name
+|The name of the configuration.
+
+|packages
+|A comma separated list of package names to search for
+plugins. Plugins are only loaded once per classloader so changing this
+value may not have any effect upon reconfiguration.
+
+|schema
+|Identifies the location for the classloader to located the XML
+Schema to use to validate the configuration. Only valid when strict is
+set to true. If not set no schema validation will take place.
+
+|shutdownHook
+|Specifies whether or not Log4j should automatically
+shutdown when the JVM shuts down. The shutdown hook is enabled by
+default but may be disabled by setting this attribute to "disable"
+
+|shutdownTimeout
+|Specifies how many milliseconds appenders and
+background tasks will get to shutdown when the JVM shuts down. Default
+is zero which mean that each appender uses its default timeout, and
+don't wait for background tasks. Not all appenders will honor this, it
+is a hint and not an absolute guarantee that the shutdown procedure will
+not take longer. Setting this too low increase the risk of losing
+outstanding log events not yet written to the final destination. See
+link:../log4j-core/target/site/apidocs/org/apache/logging/log4j/core/LoggerContext.html$%7Besc.hash%7Dstop(long,%20java.util.concurrent.TimeUnit)[LoggerContext.stop(long,
+java.util.concurrent.TimeUnit)]. (Not used if `shutdownHook` is set to
+"disable".)
+
+|status
+|The level of internal Log4j events that should be logged to the console.
+Valid values for this attribute are "trace", "debug", "info", "warn",
+"error" and "fatal". Log4j will log details about initialization,
+rollover and other internal actions to the status logger. Setting
+`status="trace"` is one of the first tools available to you if you need
+to troubleshoot log4j.
+
+(Alternatively, setting system property `log4j2.debug` will also print
+internal Log4j2 logging to the console, including internal logging that
+took place before the configuration file was found.)
+
+|strict
+|Enables the use of the strict XML format. Not supported in JSON
+configurations.
+
+|verbose
+|Enables diagnostic information while loading plugins.
+|===
+
+[[XML]]
+=== XML
+
+Log4j can be configured using two XML flavors; concise and strict. The
+concise format makes configuration very easy as the element names match
+the components they represent however it cannot be validated with an XML
+schema. For example, the ConsoleAppender is configured by declaring an
+XML element named Console under its parent appenders element. However,
+element and attribute names are are not case sensitive. In addition,
+attributes can either be specified as an XML attribute or as an XML
+element that has no attributes and has a text value. So
+
+[source,xml]
+----
+<PatternLayout pattern="%m%n"/>
+----
+
+and
+
+[source,xml]
+----
+<PatternLayout>
+  <Pattern>%m%n</Pattern>
+</PatternLayout>
+----
+
+are equivalent.
+
+The file below represents the structure of an XML configuration, but
+note that the elements in italics below represent the concise element
+names that would appear in their place.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>;
+<Configuration>
+  <Properties>
+    <Property name="name1">value</property>
+    <Property name="name2" value="value2"/>
+  </Properties>
+  <filter  ... />
+  <Appenders>
+    <appender ... >
+      <filter  ... />
+    </appender>
+    ...
+  </Appenders>
+  <Loggers>
+    <Logger name="name1">
+      <filter  ... />
+    </Logger>
+    ...
+    <Root level="level">
+      <AppenderRef ref="name"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+See the many examples on this page for sample appender, filter and
+logger declarations.
+
+=== Strict XML
+
+In addition to the concise XML format above, Log4j allows configurations
+to be specified in a more "normal" XML manner that can be validated
+using an XML Schema. This is accomplished by replacing the friendly
+element names above with their object type as shown below. For example,
+instead of the ConsoleAppender being configured using an element named
+Console it is instead configured as an appender element with a type
+attribute containing "Console".
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+  <Properties>
+    <Property name="name1">value</property>
+    <Property name="name2" value="value2"/>
+  </Properties>
+  <Filter type="type" ... />
+  <Appenders>
+    <Appender type="type" name="name">
+      <Filter type="type" ... />
+    </Appender>
+    ...
+  </Appenders>
+  <Loggers>
+    <Logger name="name1">
+      <Filter type="type" ... />
+    </Logger>
+    ...
+    <Root level="level">
+      <AppenderRef ref="name"/>
+    </Root>
+  </Loggers>
+</Configuration>
+----
+
+Below is a sample configuration using the strict format.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="debug" strict="true" name="XMLConfigTest"
+               packages="org.apache.logging.log4j.test">
+  <Properties>
+    <Property name="filename">target/test.log</Property>
+  </Properties>
+  <Filter type="ThresholdFilter" level="trace"/>
+
+  <Appenders>
+    <Appender type="Console" name="STDOUT">
+      <Layout type="PatternLayout" pattern="%m MDC%X%n"/>
+      <Filters>
+        <Filter type="MarkerFilter" marker="FLOW" onMatch="DENY" onMismatch="NEUTRAL"/>
+        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="DENY" onMismatch="ACCEPT"/>
+      </Filters>
+    </Appender>
+    <Appender type="Console" name="FLOW">
+      <Layout type="PatternLayout" pattern="%C{1}.%M %m %ex%n"/><!-- class and line number -->
+      <Filters>
+        <Filter type="MarkerFilter" marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
+        <Filter type="MarkerFilter" marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
+      </Filters>
+    </Appender>
+    <Appender type="File" name="File" fileName="${filename}">
+      <Layout type="PatternLayout">
+        <Pattern>%d %p %C{1.} [%t] %m%n</Pattern>
+      </Layout>
+    </Appender>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+      <Filter type="ThreadContextMapFilter">
+        <KeyValuePair key="test" value="123"/>
+      </Filter>
+      <AppenderRef ref="STDOUT"/>
+    </Logger>
+
+    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
+      <AppenderRef ref="File"/>
+    </Logger>
+
+    <Root level="trace">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
+----
+
+[#JSON]
+=== Configuration with JSON
+
+In addition to XML, Log4j can be configured using JSON. The JSON format
+is very similar to the concise XML format. Each key represents the name
+of a plugin and the key/value pairs associated with it are its
+attributes. Where a key contains more than a simple value it itself will
+be a subordinate plugin. In the example below, ThresholdFilter, Console,
+and PatternLayout are all plugins while the Console plugin will be
+assigned a value of STDOUT for its name attribute and the
+ThresholdFilter will be assigned a level of debug.
+
+[source,json]
+----
+{ "configuration": { "status": "error", "name": "RoutingTest",
+                     "packages": "org.apache.logging.log4j.test",
+      "properties": {
+        "property": { "name": "filename",
+                      "value" : "target/rolling1/rollingtest-$${sd:type}.log" }
+      },
+    "ThresholdFilter": { "level": "debug" },
+    "appenders": {
+      "Console": { "name": "STDOUT",
+        "PatternLayout": { "pattern": "%m%n" },
+        "ThresholdFilter": { "level": "debug" }
+      },
+      "Routing": { "name": "Routing",
+        "Routes": { "pattern": "$${sd:type}",
+          "Route": [
+            {
+              "RollingFile": {
+                "name": "Rolling-${sd:type}", "fileName": "${filename}",
+                "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
+                "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
+                "SizeBasedTriggeringPolicy": { "size": "500" }
+              }
+            },
+            { "AppenderRef": "STDOUT", "key": "Audit"}
+          ]
+        }
+      }
+    },
+    "loggers": {
+      "logger": { "name": "EventLogger", "level": "info", "additivity": "false",
+                  "AppenderRef": { "ref": "Routing" }},
+      "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
+    }
+  }
+}
+----
+
+Note that in the RoutingAppender the Route element has been declared as
+an array. This is valid because each array element will be a Route
+component. This won't work for elements such as appenders and filters,
+where each element has a different name in the concise format. Appenders
+and filters can be defined as array elements if each appender or filter
+declares an attribute named "type" that contains the type of the
+appender. The following example illustrates this as well as how to
+declare multiple loggers as an array.
+
+[source,json]
+----
+{ "configuration": { "status": "debug", "name": "RoutingTest",
+                      "packages": "org.apache.logging.log4j.test",
+      "properties": {
+        "property": { "name": "filename",
+                      "value" : "target/rolling1/rollingtest-$${sd:type}.log" }
+      },
+    "ThresholdFilter": { "level": "debug" },
+    "appenders": {
+      "appender": [
+         { "type": "Console", "name": "STDOUT", "PatternLayout": { "pattern": "%m%n" }, "ThresholdFilter": { "level": "debug" }},
+         { "type": "Routing",  "name": "Routing",
+          "Routes": { "pattern": "$${sd:type}",
+            "Route": [
+              {
+                "RollingFile": {
+                  "name": "Rolling-${sd:type}", "fileName": "${filename}",
+                  "filePattern": "target/rolling1/test1-${sd:type}.%i.log.gz",
+                  "PatternLayout": {"pattern": "%d %p %c{1.} [%t] %m%n"},
+                  "SizeBasedTriggeringPolicy": { "size": "500" }
+                }
+              },
+              { "AppenderRef": "STDOUT", "key": "Audit"}
+            ]
+          }
+        }
+      ]
+    },
+    "loggers": {
+      "logger": [
+        { "name": "EventLogger", "level": "info", "additivity": "false",
+          "AppenderRef": { "ref": "Routing" }},
+        { "name": "com.foo.bar", "level": "error", "additivity": "false",
+          "AppenderRef": { "ref": "STDOUT" }}
+      ],
+      "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
+    }
+  }
+}
+----
+
+Additional link:../runtime-dependencies.html[runtime dependencies] are
+required for using JSON configuration files.
+
+[#YAML]
+=== Configuration with YAML
+
+Log4j also supports using YAML for configuration files. The structure
+follows the same pattern as both the XML and YAML configuration formats.
+For example:
+
+[source,yaml]
+----
+Configuration:
+  status: warn
+  name: YAMLConfigTest
+  properties:
+    property:
+      name: filename
+      value: target/test-yaml.log
+  thresholdFilter:
+    level: debug
+  appenders:
+    Console:
+      name: STDOUT
+      PatternLayout:
+        Pattern: "%m%n"
+    File:
+      name: File
+      fileName: ${filename}
+      PatternLayout:
+        Pattern: "%d %p %C{1.} [%t] %m%n"
+      Filters:
+        ThresholdFilter:
+          level: error
+
+  Loggers:
+    logger:
+      -
+        name: org.apache.logging.log4j.test1
+        level: debug
+        additivity: false
+        ThreadContextMapFilter:
+          KeyValuePair:
+            key: test
+            value: 123
+        AppenderRef:
+          ref: STDOUT
+      -
+        name: org.apache.logging.log4j.test2
+        level: debug
+        additivity: false
+        AppenderRef:
+          ref: File
+    Root:
+      level: error
+      AppenderRef:
+        ref: STDOUT
+          
+----
+
+Additional link:../runtime-dependencies.html[runtime dependencies] are
+required for using YAML configuration files.
+
+[#Loggers]
+=== Configuring loggers
+
+An understanding of how loggers work in Log4j is critical before trying
+to configure them. Please reference the Log4j
+link:architecture.html[architecture] if more information is required.
+Trying to configure Log4j without understanding those concepts will lead
+to frustration.
+
+A LoggerConfig is configured using the `logger` element. The `logger`
+element must have a name attribute specified, will usually have a level
+attribute specified and may also have an additivity attribute specified.
+The level may be configured with one of TRACE, DEBUG, INFO, WARN, ERROR,
+ALL or OFF. If no level is specified it will default to ERROR. The
+additivity attribute may be assigned a value of true or false. If the
+attribute is omitted the default value of true will be used.
+
+A LoggerConfig (including the root LoggerConfig) can be configured with
+properties that will be added to the properties copied from the
+ThreadContextMap. These properties can be referenced from Appenders,
+Filters, Layouts, etc just as if they were part of the ThreadContext
+Map. The properties can contain variables that will be resolved either
+when the configuration is parsed or dynamically when each event is
+logged. See link:#PropertySubstitution[Property Substitution] for more
+information on using variables.
+
+The LoggerConfig may also be configured with one or more AppenderRef
+elements. Each appender referenced will become associated with the
+specified LoggerConfig. If multiple appenders are configured on the
+LoggerConfig each of them be called when processing logging events.
+
+*_Every configuration must have a root logger_*. If one is not
+configured the default root LoggerConfig, which has a level of ERROR and
+has a Console appender attached, will be used. The main differences
+between the root logger and other loggers are
+
+1.  The root logger does not have a name attribute.
+2.  The root logger does not support the additivity attribute since it
+has no parent.
+
+[#Appenders]
+=== Configuring Appenders
+
+An appender is configured either using the specific appender plugin's
+name or with an appender element and the type attibute containing the
+appender plugin's name. In addition each appender must have a name
+attribute specified with a value that is unique within the set of
+appenders. The name will be used by loggers to reference the appender as
+described in the previous section.
+
+Most appenders also support a layout to be configured (which again may
+be specified either using the specific Layout plugin's name as the
+element or with "layout" as the element name along with a type attribute
+that contains the layout plugin's name. The various appenders will
+contain other attributes or elements that are required for them to
+function properly.
+
+[#Filters]
+=== Configuring Filters
+
+Log4j allows a filter to be specified in any of 4 places:
+
+1.  At the same level as the appenders, loggers and properties elements.
+These filters can accept or reject events before they have been passed
+to a LoggerConfig.
+2.  In a logger element. These filters can accept or reject events for
+specific loggers.
+3.  In an appender element. These filters can prevent or cause events to
+be processed by the appender.
+4.  In an appender reference element. These filters are used to
+determine if a Logger should route the event to an appender.
+
+Although only a single `filter` element can be configured, that element
+may be the `filters` element which represents the CompositeFilter. The
+`filters` element allows any number of `filter` elements to be
+configured within it. The following example shows how multiple filters
+can be configured on the ConsoleAppender.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="debug" name="XMLConfigTest" packages="org.apache.logging.log4j.test">
+  <Properties>
+    <Property name="filename">target/test.log</Property>
+  </Properties>
+  <ThresholdFilter level="trace"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m MDC%X%n"/>
+    </Console>
+    <Console name="FLOW">
+      <!-- this pattern outputs class name and line number -->
+      <PatternLayout pattern="%C{1}.%M %m %ex%n"/>
+      <filters>
+        <MarkerFilter marker="FLOW" onMatch="ACCEPT" onMismatch="NEUTRAL"/>
+        <MarkerFilter marker="EXCEPTION" onMatch="ACCEPT" onMismatch="DENY"/>
+      </filters>
+    </Console>
+    <File name="File" fileName="${filename}">
+      <PatternLayout>
+        <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+      </PatternLayout>
+    </File>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+      <ThreadContextMapFilter>
+        <KeyValuePair key="test" value="123"/>
+      </ThreadContextMapFilter>
+      <AppenderRef ref="STDOUT"/>
+    </Logger>
+
+    <Logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
+      <Property name="user">${sys:user.name}</Property>
+      <AppenderRef ref="File">
+        <ThreadContextMapFilter>
+          <KeyValuePair key="test" value="123"/>
+        </ThreadContextMapFilter>
+      </AppenderRef>
+      <AppenderRef ref="STDOUT" level="error"/>
+    </Logger>
+
+    <Root level="trace">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
+----
+
+[#Properties]
+=== Configuration with Properties
+
+As of version 2.4, Log4j now supports configuration via properties
+files. Note that the property syntax is NOT the same as the syntax used
+in Log4j 1. Like the XML and JSON configurations, properties
+configurations define the configuration in terms of plugins and
+attributes to the plugins.
+
+Prior to version 2.6, the properties configuration requires that you
+list the identifiers of the appenders, filters and loggers, in a comma
+separated list in properties with those names. Each of those components
+will then be expected to be defined in sets of properties that begin
+with _component.<.identifier>._. The identifier does not have to match
+the name of the component being defined but must uniquely identify all
+the attributes and subcomponents that are part of the component. If the
+list of identifiers is not present the identier must not contain a '.'.
+Each individual component MUST have a "type" attribute specified that
+identifies the component's Plugin type.
+
+As of version 2.6, this list of identifiers is no longer required as
+names are inferred upon first usage, however if you wish to use more
+complex identifies you must still use the list. If the list is present
+it will be used.
+
+Unlike the base components, when creating subcomponents you cannot
+specify an element containing a list of identifiers. Instead, you must
+define the wrapper element with its type as is shown in the policies
+definition in the rolling file appender below. You then define each of
+the subcomponents below that wrapper element, as the
+TimeBasedTriggeringPolicy and SizeBasedTriggeringPolicy are defined
+below.
+
+Properties configuration files support the advertiser, monitorInterval,
+name, packages, shutdownHook, shutdownTimeout, status, verbose, and dest
+attributes. See link:#ConfigurationSyntax[Configuration Syntax] for the
+definitions of these attributes.
+
+[source,properties]
+----
+status = error
+dest = err
+name = PropertiesConfig
+
+property.filename = target/rolling/rollingtest.log
+
+filter.threshold.type = ThresholdFilter
+filter.threshold.level = debug
+
+appender.console.type = Console
+appender.console.name = STDOUT
+appender.console.layout.type = PatternLayout
+appender.console.layout.pattern = %m%n
+appender.console.filter.threshold.type = ThresholdFilter
+appender.console.filter.threshold.level = error
+
+appender.rolling.type = RollingFile
+appender.rolling.name = RollingFile
+appender.rolling.fileName = ${filename}
+appender.rolling.filePattern = target/rolling2/test1-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
+appender.rolling.layout.type = PatternLayout
+appender.rolling.layout.pattern = %d %p %C{1.} [%t] %m%n
+appender.rolling.policies.type = Policies
+appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
+appender.rolling.policies.time.interval = 2
+appender.rolling.policies.time.modulate = true
+appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
+appender.rolling.policies.size.size=100MB
+appender.rolling.strategy.type = DefaultRolloverStrategy
+appender.rolling.strategy.max = 5
+
+logger.rolling.name = com.example.my.app
+logger.rolling.level = debug
+logger.rolling.additivity = false
+logger.rolling.appenderRef.rolling.ref = RollingFile
+
+rootLogger.level = info
+rootLogger.appenderRef.stdout.ref = STDOUT
+          
+----
+
+[#PropertySubstitution]
+== Property Substitution
+
+Log4j 2 supports the ability to specify tokens in the configuration as
+references to properties defined elsewhere. Some of these properties
+will be resolved when the configuration file is interpreted while others
+may be passed to components where they will be evaluated at runtime. To
+accomplish this, Log4j uses variations of
+https://commons.apache.org/proper/commons-lang/[Apache Commons Lang]'s
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`]
+and
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`]
+classes. In a manner similar to Ant or Maven, this allows variables
+declared as `${name}` to be resolved using properties declared in the
+configuration itself. For example, the following example shows the
+filename for the rolling file appender being declared as a property.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="debug" name="RoutingTest" packages="org.apache.logging.log4j.test">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+      <ThresholdFilter level="debug"/>
+    </Console>
+    <Routing name="Routing">
+      <Routes pattern="$${sd:type}">
+        <Route>
+          <RollingFile name="Rolling-${sd:type}" fileName="${filename}"
+                       filePattern="target/rolling1/test1-${sd:type}.%i.log.gz">
+            <PatternLayout>
+              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+            </PatternLayout>
+            <SizeBasedTriggeringPolicy size="500" />
+          </RollingFile>
+        </Route>
+        <Route ref="STDOUT" key="Audit"/>
+      </Routes>
+    </Routing>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="EventLogger" level="info" additivity="false">
+      <AppenderRef ref="Routing"/>
+    </Logger>
+
+    <Root level="error">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
+----
+
+While this is useful, there are many more places properties can
+originate from. To accommodate this, Log4j also supports the syntax
+`${prefix:name}` where the prefix identifies tells Log4j that variable
+name should be evaluated in a specific context. See the
+link:lookups.html[Lookups] manual page for more details. The contexts
+that are built in to Logj4 are:
+
+[cols="1m,5"]
+|===
+|Prefix |Context
+
+|bundle
+|Resource bundle. The format is `${bundle:BundleName:BundleKey}`.
+The bundle name follows package naming conventions, for example:
+`${bundle:com.domain.Messages:MyKey}`.
+
+|ctx
+|Thread Context Map (MDC)
+
+|date
+|Inserts the current date and/or time using the specified format
+
+|env
+|System environment variables. The formats are `${env:ENV_NAME}` and `${env:ENV_NAME:-default_value}`.
+
+|jndi
+|A value set in the default JNDI Context.
+
+|jvmrunargs
+|A JVM input argument accessed through JMX, but not a main argument; see
+https://docs.oracle.com/javase/6/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[RuntimeMXBean.getInputArguments()].
+Not available on Android.
+
+|log4j
+|Log4j configuration properties. The expressions
+`${log4j:configLocation}` and `${log4j:configParentLocation}`
+respectively provide the absolute path to the log4j configuration file
+and its parent folder.
+
+|main
+|A value set with
+../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments-java.lang.String:A-[MapLookup.setMainArguments(String[])]
+
+|map
+|A value from a MapMessage
+
+|sd
+|A value from a StructuredDataMessage. The key "id" will return the
+name of the StructuredDataId without the enterprise number. The key
+"type" will return the message type. Other keys will retrieve individual
+elements from the Map.
+
+|sys
+|System properties. The formats are `${sys:some.property}` and
+`${sys:some.property:-default_value}`.
+|===
+
+A default property map can be declared in the configuration file. If the
+value cannot be located in the specified lookup the value in the default
+property map will be used. The default map is pre-populated with a value
+for "hostName" that is the current system's host name or IP address and
+the "contextName" with is the value of the current logging context.
+
+[#RuntimeLookup]
+== Lookup Variables with Multiple Leading '$' Characters
+
+An interesting feature of StrLookup processing is that when a variable
+reference is declared with multiple leading '$' characters each time the
+variable is resolved the leading '$' is simply removed. In the previous
+example the "Routes" element is capable of resolving the variable at
+runtime. To allow this the prefix value is specified as a variable with
+two leading '$' characters. When the configuration file is first
+processed the first '$' character is simply removed. Thus, when the
+Routes element is evaluated at runtime it is the variable declaration
+"$\{sd:type}" which causes the event to be inspected for a
+StructuredDataMessage and if one is present the value of its type
+attribute to be used as the routing key. Not all elements support
+resolving variables at runtime. Components that do will specifically
+call that out in their documentation.
+
+If no value is found for the key in the Lookup associated with the
+prefix then the value associated with the key in the properties
+declaration in the configuration file will be used. If no value is found
+the variable declaration will be returned as the value. Default values
+may be declared in the configuration by doing:
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration>
+  <Properties>
+    <Property name="type">Audit</property>
+  </Properties>
+  ...
+</Configuration>
+----
+
+_As a footnote, it is worth pointing out that the variables in the
+RollingFile appender declaration will also not be evaluated when the
+configuration is processed. This is simply because the resolution of the
+whole RollingFile element is deferred until a match occurs. See
+link:appenders.html#RoutingAppender[RoutingAppender] for more
+information._
+
+[#Scripts]
+== Scripts
+
+Log4j provides support for
+https://docs.oracle.com/javase/6/docs/technotes/guides/scripting/[JSR
+223] scripting languages to be used in some of its components. Any
+language that provides support for the JSR 223 scripting engine may be
+used. A list of the languages and bindings for them can be found at the
+https://java.net/projects/scripting/sources/svn/show/trunk/engines[Scripting
+Engine] web site. However, some of the languages listed there, such as
+JavaScript, Groovy and Beanshell, directly support the JSR 223 scripting
+framework and only require that the jars for that language be installed.
+
+The components that support using scripts do so by allowing a `<script>`,
+`<scriptFile>`, or `<scriptRef>` element to be configured on them. The
+script element contains a name for the script, the language of the
+script, and the script text. The scriptFile element contains the name of
+the script, its location, its language, its charset, and whether the
+file should be watched for changes. The scriptRef element contains the
+name of the script that is defined in the `<scripts>` configuration
+element. The name of the script is used to store the script, along with
+its ScriptEngine, so it can quickly be located each time the script
+needs to be run. While the name is not required, providing it will help
+in debugging problems when the script is running. The language must be
+provided on the script element and must specify one of the language
+names that appear in the Configuration status log as described in the
+next section. If the language is not specified on the scriptFile element
+the language will be determined by the file extension of the script
+path. If file monitoring is requested it will only be enabled if a
+non-zero monitorInterval is specified on the configuration element. That
+interval will be used to check for changes in the file.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="debug" name="RoutingTest">
+  <Scripts>
+    <Script name="selector" language="javascript"><![CDATA[
+            var result;
+            if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
+                result = "NoLocation";
+            } else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
+                result = "Flow";
+            }
+            result;
+            ]]></Script>
+    <ScriptFile name="groovy.filter" path="scripts/filter.groovy"/>
+  </Scripts>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <ScriptPatternSelector defaultPattern="%d %p %m%n">
+        <ScriptRef ref="selector"/>
+          <PatternMatch key="NoLocation" pattern="[%-5level] %c{1.} %msg%n"/>
+          <PatternMatch key="Flow" pattern="[%-5level] %c{1.} ====== %C{1.}.%M:%L %msg ======%n"/>
+      </ScriptPatternSelector>
+      <PatternLayout pattern="%m%n"/>
+    </Console>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="EventLogger" level="info" additivity="false">
+        <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
+          <Script name="GroovyFilter" language="groovy"><![CDATA[
+            if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
+                return true;
+            } else if (logEvent.getContextMap().containsKey("UserId")) {
+                return true;
+            }
+            return false;
+            ]]>
+          </Script>
+        </ScriptFilter>
+      <AppenderRef ref="STDOUT"/>
+    </Logger>
+
+    <Root level="error">
+      <ScriptFilter onMatch="ACCEPT" onMisMatch="DENY">
+        <ScriptRef ref="groovy.filter"/>
+      </ScriptFilter>
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
+----
+
+If the status attribute on the Configuration element is set to DEBUG the
+list of script engines currently installed and their attributes will be
+listed. Although some engines may say they are not thread safe, Log4j
+takes steps to insure that the scripts will run in a thread-safe manner
+if the engine advertises that it is not thread safe.
+
+....
+2015-09-27 16:13:22,925 main DEBUG Installed script engines
+2015-09-27 16:13:22,963 main DEBUG AppleScriptEngine Version: 1.1, Language: AppleScript, Threading: Not Thread Safe,
+            Compile: false, Names: {AppleScriptEngine, AppleScript, OSA}
+2015-09-27 16:13:22,983 main DEBUG Groovy Scripting Engine Version: 2.0, Language: Groovy, Threading: MULTITHREADED,
+            Compile: true, Names: {groovy, Groovy}
+2015-09-27 16:13:23,030 main DEBUG BeanShell Engine Version: 1.0, Language: BeanShell, Threading: MULTITHREADED,
+            Compile: true, Names: {beanshell, bsh, java}
+2015-09-27 16:13:23,039 main DEBUG Mozilla Rhino Version: 1.7 release 3 PRERELEASE, Language: ECMAScript, Threading: MULTITHREADED,
+            Compile: true, Names: {js, rhino, JavaScript, javascript, ECMAScript, ecmascript}
+....
+
+When the scripts are executed they will be provided with a set of
+variables that should allow them to accomplish whatever task they are
+expected to perform. See the documentation for the individual components
+for the list of variables that are available to the script.
+
+The components that support scripting expect a return value to be passed
+back to the calling Java code. This is not a problem for several of the
+scripting languages, but Javascript does not allow a return statement
+unless it is within a function. However, Javascript will return the
+value of the last statement executed in the script. As a consequence,
+code such as that shown below will result in the desired behavior.
+
+[source,javascript]
+----
+var result;
+if (logEvent.getLoggerName().equals("JavascriptNoLocation")) {
+    result = "NoLocation";
+} else if (logEvent.getMarker() != null && logEvent.getMarker().isInstanceOf("FLOW")) {
+    result = "Flow";
+}
+result;
+----
+
+=== A special note on Beanshell
+
+JSR 223 scripting engines are supposed to identify that they support the
+Compilable interface if they support compiling their scripts. Beanshell
+does this. However, whenever the compile method is called it throws an
+Error (not an Exception). Log4j catches this but will log the warning
+shown below for each Beanshell script when it tries to compile them. All
+Beanshell scripts will then be interpreted on each execution.
+
+....
+2015-09-27 16:13:23,095 main DEBUG Script BeanShellSelector is compilable
+2015-09-27 16:13:23,096 main WARN Error compiling script java.lang.Error: unimplemented
+            at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:175)
+            at bsh.engine.BshScriptEngine.compile(BshScriptEngine.java:154)
+            at org.apache.logging.log4j.core.script.ScriptManager$MainScriptRunner.<init>(ScriptManager.java:125)
+            at org.apache.logging.log4j.core.script.ScriptManager.addScript(ScriptManager.java:94)
+          
+....
+
+[#XInclude]
+== XInclude
+
+XML configuration files can include other files with
+http://www.xml.com/lpt/a/1009[XInclude]. Here is an example log4j2.xml
+file that includes two other files:
+
+.log4j2.xml
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<configuration xmlns:xi="http://www.w3.org/2001/XInclude"
+               status="warn" name="XIncludeDemo">
+  <properties>
+    <property name="filename">xinclude-demo.log</property>
+  </properties>
+  <ThresholdFilter level="debug"/>
+  <xi:include href="log4j-xinclude-appenders.xml" />
+  <xi:include href="log4j-xinclude-loggers.xml" />
+</configuration>
+----
+
+.log4j-xinclude-appenders.xml
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<appenders>
+  <Console name="STDOUT">
+    <PatternLayout pattern="%m%n" />
+  </Console>
+  <File name="File" fileName="${filename}" bufferedIO="true" immediateFlush="true">
+    <PatternLayout>
+      <pattern>%d %p %C{1.} [%t] %m%n</pattern>
+    </PatternLayout>
+  </File>
+</appenders>
+----
+
+.log4j-xinclude-loggers.xml
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<loggers>
+  <logger name="org.apache.logging.log4j.test1" level="debug" additivity="false">
+    <ThreadContextMapFilter>
+      <KeyValuePair key="test" value="123" />
+    </ThreadContextMapFilter>
+    <AppenderRef ref="STDOUT" />
+  </logger>
+
+  <logger name="org.apache.logging.log4j.test2" level="debug" additivity="false">
+    <AppenderRef ref="File" />
+  </logger>
+
+  <root level="error">
+    <AppenderRef ref="STDOUT" />
+  </root>
+</loggers>
+----
+
+[#CompositeConfiguration]
+== Composite Configuration
+
+Log4j allows multiple configuration files to be used by specifying them
+as a list of comma separated file paths on log4j.configurationFile. The
+merge logic can be controlled by specifying a class that implements the
+MergeStrategy interface on the log4j.mergeStrategy property. The default
+merge strategy will merge the files using the following rules:
+
+1.  The global configuration attributes are aggregated with those in
+later configurations replacing those in previous configurations, with
+the exception that the highest status level and the lowest
+monitorInterval greater than 0 will be used.
+2.  Properties from all configurations are aggregated. Duplicate
+properties replace those in previous configurations.
+3.  Filters are aggregated under a CompositeFilter if more than one
+Filter is defined. Since Filters are not named duplicates may be
+present.
+4.  Scripts and ScriptFile references are aggregated. Duplicate
+definitions replace those in previous configurations.
+5.  Appenders are aggregated. Appenders with the same name are replaced
+by those in later configurations, including all of the Appender's
+subcomponents.
+6.  Loggers are all aggregated. Logger attributes are individually
+merged with duplicates being replaced by those in later configurations.
+Appender references on a Logger are aggregated with duplicates being
+replaced by those in later configurations. Filters on a Logger are
+aggregated under a CompositeFilter if more than one Filter is defined.
+Since Filters are not named duplicates may be present. Filters under
+Appender references included or discarded depending on whether their
+parent Appender reference is kept or discarded.
+
+[#StatusMessages]
+== Status Messages
+
+****
+*Troubleshooting tip for the impatient:*
+
+From log4j-2.9 onward, log4j2 will print all internal logging to the
+console if system property `log4j2.debug` is defined (with any or no
+value).
+
+Prior to log4j-2.9, there are two places where internal logging can be
+controlled:
+
+* Before a configuration is found, status logger level can be controlled
+with system property
+`org.apache.logging.log4j.simplelog.StatusLogger.level`.
+* After a configuration is found, status logger level can be controlled
+in the configuration file with the "status" attribute, for example:
+`<Configuration status="trace">`.
+****
+
+Just as it is desirable to be able to diagnose problems in applications,
+it is frequently necessary to be able to diagnose problems in the
+logging configuration or in the configured components. Since logging has
+not been configured, "normal" logging cannot be used during
+initialization. In addition, normal logging within appenders could
+create infinite recursion which Log4j will detect and cause the
+recursive events to be ignored. To accomodate this need, the Log4j 2 API
+includes a
+link:../log4j-api/apidocs/org/apache/logging/log4j/status/StatusLogger.html[`StatusLogger`].
+Components declare an instance of the StatusLogger similar to:
+
+[source,java]
+----
+protected final static Logger logger = StatusLogger.getLogger();
+----
+
+Since StatusLogger implements the Log4j 2 API's Logger interface, all
+the normal Logger methods may be used.
+
+When configuring Log4j it is sometimes necessary to view the generated
+status events. This can be accomplished by adding the status attribute
+to the configuration element or a default value can be provided by
+setting the "Log4jDefaultStatusLevel" system property. Valid values of
+the status attribute are "trace", "debug", "info", "warn", "error" and
+"fatal". The following configuration has the status attribute set to
+debug.
+
+[source,xml]
+----
+<?xml version="1.0" encoding="UTF-8"?>
+<Configuration status="debug" name="RoutingTest">
+  <Properties>
+    <Property name="filename">target/rolling1/rollingtest-$${sd:type}.log</Property>
+  </Properties>
+  <ThresholdFilter level="debug"/>
+
+  <Appenders>
+    <Console name="STDOUT">
+      <PatternLayout pattern="%m%n"/>
+      <ThresholdFilter level="debug"/>
+    </Console>
+    <Routing name="Routing">
+      <Routes pattern="$${sd:type}">
+        <Route>
+          <RollingFile name="Rolling-${sd:type}" fileName="${filename}"
+                       filePattern="target/rolling1/test1-${sd:type}.%i.log.gz">
+            <PatternLayout>
+              <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+            </PatternLayout>
+            <SizeBasedTriggeringPolicy size="500" />
+          </RollingFile>
+        </Route>
+        <Route ref="STDOUT" key="Audit"/>
+      </Routes>
+    </Routing>
+  </Appenders>
+
+  <Loggers>
+    <Logger name="EventLogger" level="info" additivity="false">
+      <AppenderRef ref="Routing"/>
+    </Logger>
+
+    <Root level="error">
+      <AppenderRef ref="STDOUT"/>
+    </Root>
+  </Loggers>
+
+</Configuration>
+----
+
+During startup this configuration produces:
+
+....
+2011-11-23 17:08:00,769 DEBUG Generated plugins in 0.003374000 seconds
+2011-11-23 17:08:00,789 DEBUG Calling createProperty on class org.apache.logging.log4j.core.config.Property for element property with params(name="filename", value="target/rolling1/rollingtest-${sd:type}.log")
+2011-11-23 17:08:00,792 DEBUG Calling configureSubstitutor on class org.apache.logging.log4j.core.config.PropertiesPlugin for element properties with params(properties={filename=target/rolling1/rollingtest-${sd:type}.log})
+2011-11-23 17:08:00,794 DEBUG Generated plugins in 0.001362000 seconds
+2011-11-23 17:08:00,797 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null")
+2011-11-23 17:08:00,800 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%m%n", Configuration(RoutingTest), null, charset="null")
+2011-11-23 17:08:00,802 DEBUG Generated plugins in 0.001349000 seconds
+2011-11-23 17:08:00,804 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.ConsoleAppender for element Console with params(PatternLayout(%m%n), null, target="null", name="STDOUT", ignoreExceptions="null")
+2011-11-23 17:08:00,804 DEBUG Calling createFilter on class org.apache.logging.log4j.core.filter.ThresholdFilter for element ThresholdFilter with params(level="debug", onMatch="null", onMismatch="null")
+2011-11-23 17:08:00,813 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="null", key="null", Node=Route)
+2011-11-23 17:08:00,823 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="STDOUT", key="Audit", Node=Route)
+2011-11-23 17:08:00,825 DEBUG Calling createRoutes on class org.apache.logging.log4j.core.appender.routing.Routes for element Routes with params(pattern="${sd:type}", routes={Route(type=dynamic default), Route(type=static Reference=STDOUT key='Audit')})
+2011-11-23 17:08:00,827 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.routing.RoutingAppender for element Routing with params(name="Routing", ignoreExceptions="null", Routes({Route(type=dynamic default),Route(type=static Reference=STDOUT key='Audit')}), Configuration(RoutingTest), null, null)
+2011-11-23 17:08:00,827 DEBUG Calling createAppenders on class org.apache.logging.log4j.core.config.AppendersPlugin for element appenders with params(appenders={STDOUT, Routing})
+2011-11-23 17:08:00,828 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="Routing")
+2011-11-23 17:08:00,829 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig for element logger with params(additivity="false", level="info", name="EventLogger", AppenderRef={Routing}, null)
+2011-11-23 17:08:00,830 DEBUG Calling createAppenderRef on class org.apache.logging.log4j.core.config.plugins.AppenderRefPlugin for element AppenderRef with params(ref="STDOUT")
+2011-11-23 17:08:00,831 DEBUG Calling createLogger on class org.apache.logging.log4j.core.config.LoggerConfig$RootLogger for element root with params(additivity="null", level="error", AppenderRef={STDOUT}, null)
+2011-11-23 17:08:00,833 DEBUG Calling createLoggers on class org.apache.logging.log4j.core.config.LoggersPlugin for element loggers with params(loggers={EventLogger, root})
+2011-11-23 17:08:00,834 DEBUG Reconfiguration completed
+2011-11-23 17:08:00,846 DEBUG Calling createLayout on class org.apache.logging.log4j.core.layout.PatternLayout for element PatternLayout with params(pattern="%d %p %c{1.} [%t] %m%n", Configuration(RoutingTest), null, charset="null")
+2011-11-23 17:08:00,849 DEBUG Calling createPolicy on class org.apache.logging.log4j.core.appender.rolling.SizeBasedTriggeringPolicy for element SizeBasedTriggeringPolicy with params(size="500")
+2011-11-23 17:08:00,851 DEBUG Calling createAppender on class org.apache.logging.log4j.core.appender.RollingFileAppender for element RollingFile with params(fileName="target/rolling1/rollingtest-Unknown.log", filePattern="target/rolling1/test1-Unknown.%i.log.gz", append="null", name="Rolling-Unknown", bufferedIO="null", immediateFlush="null", SizeBasedTriggeringPolicy(SizeBasedTriggeringPolicy(size=500)), null, PatternLayout(%d %p %c{1.} [%t] %m%n), null, ignoreExceptions="null")
+2011-11-23 17:08:00,858 DEBUG Generated plugins in 0.002014000 seconds
+2011-11-23 17:08:00,889 DEBUG Reconfiguration started for context sun.misc.Launcher$AppClassLoader@37b90b39
+2011-11-23 17:08:00,890 DEBUG Generated plugins in 0.001355000 seconds
+2011-11-23 17:08:00,959 DEBUG Generated plugins in 0.001239000 seconds
+2011-11-23 17:08:00,961 DEBUG Generated plugins in 0.001197000 seconds
+2011-11-23 17:08:00,965 WARN No Loggers were configured, using default
+2011-11-23 17:08:00,976 DEBUG Reconfiguration completed
+....
+
+If the status attribute is set to error than only error messages will be
+written to the console. This makes troubleshooting configuration errors
+possible. As an example, if the configuration above is changed to have
+the status set to error and the logger declaration is:
+
+[source,xml]
+----
+<logger name="EventLogger" level="info" additivity="false">
+  <AppenderRef ref="Routng"/>
+</logger>
+----
+
+the following error message will be produced.
+
+....
+2011-11-24 23:21:25,517 ERROR Unable to locate appender Routng for logger EventLogger
+....
+
+Applications may wish to direct the status output to some other
+destination. This can be accomplished by setting the dest attribute to
+either "err" to send the output to stderr or to a file location or URL.
+This can also be done by insuring the configured status is set to OFF
+and then configuring the application programmatically such as:
+
+[source,java]
+----
+StatusConsoleListener listener = new StatusConsoleListener(Level.ERROR);
+StatusLogger.getLogger().registerListener(listener);
+----
+
+[#UnitTestingInMaven]
+== Testing in Maven
+
+Maven can run unit and functional tests during the build cycle. By
+default, any files placed in `src/test/resources` are automatically
+copied to target/test-classes and are included in the classpath during
+execution of any tests. As such, placing a log4j2-test.xml into this
+directory will cause it to be used instead of a log4j2.xml or
+log4j2.json that might be present. Thus a different log configuration
+can be used during testing than what is used in production.
+
+A second approach, which is extensively used by Log4j 2, is to set the
+log4j.configurationFile property in the method annotated with
+@BeforeClass in the junit test class. This will allow an arbitrarily
+named file to be used during the test.
+
+A third approach, also used extensively by Log4j 2, is to use the
+`LoggerContextRule` JUnit test rule which provides additional
+convenience methods for testing. This requires adding the `log4j-core`
+`test-jar` dependency to your test scope dependencies. For example:
+
+[source,java]
+----
+public class AwesomeTest {
+    @Rule
+    public LoggerContextRule init = new LoggerContextRule("MyTestConfig.xml");
+
+    @Test
+    public void testSomeAwesomeFeature() {
+        final LoggerContext ctx = init.getContext();
+        final Logger logger = init.getLogger("org.apache.logging.log4j.my.awesome.test.logger");
+        final Configuration cfg = init.getConfiguration();
+        final ListAppender app = init.getListAppender("List");
+        logger.warn("Test message");
+        final List<LogEvent> events = app.getEvents();
+        // etc.
+    }
+}
+----
+
+[#SystemProperties]
+== System Properties
+
+The Log4j documentation references a number of System Properties that
+can be used to control various aspects of Log4j 2 behavior. The table
+below lists these properties along with their default value and a
+description of what they control. Any spaces present in the property
+name are for visual flow and should be removed.
+
+Note that beginning in Log4j 2.10, all system property names have been
+normalized to follow a consistent naming scheme. While the old property
+names are still supported for backwards compatibility, it is recommended
+to update configurations to use the new style. This system is extensible
+and is enabled through the
+link:../log4j-api/apidocs/org/apache/logging/log4j/util/PropertySource.html[`PropertySource`]
+interface. Additional property source classes can be added through the
+standard `ServiceLoader` mechanism in Java SE.
+
+Properties can be overridden by sources with a lower number priority
+(e.g.., -100 comes before 100). The following sources are all available
+by default:
+
+.PropertySource priorities and descriptions
+[cols="2,1,5"]
+|===
+|Source |Priority |Description
+
+|Environment Variables
+|-100
+|Environment variables are all prefixed
+with `LOG4J_`, are in all caps, and words are all separated by
+underscores. Only this naming scheme is support for environment
+variables as there were no old naming schemes to maintain compatibility
+with.
+
+|`log4j2.component.properties` file
+|0
+|Including this file on the
+classpath can be used as an alternative to providing properties as
+system properties. This has priority over system properties, but they
+can be overridden by environment variables as described above.
+
+|System Properties
+|100
+|All properties can be set using normal system
+property patterns. These have the lowest priority and can be overridden
+by included properties files or environment variables.
+|===
+
+The following is a list of available global configuration properties.
+Note that these can only be set once per JVM process unlike
+configuration settings available in configuration files. The _Property
+Name_ column contains the name used in properties files and system
+properties; _Environment Variable_ for the equivalent environment
+variable; and _Legacy Property Name_ for the pre-2.10 name.
+
+.Log4j 2 global configuration properties
+[cols="3*,a"]
+|===
+|Property Name (Legacy Property Name) |Environment Variable |Default Value |Description
+
+|[[configurationFile]]log4j2.configurationFile +
+([[log4j.configurationFile]]log4j.configurationFile)
+|LOG4J_CONFIGURATION_FILE
+| 
+|Path to an Log4j 2 configuration file. May
+also contain a comma separated list of configuration file names.
+
+|[[debug]]log4j2.debug +
+([[log4j2.debug]]log4j2.debug)
+|LOG4J_DEBUG
+| 
+|Log4j2 will print all
+internal logging to the console if system property `log4j2.debug` is
+defined (with any or no value).
+
+|[[mergeFactory]]log4j2.mergeFactory +
+([[log4j.mergeFactory]]log4j.mergeFactory)
+|LOG4J_MERGE_FACTORY
+| 
+|The name of the class that implements the MergeStrategy interface. If not
+specified `DefaultMergeStrategy` will be used when creating a CompositeConfiguration.
+
+|[[contextSelector]]log4j2.contextSelector +
+([[Log4jContextSelector]]Log4jContextSelector)
+|LOG4J_CONTEXT_SELECTOR
+|ClassLoaderContextSelector
+|Creates the `LoggerContext`s. An
+application can have one or more active LoggerContexts depending on the
+circumstances. See link:logsep.html[Log Separation] for more details.
+Available context selector implementation classes: +
+`org.apache.logging.log4j.core.async .AsyncLoggerContextSelector` -
+makes link:async.html[all loggers asynchronous]. +
+`org.apache.logging.log4j.core.selector .BasicContextSelector` - creates
+a single shared LoggerContext. +
+`org.apache.logging.log4j.core.selector .ClassLoaderContextSelector` -
+separate LoggerContexts for each web application. +
+`org.apache.logging.log4j.core.selector .JndiContextSelector` - use JNDI
+to locate each web application's LoggerContext. +
+`org.apache.logging.log4j.core.osgi .BundleContextSelector` - separate
+LoggerContexts for each OSGi bundle.
+
+|[[logEventFactory]]log4j2.logEventFactory +
+([[Log4jLogEventFactory]]Log4jLogEventFactory)
+|LOG4J_LOG_EVENT_FACTORY
+|org.apache.logging.log4j.core.impl .DefaultLogEventFactory
+|Factory class used by LoggerConfig to create `LogEvent` instances. (Ignored when
+the `AsyncLoggerContextSelector` is used.)
+
+|[[loggerContextFactory]]log4j2.loggerContextFactory +
+([[log4j2.loggerContextFactory]]log4j2.loggerContextFactory)
+|LOG4J_LOGGER_CONTEXT_FACTORY
+|org.apache.logging.log4j.simple
+.SimpleLoggerContextFactory
+|Factory class used by LogManager to
+bootstrap the logging implementation. The core jar provides
+`org.apache.logging.log4j.core .impl.Log4jContextFactory`.
+
+|[[configurationFactory]]log4j2.configurationFactory +
+([[log4j.configurationFactory]]log4j.configurationFactory)
+|LOG4J_CONFIGURATION_FACTORY
+| 
+|Fully specified class name of a class
+extending
+`org.apache.logging.log4j.core .config.ConfigurationFactory`.
+If specified, an instance of this class is added to the list of
+configuration factories.
+
+|[[shutdownHookEnabled]]log4j2.shutdownHookEnabled +
+([[log4j.shutdownHookEnabled]]log4j.shutdownHookEnabled)
+|LOG4J_SHUTDOWN_HOOK_ENABLED
+|true
+|Overrides the global flag for
+whether or not a shutdown hook should be used to stop a
+`LoggerContext`. By default, this is enabled and can be
+disabled on a per-configuration basis. When running with the `log4j-web`
+module, this is automatically disabled.
+
+|[[shutdownCallbackRegistry]]log4j2.shutdownCallbackRegistry +
+([[log4j.shutdownCallbackRegistry]]log4j.shutdownCallbackRegistry)
+|LOG4J_SHUTDOWN_CALLBACK_REGISTRY
+|org.apache.logging.log4j.core.util
+.DefaultShutdownCallbackRegistry
+|Fully specified class name of a class implementing
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/util/ShutdownCallbackRegistry.html[ShutdownCallbackRegistry].
+If specified, an instance of this class is used instead of
+`DefaultShutdownCallbackRegistry`. The specified class must have a
+default constructor.
+
+|[[clock]]log4j2.clock +
+([[log4j.Clock]]log4j.Clock)
+|LOG4J_CLOCK
+|SystemClock
+|Implementation
+of the `org.apache.logging.log4j .core.time.Clock` interface that is
+used for timestamping the log events. +
+By default, `System.currentTimeMillis` is called on every log event. +
+You can also specify a fully qualified class name of a custom class that
+implements the `Clock` interface.
+
+|[[level]]log4j2.level +
+([[org.apache.logging.log4j.level]]org.apache.logging.log4j.level)
+|LOG4J_LEVEL
+|ERROR
+|Log level of the default configuration. The default
+configuration is used if the ConfigurationFactory could not successfully
+create a configuration (e.g. no log4j2.xml file was found).
+
+|[[disableThreadContext]]log4j2.disableThreadContext +
+(disableThreadContext)
+|LOG4J_DISABLE_THREAD_CONTEXT
+|false
+|If `true`,
+the ThreadContext stack and map are disabled. (May be ignored if a
+custom ThreadContext map is specified.)
+
+|[[disableThreadContextStack]]log4j2.disableThreadContextStack +
+(disableThreadContextStack)
+|LOG4J_DISABLE_THREAD_CONTEXT_STACK
+|false
+|If `true`, the ThreadContext stack is disabled.
+
+|[[disableThreadContextMap]]log4j2.disableThreadContextMap +
+(disableThreadContextMap)
+|LOG4J_DISABLE_THREAD_CONTEXT_MAP
+|false
+|If
+`true`, the ThreadContext map is disabled. (May be ignored if a custom
+ThreadContext map is specified.)
+
+|[[log4j2.threadContextMap]]log4j2.threadContextMap +
+(log4j2.threadContextMap)
+|LOG4J_THREAD_CONTEXT_MAP
+| 
+|Fully specified
+class name of a custom `ThreadContextMap` implementation class.
+
+|[[isThreadContextMapInheritable]]log4j2.isThreadContextMapInheritable +
+(isThreadContextMapInheritable)
+|LOG4J_IS_THREAD_CONTEXT_MAP_INHERITABLE
+|false
+|If `true` use a `InheritableThreadLocal` to implement the
+ThreadContext map. Otherwise, use a plain `ThreadLocal`. (May be ignored
+if a custom ThreadContext map is specified.)
+
+|[[contextDataInjector]]log4j2.contextDataInjector +
+([[log4j2.ContextDataInjector]]log4j2.ContextDataInjector)
+|LOG4J_CONTEXT_DATA_INJECTOR
+| 
+|Fully specified class name of a custom
+`ContextDataInjector` implementation class.
+
+|[[garbagefreeThreadContextMap]]log4j2.garbagefreeThreadContextMap +
+([[log4j2.garbagefree.threadContextMap]]log4j2.garbagefree.threadContextMap)
+|LOG4J_GARBAGEFREE_THREAD_CONTEXT_MAP
+|false
+|Specify "true" to make the
+ThreadContext map garbage-free.
+
+|[[disableJmx]]log4j2.disableJmx +
+([[log4j2.disable.jmx]]log4j2.disable.jmx)
+|LOG4J_DISABLE_JMX
+|false
+|If
+`true`, Log4j configuration objects like LoggerContexts, Appenders,
+Loggers, etc. will not be instrumented with MBeans and cannot be
+remotely monitored and managed.
+
+|[[jmxNotifyAsync]]log4j2.jmxNotifyAsync +
+([[log4j2.jmx.notify.async]]log4j2.jmx.notify.async)
+|LOG4J_JMX_NOTIFY_ASYNC
+|false for web apps, true otherwise
+|If `true`,
+log4j's JMX notifications are sent from a separate background thread,
+otherwise they are sent from the caller thread. If system property
+`log4j2.is.webapp` is `true` or the `javax.servlet.Servlet` class is on
+the classpath, the default behaviour is to use the caller thread to send
+JMX notifications.
+
+|[[skipJansi]]log4j2.skipJansi +
+([[log4j.skipJansi]]log4j.skipJansi)
+|LOG4J_SKIP_JANSI
+|true
+|If `true`,
+the ConsoleAppender will not try to use the Jansi output stream on
+Windows.
+
+|[[ignoreTCL]]log4j2.ignoreTCL +
+([[log4j.ignoreTCL]]log4j.ignoreTCL)
+|LOG4J_IGNORE_TCL
+|false
+|If
+`true`, classes are only loaded with the default class loader.
+Otherwise, an attempt is made to load classes with the current thread's
+context class loader before falling back to the default class loader.
+
+|[[uuidSequence]]log4j2.uuidSequence +
+([[org.apache.logging.log4j.uuidSequence]]org.apache.logging.log4j.uuidSequence)
+|LOG4J_UUID_SEQUENCE
+|0
+|System property that may be used to seed the
+UUID generation with an integer value.
+
+|[[simplelogShowContextMap]]log4j2.simplelogShowContextMap +
+([[org.apache.logging.log4j.simplelog.showContextMap]]org.apache.logging.log4j
+.simplelog.showContextMap)
+|LOG4J_SIMPLELOG_SHOW_CONTEXT_MAP
+|false
+|If
+`true`, the full ThreadContext map is included in each SimpleLogger log
+message.
+
+|[[simplelogShowlogname]]log4j2.simplelogShowlogname +
+([[org.apache.logging.log4j.simplelog.showlogname]]org.apache.logging.log4j
+.simplelog.showlogname)
+|LOG4J_SIMPLELOG_SHOWLOGNAME
+|false
+|If `true`,
+the logger name is included in each SimpleLogger log message.
+
+|[[simplelogShowShortLogname]]log4j2.simplelogShowShortLogname +
+([[org.apache.logging.log4j.simplelog.showShortLogname]]org.apache.logging.log4j
+.simplelog.showShortLogname)
+|LOG4J_SIMPLELOG_SHOW_SHORT_LOGNAME
+|true
+|If `true`, only the last component of a logger name is included in
+SimpleLogger log messages. (E.g., if the logger name is
+"mycompany.myproject.mycomponent", only "mycomponent" is logged.
+
+|[[simplelogShowdatetime]]log4j2.simplelogShowdatetime +
+([[org.apache.logging.log4j.simplelog.showdatetime]]org.apache.logging.log4j
+.simplelog.showdatetime)
+|LOG4J_SIMPLELOG_SHOWDATETIME
+|false
+|If
+`true`, SimpleLogger log messages contain timestamp information.
+
+|[[simplelogDateTimeFormat]]log4j2.simplelogDateTimeFormat +
+([[org.apache.logging.log4j.simplelog.dateTimeFormat]]org.apache.logging.log4j
+.simplelog.dateTimeFormat)
+|LOG4J_SIMPLELOG_DATE_TIME_FORMAT
+|"yyyy/MM/dd HH:mm:ss:SSS zzz"
+|Date-time format to use. Ignored if
+`org.apache.logging.log4j .simplelog.showdatetime` is `false`.
+
+|[[simplelogLogFile]]log4j2.simplelogLogFile +
+([[org.apache.logging.log4j.simplelog.logFile]]org.apache.logging.log4j
+.simplelog.logFile)
+|LOG4J_SIMPLELOG_LOG_FILE
+|system.err
+|"system.err"
+(case-insensitive) logs to System.err, "system.out" (case-insensitive)
+logs to System.out, any other value is interpreted as a file name to
+save SimpleLogger messages to.
+
+|[[simplelogLevel]]log4j2.simplelogLevel +
+([[org.apache.logging.log4j.simplelog.level]]org.apache.logging.log4j
+.simplelog.level)
+|LOG4J_SIMPLELOG_LEVEL
+|ERROR
+|Default level for new
+SimpleLogger instances.
+
+|log4j2.simplelog.<loggerName>.level +
+([[org.apache.logging.log4j.simplelog.[loggerName]level]]org.apache.logging.log4j
+.simplelog.<loggerName>.level)
+|LOG4J_SIMPLELOG_<LOGGER_NAME>_LEVEL
+|SimpleLogger default log level
+|Log level for a the SimpleLogger
+instance with the specified name.
+
+|[[simplelogStatusLoggerLevel]]log4j2.simplelogStatusLoggerLevel +
+([[org.apache.logging.log4j.simplelog.StatusLogger.level]]org.apache.logging.log4j.simplelog
+.StatusLogger.level)
+|LOG4J_SIMPLELOG_STATUS_LOGGER_LEVEL
+|ERROR
+|This
+property is used to control the initial StatusLogger level, and can be
+overridden in code by calling
+`StatusLogger.getLogger() .setLevel(someLevel)`. Note that the
+StatusLogger level is only used to determine the status log output level
+until a listener is registered. In practice, a listener is registered
+when a configuration is found, and from that point onwards, status
+messages are only sent to the listeners (depending on their
+statusLevel).
+
+|[[defaultStatusLevel]]log4j2.defaultStatusLevel +
+([[Log4jDefaultStatusLevel]]Log4jDefaultStatusLevel)
+|LOG4J_DEFAULT_STATUS_LEVEL
+|ERROR
+|
+The StatusLogger logs events that occur in the logging system to the
+console. During configuration, AbstractConfiguration registers a
+StatusConsoleListener with the StatusLogger that may redirect status log
+events from the default console output to a file. The listener also
+supports fine-grained filtering. This system property specifies the
+default status log level for the listener to use if the configuration
+does not specify a status level.
+
+Note: this property is used by the log4j-core implementation only after
+a configuration file has been found.
+
+|[[statusLoggerLevel]]log4j2.statusLoggerLevel +
+([[log4j2.StatusLogger.level]]log4j2.StatusLogger.level)
+|LOG4J_STATUS_LOGGER_LEVEL
+|WARN
+|
+The initial "listenersLevel" of the StatusLogger. If StatusLogger
+listeners are added, the "listenerLevel" is changed to that of the most
+verbose listener. If any listeners are registered, the listenerLevel is
+used to quickly determine if an interested listener exists.
+
+By default, StatusLogger listeners are added when a configuration is
+found and by the JMX StatusLoggerAdmin MBean. For example, if a
+configuration contains `<Configuration status="trace">`, a listener with
+statusLevel TRACE is registered and the StatusLogger listenerLevel is
+set to TRACE, resulting in verbose status messages displayed on the
+console.
+
+If no listeners are registered, the listenersLevel is not used, and the
+StatusLogger output level is determined by
+`StatusLogger.getLogger().getLevel()` (see property
+`org.apache.logging.log4j.simplelog .StatusLogger.level`).
+
+|[[statusEntries]]log4j2.statusEntries +
+([[log4j2.status.entries]]log4j2.status.entries)
+|LOG4J_STATUS_ENTRIES
+|200
+|Number of StatusLogger events that are kept in a buffer and can be
+retrieved with `StatusLogger.getStatusData()`.
+
+|[[statusLoggerDateformat]]log4j2.statusLoggerDateformat +
+([[log4j2.StatusLogger.DateFormat]]log4j2.StatusLogger.DateFormat)
+|LOG4J_STATUS_LOGGER_DATEFORMAT
+| 
+|Date-time format string to use as
+the format for timestamps in the status logger output. See
+`java.text.SimpleDateFormat` for supported formats.
+
+|[[asyncLoggerExceptionHandler]]log4j2.asyncLoggerExceptionHandler +
+([[AsyncLogger.ExceptionHandler]]AsyncLogger.ExceptionHandler)
+|LOG4J_ASYNC_LOGGER_EXCEPTION_HANDLER
+|default handler
+|See
+link:async.html#SysPropsAllAsync[Async Logger System Properties] for
+details.
+
+|[[asyncLoggerRingBufferSize]]log4j2.asyncLoggerRingBufferSize +
+([[AsyncLogger.RingBufferSize]]AsyncLogger.RingBufferSize)
+|LOG4J_ASYNC_LOGGER_RING_BUFFER_SIZE
+|256 * 1024
+|See
+link:async.html#SysPropsAllAsync[Async Logger System Properties] for
+details.
+
+|[[asyncLoggerWaitStrategy]]log4j2.asyncLoggerWaitStrategy +
+([[AsyncLogger.WaitStrategy]]AsyncLogger.WaitStrategy)
+|LOG4J_ASYNC_LOGGER_WAIT_STRATEGY
+|Timeout
+|See
+link:async.html#SysPropsAllAsync[Async Logger System Properties] for
+details.
+
+|[[asyncLoggerThreadNameStrategy]]log4j2.asyncLoggerThreadNameStrategy +
+([[AsyncLogger.ThreadNameStrategy]]AsyncLogger.ThreadNameStrategy)
+|LOG4J_ASYNC_LOGGER_THREAD_NAME_STRATEGY
+|CACHED
+|See
+link:async.html#SysPropsAllAsync[Async Logger System Properties] for
+details.
+
+|[[asyncLoggerConfigExceptionHandler]]log4j2.asyncLoggerConfigExceptionHandler +
+([[AsyncLoggerConfig.ExceptionHandler]]AsyncLoggerConfig.ExceptionHandler)
+|LOG4J_ASYNC_LOGGER_CONFIG_EXCEPTION_HANDLER
+|default handler
+|See
+link:async.html#SysPropsMixedSync-Async[Mixed Async/Synchronous Logger
+System Properties] for details.
+
+|[[asyncLoggerConfigRingBufferSize]]log4j2.asyncLoggerConfigRingBufferSize +
+([[AsyncLoggerConfig.RingBufferSize]]AsyncLoggerConfig.RingBufferSize)
+|LOG4J_ASYNC_LOGGER_CONFIG_RING_BUFFER_SIZE
+|256 * 1024
+|See
+link:async.html#SysPropsMixedSync-Async[Mixed Async/Synchronous Logger
+System Properties] for details.
+
+|[[asyncLoggerConfigWaitStrategy]]log4j2.asyncLoggerConfigWaitStrategy +
+([[AsyncLoggerConfig.WaitStrategy]]AsyncLoggerConfig.WaitStrategy)
+|LOG4J_ASYNC_LOGGER_CONFIG_WAIT_STRATEGY
+|Timeout
+|See
+link:async.html#SysPropsMixedSync-Async[Mixed Async/Synchronous Logger
+System Properties] for details.
+
+|[[julLoggerAdapter]]log4j2.julLoggerAdapter +
+([[log4j.jul.LoggerAdapter]]log4j.jul.LoggerAdapter)
+|LOG4J_JUL_LOGGER_ADAPTER
+|org.apache.logging.log4j
+.jul.ApiLoggerAdapter
+|Default LoggerAdapter to use in the JUL adapter.
+By default, if log4j-core is available, then the class
+`org.apache.logging.log4j.jul .CoreLoggerAdapter` will be used.
+Otherwise, the `ApiLogggerAdapter` will be used. Custom implementations
+must provide a public default constructor.
+
+|[[formatMsgAsync]]log4j2.formatMsgAsync +
+([[log4j.format.msg.async]]log4j.format.msg.async)
+|LOG4J_FORMAT_MSG_ASYNC
+|false
+|If `false` (the default), Log4j will
+make sure the message is formatted in the caller thread, to ensure the
+value at the time of the call to the logger is the value that is logged.
+
+|[[asyncQueueFullPolicy]]log4j2.asyncQueueFullPolicy +
+([[log4j2.AsyncQueueFullPolicy]]log4j2.AsyncQueueFullPolicy)
+|LOG4J_ASYNC_QUEUE_FULL_POLICY
+| 
+|
+Used by Async Loggers and the AsyncAppender to maintain application
+throughput even when the underlying appender cannot keep up with the
+logging rate and the queue is filling up.
+
+If no value is specified (the default) events are never discarded. If
+the queue is full, the logger call blocks until the event can be added
+to the queue.
+
+Specify `Discard` to drop events whose level is equal or less than the
+threshold level (INFO by default) when the queue is full.
+
+|[[discardThreshold]]log4j2.discardThreshold +
+([[log4j2.DiscardThreshold]]log4j2.DiscardThreshold)
+|LOG4J_DISCARD_THRESHOLD
+|INFO
+|Used by the
+DiscardingAsyncQueueFullPolicy to determine which events to drop when
+the queue becomes full. By default, `INFO`, `DEBUG` and `TRACE` level
+events are discarded when the queue is full. This property only has
+effect if `Discard` is specified as the `log4j2.AsyncQueueFullPolicy`.
+
+|[[messageFactory]]log4j2.messageFactory +
+([[log4j2.messageFactory]]log4j2.messageFactory)
+|LOG4J_MESSAGE_FACTORY
+|org.apache.logging.log4j.message. ParameterizedMessageFactory or
+org.apache.logging.log4j.message. ReusableMessageFactory in garbage-free
+mode
+|Default message factory used by Loggers if no factory was
+specified.
+
+|[[flowMessageFactory]]log4j2.flowMessageFactory +
+([[log4j2.flowMessageFactory]]log4j2.flowMessageFactory)
+|LOG4J_FLOW_MESSAGE_FACTORY
+|org.apache.logging.log4j.message.
+DefaultFlowMessageFactory
+|Default flow message factory used by Loggers.
+
+|[[isWebapp]]log4j2.isWebapp +
+([[log4j2.is.webapp]]log4j2.is.webapp)
+|LOG4J_IS_WEBAPP
+|true if
+`Servlet` class on class path
+|This system property can be used to force
+Log4j 2 to behave as if it is part of a web application (when true) or
+as if it is not part of a web application (when false).
+
+|[[enableThreadlocals]]log4j2.enableThreadlocals +
+([[log4j2.enable.threadlocals]]log4j2.enable.threadlocals)
+|LOG4J_ENABLE_THREADLOCALS
+|true
+|This system property can be used to
+switch off the use of threadlocals, which will partly disable Log4j's
+garbage-free behaviour: to be fully garbage-free, Log4j stores objects
+in ThreadLocal fields to reuse them, otherwise new objects are created
+for each log event. Note that this property is not effective when Log4j
+detects it is running in a web application.
+
+|[[enableDirectEncoders]]log4j2.enableDirectEncoders +
+([[log4j2.enable.direct.encoders]]log4j2.enable.direct.encoders)
+|LOG4J_ENABLE_DIRECT_ENCODERS
+|true
+|This property can be used to force
+garbage-aware Layouts and Appenders to revert to the pre-2.6 behaviour
+where converting log events to text generates temporary objects like
+Strings and char[] arrays, and converting this text to bytes generates
+temporary byte[] arrays. By default, this property is `true` and
+garbage-aware Layouts and Appenders that convert log events to text will
+convert this text to bytes without creating temporary objects.
+
+|[[initialReusableMsgSize]]log4j2.initialReusableMsgSize +
+([[log4j.initialReusableMsgSize]]log4j.initialReusableMsgSize)
+|LOG4J_INITIAL_REUSABLE_MSG_SIZE
+|128
+|In GC-free mode, this property
+determines the initial size of the reusable StringBuilders where the
+message text is formatted and potentially passed to background threads.
+
+|[[maxReusableMsgSize]]log4j2.maxReusableMsgSize +
+([[log4j.maxReusableMsgSize]]log4j.maxReusableMsgSize)
+|LOG4J_MAX_REUSABLE_MSG_SIZE
+|518
+|In GC-free mode, this property
+determines the maximum size of the reusable StringBuilders where the
+message text is formatted and potentially passed to background threads.
+
+|[[layoutStringBuilderMaxSize]]log4j2.layoutStringBuilderMaxSize +
+([[log4j.layoutStringBuilder.maxSize]]log4j.layoutStringBuilder.maxSize)
+|LOG4J_LAYOUT_STRING_BUILDER_MAX_SIZE
+|2048
+|This property determines
+the maximum size of the thread-local reusable StringBuilders used to
+format the log event to text by Layouts that extend
+AbstractStringLayout.
+
+|[[unboxRingbufferSize]]log4j2.unboxRingbufferSize +
+([[log4j.unbox.ringbuffer.size]]log4j.unbox.ringbuffer.size)
+|LOG4J_UNBOX_RINGBUFFER_SIZE
+|32
+|
+The `org.apache.logging.log4j.util.Unbox` utility manages a small
+thread-local ring buffer of StringBuilders. Each time one of the `box()`
+methods is called, the next slot in the ring buffer is used, until the
+ring buffer is full and the first slot is reused. By default the Unbox
+ring buffer has 32 slots, so user code can have up to 32 boxed
+primitives in a single logger call.
+
+If more slots are required, set system property
+`log4j.unbox.ringbuffer.size` to the desired ring buffer size. Note that
+the specified number will be rounded up to the nearest power of 2.
+
+|[[loggerContextStacktraceOnStart]]log4j2.loggerContextStacktraceOnStart +
+([[log4j.LoggerContext.stacktrace.on.start]]log4j.LoggerContext.stacktrace.on.start)
+|LOG4J_LOGGER_CONTEXT_STACKTRACE_ON_START
+|false
+|Prints a stacktrace to
+the link:#StatusMessages[status logger] at DEBUG level when the
+LoggerContext is started. For debug purposes.
+
+|[[formatMsgNoLookups]]log4j2.formatMsgNoLookups +
+([[log4j2.formatMsgNoLookups]]log4j2.formatMsgNoLookups)
+|FORMAT_MESSAGES_PATTERN_DISABLE_LOOKUPS
+|false
+|Disables message
+pattern lookups globally when set to `true`. This is equivalent to
+defining all message patterns using `%m{nolookups}`.
+|===


[2/8] logging-log4j2 git commit: LOG4J2-1802: Convert lookups manual page to asciidoc

Posted by ma...@apache.org.
LOG4J2-1802: Convert lookups manual page 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/1079bef3
Tree: http://git-wip-us.apache.org/repos/asf/logging-log4j2/tree/1079bef3
Diff: http://git-wip-us.apache.org/repos/asf/logging-log4j2/diff/1079bef3

Branch: refs/heads/master
Commit: 1079bef340dc821cd92e9af8e502adf136e06725
Parents: 0a60a4a
Author: Matt Sicker <bo...@gmail.com>
Authored: Sun Apr 8 19:48:51 2018 -0500
Committer: Matt Sicker <bo...@gmail.com>
Committed: Sun Apr 8 20:08:49 2018 -0500

----------------------------------------------------------------------
 src/site/asciidoc/manual/lookups.adoc | 498 ++++++++++++++++++++++++++++
 src/site/xdoc/manual/lookups.xml      | 511 -----------------------------
 2 files changed, 498 insertions(+), 511 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1079bef3/src/site/asciidoc/manual/lookups.adoc
----------------------------------------------------------------------
diff --git a/src/site/asciidoc/manual/lookups.adoc b/src/site/asciidoc/manual/lookups.adoc
new file mode 100644
index 0000000..89317dd
--- /dev/null
+++ b/src/site/asciidoc/manual/lookups.adoc
@@ -0,0 +1,498 @@
+////
+    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
+
+        https://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.
+////
+= Lookups
+Ralph Goers <rg...@apache.org>
+
+Lookups provide a way to add values to the Log4j configuration at
+arbitrary places. They are a particular type of Plugin that implements
+the
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`]
+interface. Information on how to use Lookups in configuration files can
+be found in the link:configuration.html#PropertySubstitution[Property
+Substitution] section of the link:configuration.html[Configuration]
+page.
+
+[#ContextMapLookup]
+== Context Map Lookup
+
+The ContextMapLookup allows applications to store data in the Log4j
+ThreadContext Map and then retrieve the values in the Log4j
+configuration. In the example below, the application would store the
+current user's login id in the ThreadContext Map with the key "loginId".
+During initial configuration processing the first '$' will be removed.
+The PatternLayout supports interpolation with Lookups and will then
+resolve the variable for each event. Note that the pattern
+"%X\{loginId}" would achieve the same result.
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] $${ctx:loginId} %m%n</pattern>
+  </PatternLayout>
+</File>
+----
+
+[#DateLookup]
+== Date Lookup
+
+The DateLookup is somewhat unusual from the other lookups as it doesn't
+use the key to locate an item. Instead, the key can be used to specify a
+date format string that is valid for
+http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html[SimpleDateFormat].
+The current date, or the date associated with the current log event will
+be formatted as specified.
+
+[source,xml]
+----
+<RollingFile name="Rolling-${map:type}" fileName="${filename}" filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}.%i.log.gz">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+  </PatternLayout>
+  <SizeBasedTriggeringPolicy size="500" />
+</RollingFile>
+----
+
+[#EnvironmentLookup]
+== Environment Lookup
+
+The EnvironmentLookup allows systems to configure environment variables,
+either in global files such as /etc/profile or in the startup scripts
+for applications, and then retrieve those variables from within the
+logging configuration. The example below includes the name of the
+currently logged in user in the application log.
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] $${env:USER} %m%n</pattern>
+  </PatternLayout>
+</File>
+----
+
+This lookup also supports default value syntax. In the sample below,
+when the `USER` environment variable is undefined, the default value
+`jdoe` is used:
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] $${env:USER:-jdoe} %m%n</pattern>
+  </PatternLayout>
+</File>
+----
+
+[#JavaLookup]
+== Java Lookup
+
+The JavaLookup allows Java environment information to be retrieved in
+convenient preformatted strings using the `java:` prefix.
+
+[cols="1m,4a"]
+|===
+|Key |Description
+
+|version
+|The short Java version, like:
+
+`Java version 1.7.0_67`
+
+|runtime
+|The Java runtime version, like:
+
+`Java(TM) SE Runtime Environment (build 1.7.0_67-b01) from Oracle Corporation`
+
+|vm
+|The Java VM version, like:
+
+`Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)`
+
+|os
+|The OS version, like:
+
+`Windows 7 6.1 Service Pack 1, architecture: amd64-64`
+
+|locale
+|Hardware information, like:
+
+`default locale: en_US, platform encoding: Cp1252`
+
+|hw
+|Hardware information, like:
+
+`processors: 4, architecture: amd64-64, instruction sets: amd64`
+
+|===
+
+For example:
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout header="${java:runtime} - ${java:vm} - ${java:os}">
+    <Pattern>%d %m%n</Pattern>
+  </PatternLayout>
+</File>
+----
+
+[#JndiLookup]
+== JNDI Lookup
+
+The JndiLookup allows variables to be retrieved via JNDI. By default the
+key will be prefixed with java:comp/env/, however if the key contains a
+":" no prefix will be added.
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n</pattern>
+  </PatternLayout>
+</File>
+----
+
+*Java's JNDI module is not available on Android.*
+
+[#JmxRuntimeInputArgumentsLookup]
+== JVM Input Arguments Lookup (JMX)
+
+Maps JVM input arguments -- but not _main_ arguments -- using JMX to
+acquire the JVM arguments.
+
+Use the prefix `jvmrunargs` to access JVM arguments.
+
+See the Javadocs for
+https://docs.oracle.com/javase/8/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--[java.lang.management.RuntimeMXBean.getInputArguments()].
+
+*Java's JMX module is not available on Android or on Google App Engine.*
+
+[#Log4jConfigLookup]
+== Log4j Configuration Location Lookup
+
+Log4j configuration properties. The expressions
+`${log4j:configLocation}` and `${log4j:configParentLocation}`
+respectively provide the absolute path to the log4j configuration file
+and its parent folder.
+
+The example below uses this lookup to place log files in a directory
+relative to the log4j configuration file.
+
+[source,xml]
+----
+<File name="Application" fileName="${log4j:configParentLocation}/logs/application.log">
+  <PatternLayout>
+    <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+  </PatternLayout>
+</File>
+----
+
+[#AppMainArgsLookup]
+== Main Arguments Lookup (Application)
+
+This lookup requires that you manually provide the main arguments of the
+application to Log4j:
+
+[source,java]
+----
+import org.apache.logging.log4j.core.lookup.MainMapLookup;
+
+public static void main(String args[]) {
+  MainMapLookup.setMainArguments(args);
+  ...
+}
+----
+
+If the main arguments have been set, this lookup allows applications to
+retrieve these main argument values from within the logging
+configuration. The key that follows the `main:` prefix can either be a
+0-based index into the argument list, or a string, where
+`${main:myString}` is substituted with the value that follows `myString`
+in the main argument list.
+
+For example, suppose the static void main String[] arguments are:
+
+....
+--file foo.txt --verbose -x bar
+....
+
+Then the following substitutions are possible:
+
+[cols="m,m"]
+|===
+|Expression |Result
+
+|${main:0}
+|--file
+
+|${main:1}
+|foo.txt
+
+|${main:2}
+|--verbose
+
+|${main:3}
+|-x
+
+|${main:4}
+|bar
+
+|${main:--file}
+|foo.txt
+
+|${main:-x}
+|bar
+
+|${main:bar}
+|null
+|===
+
+Example usage:
+
+[source,xml]
+----
+<File name="Application" fileName="application.log">
+  <PatternLayout header="File: ${main:--file}">
+    <Pattern>%d %m%n</Pattern>
+  </PatternLayout>
+</File>
+----
+
+[#MapLookup]
+== Map Lookup
+
+The MapLookup serves several purposes.
+
+1.  Provide the base for Properties declared in the configuration file.
+2.  Retrieve values from MapMessages in LogEvents.
+3.  Retrieve values set with
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String%5B%5D%29[MapLookup.setMainArguments(String[])]
+
+The first item simply means that the MapLookup is used to substitute
+properties that are defined in the configuration file. These variables
+are specified without a prefix - e.g. `${name}`. The second usage allows
+a value from the current
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html[`MapMessage`],
+if one is part of the current log event, to be substituted. In the
+example below the RoutingAppender will use a different
+RollingFileAppender for each unique value of the key named "type" in the
+MapMessage. Note that when used this way a value for "type" should be
+declared in the properties declaration to provide a default value in
+case the message is not a MapMessage or the MapMessage does not contain
+the key. See the link:configuration.html#PropertySubstitution[Property
+Substitution] section of the link:configuration.html[Configuration]
+page for information on how to set the default values.
+
+[source,xml]
+----
+<Routing name="Routing">
+  <Routes pattern="$${map:type}">
+    <Route>
+      <RollingFile name="Rolling-${map:type}" fileName="${filename}"
+                   filePattern="target/rolling1/test1-${map:type}.%i.log.gz">
+        <PatternLayout>
+          <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+        </PatternLayout>
+        <SizeBasedTriggeringPolicy size="500" />
+      </RollingFile>
+    </Route>
+  </Routes>
+</Routing>
+----
+
+The marker lookup allows you to use markers in interesting
+configurations like a routing appender. Consider the following YAML
+configuration and code that logs to different files based on markers:
+
+[source,yaml]
+----
+Configuration:
+  status: debug
+
+  Appenders:
+    Console:
+    RandomAccessFile:
+      - name: SQL_APPENDER
+        fileName: logs/sql.log
+        PatternLayout:
+          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+      - name: PAYLOAD_APPENDER
+        fileName: logs/payload.log
+        PatternLayout:
+          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+      - name: PERFORMANCE_APPENDER
+        fileName: logs/performance.log
+        PatternLayout:
+          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
+
+    Routing:
+      name: ROUTING_APPENDER
+      Routes:
+        pattern: "$${marker:}"
+        Route:
+        - key: PERFORMANCE
+          ref: PERFORMANCE_APPENDER
+        - key: PAYLOAD
+          ref: PAYLOAD_APPENDER
+        - key: SQL
+          ref: SQL_APPENDER
+
+  Loggers:
+    Root:
+      level: trace
+      AppenderRef:
+        - ref: ROUTING_APPENDER
+----
+
+[source,java]
+----
+public static final Marker SQL = MarkerFactory.getMarker("SQL");
+public static final Marker PAYLOAD = MarkerFactory.getMarker("PAYLOAD");
+public static final Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
+
+final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
+
+logger.info(SQL, "Message in Sql.log");
+logger.info(PAYLOAD, "Message in Payload.log");
+logger.info(PERFORMANCE, "Message in Performance.log");
+----
+
+Note the key part of the configuration is `pattern: "$${marker:}"`. This
+will produce three log files, each with a log event for a specific
+marker. Log4j will route the log event with the `SQL` marker to
+`sql.log`, the log event with the `PAYLOAD` marker to `payload.log`, and
+so on.
+
+You can use the notation `"${marker:name}"` and `"$${marker:name}"` to
+check for the existence of a marker where `name` is the marker name. If
+the marker exists, the expression returns the name, otherwise `null`.
+
+[#StructuredDataLookup]
+== Structured Data Lookup
+
+The StructuredDataLookup is very similar to the MapLookup in that it
+will retrieve values from StructuredDataMessages. In addition to the Map
+values it will also return the name portion of the id (not including the
+enterprise number) and the type field. The main difference between the
+example below and the example for MapMessage is that the "type" is an
+attribute of the
+link:../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html[StructuredDataMessage]
+while "type" would have to be an item in the Map in a MapMessage.
+
+[source,xml]
+----
+<Routing name="Routing">
+  <Routes pattern="$${sd:type}">
+    <Route>
+      <RollingFile name="Rolling-${sd:type}" fileName="${filename}"
+                   filePattern="target/rolling1/test1-${sd:type}.%i.log.gz">
+        <PatternLayout>
+          <pattern>%d %p %c{1.} [%t] %m%n</pattern>
+        </PatternLayout>
+        <SizeBasedTriggeringPolicy size="500" />
+      </RollingFile>
+    </Route>
+  </Routes>
+</Routing>
+----
+
+[#SystemPropertiesLookup]
+== System Properties Lookup
+
+As it is quite common to define values inside and outside the
+application by using System Properties, it is only natural that they
+should be accessible via a Lookup. As system properties are often
+defined outside the application it would be quite common to see
+something like:
+
+[source,xml]
+----
+<Appenders>
+  <File name="ApplicationLog" fileName="${sys:logPath}/app.log"/>
+</Appenders>
+----
+
+This lookup also supports default value syntax. In the sample below,
+when the `logPath` system property is undefined, the default value
+`/var/logs` is used:
+
+[source,xml]
+----
+<Appenders>
+  <File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
+</Appenders>
+----
+
+[#WebLookup]
+== Web Lookup
+
+The WebLookup allows applications to retrieve variables that are
+associated with the ServletContext. In addition to being able to
+retrieve various fields in the ServletContext, WebLookup supports
+looking up values stored as attributes or configured as initialization
+parameters. The following table lists various keys that can be
+retrieved:
+
+[cols="1m,4"]
+|===
+|Key |Description
+
+|attr._name_
+|Returns the ServletContext attribute with the specified name
+
+|contextPath
+|The context path of the web application
+
+|effectiveMajorVersion
+|Gets the major version of the Servlet specification that the application
+represented by this ServletContext is based on.
+
+|effectiveMinorVersion
+|Gets the minor version of the Servlet specification that the application
+represented by this ServletContext is based on.
+
+|initParam._name_
+|Returns the ServletContext initialization parameter with the specified name
+
+|majorVersion
+|Returns the major version of the Servlet API that this servlet container supports.
+
+|minorVersion
+|Returns the minor version of the Servlet API that this servlet container supports.
+
+|rootDir
+|Returns the result of calling getRealPath with a value of "/".
+
+|serverInfo
+|Returns the name and version of the servlet container on which the servlet is running.
+
+|servletContextName
+|Returns the name of the web application as defined in the display-name element of the deployment descriptor
+|===
+
+Any other key names specified will first be checked to see if a
+ServletContext attribute exists with that name and then will be checked
+to see if an initialization parameter of that name exists. If the key is
+located then the corresponding value will be returned.
+
+[source,xml]
+----
+<Appenders>
+  <File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
+</Appenders>
+----

http://git-wip-us.apache.org/repos/asf/logging-log4j2/blob/1079bef3/src/site/xdoc/manual/lookups.xml
----------------------------------------------------------------------
diff --git a/src/site/xdoc/manual/lookups.xml b/src/site/xdoc/manual/lookups.xml
deleted file mode 100644
index 255054a..0000000
--- a/src/site/xdoc/manual/lookups.xml
+++ /dev/null
@@ -1,511 +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 Lookups</title>
-        <author email="rgoers@apache.org">Ralph Goers</author>
-    </properties>
-
-    <body>
-      <section name="Lookups">
-        <p>
-          Lookups provide a way to add values to the Log4j configuration at arbitrary places. They are
-          a particular type of Plugin that implements the
-          <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a> interface.
-          Information on how to use Lookups in configuration files can be found in the
-          <a href="./configuration.html#PropertySubstitution">Property Substitution</a> section of the
-          <a href="./configuration.html">Configuration</a> page.
-        </p>
-        <a name="ContextMapLookup"/>
-        <subsection name="Context Map Lookup">
-          <p>
-            The ContextMapLookup allows applications to store data in the Log4j ThreadContext Map and
-            then retrieve the values in the Log4j configuration. In the example below, the application
-            would store the current user's login id in the ThreadContext Map with the key "loginId". During
-            initial configuration processing the first '$' will be removed. The PatternLayout supports
-            interpolation with Lookups and will then resolve the variable for each event.  Note that
-            the pattern "%X{loginId}" would achieve the same result.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] $${ctx:loginId} %m%n</pattern>
-  </PatternLayout>
-</File>]]></pre>
-        </subsection>
-        <a name="DateLookup"/>
-        <subsection name="Date Lookup">
-          <p>
-            The DateLookup is somewhat unusual from the other lookups as it doesn't use the key to locate an item.
-            Instead, the key can be used to specify a date format string that is valid for
-            <a href="http://docs.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>.
-            The current date, or the date associated with the current log event will be formatted as specified.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<RollingFile name="Rolling-${map:type}" fileName="${filename}" filePattern="target/rolling1/test1-$${date:MM-dd-yyyy}.%i.log.gz">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-  </PatternLayout>
-  <SizeBasedTriggeringPolicy size="500" />
-</RollingFile>]]></pre>
-        </subsection>
-        <a name="EnvironmentLookup"/>
-        <subsection name="Environment Lookup">
-          <p>
-            The EnvironmentLookup allows systems to configure environment variables, either in global files
-            such as /etc/profile or in the startup scripts for applications, and then retrieve those variables
-            from within the logging configuration. The example below includes the name of the currently logged
-            in user in the application log.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] $${env:USER} %m%n</pattern>
-  </PatternLayout>
-</File>]]></pre>
-          <p>
-            This lookup also supports default value syntax. In the sample below, when the <code>USER</code> environment
-            variable is undefined, the default value <code>jdoe</code> is used:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] $${env:USER:-jdoe} %m%n</pattern>
-  </PatternLayout>
-</File>]]></pre>           
-        </subsection>
-        <a name="JavaLookup"/>
-        <subsection name="Java Lookup">
-          <p>
-            The JavaLookup allows Java environment information to be retrieved in convenient preformatted strings
-            using the <code>java:</code> prefix.
-          </p>
-          <table>
-            <tr>
-              <th>Key</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>version</td>
-              <td>
-                <p>The short Java version, like:</p>
-                <p><code>Java version 1.7.0_67</code></p>
-              </td>
-            </tr>
-            <tr>
-              <td>runtime</td>
-              <td>
-                <p>The Java runtime version, like:</p>
-                <p><code>Java(TM) SE Runtime Environment (build 1.7.0_67-b01) from Oracle Corporation</code></p>
-              </td>
-            </tr>
-            <tr>
-              <td>vm</td>
-              <td>
-                <p>The Java VM version, like:</p>
-                <p><code>Java HotSpot(TM) 64-Bit Server VM (build 24.65-b04, mixed mode)</code></p>
-              </td>
-            </tr>
-            <tr>
-              <td>os</td>
-              <td>
-                <p>The OS version, like:</p>
-                <p><code>Windows 7 6.1 Service Pack 1, architecture: amd64-64</code></p>
-              </td>
-            </tr>
-            <tr>
-              <td>locale</td>
-              <td>
-                <p>Hardware information, like:</p>
-                <p><code>default locale: en_US, platform encoding: Cp1252</code></p>
-              </td>
-            </tr>
-            <tr>
-              <td>hw</td>
-              <td>
-                <p>Hardware information, like:</p>
-                <p><code>processors: 4, architecture: amd64-64, instruction sets: amd64</code></p>
-              </td>
-            </tr>
-          </table>
-          <p>
-            For example:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout header="${java:runtime} - ${java:vm} - ${java:os}">
-    <Pattern>%d %m%n</Pattern>
-  </PatternLayout>
-</File>]]></pre>
-        </subsection>
-        <a name="JndiLookup"/>
-        <subsection name="Jndi Lookup">
-          <p>
-            The JndiLookup allows variables to be retrieved via JNDI. By default the key will be prefixed with
-            java:comp/env/, however if the key contains a ":" no prefix will be added.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] $${jndi:logging/context-name} %m%n</pattern>
-  </PatternLayout>
-</File>]]></pre>
-        <p><strong>Java's JNDI module is not available on Android.</strong></p>
-        </subsection>
-        <a name="JmxRuntimeInputArgumentsLookup"/>
-        <subsection name="JVM Input Arguments Lookup (JMX)">
-          <p>
-            Maps JVM input arguments -- but not <em>main</em> arguments -- using JMX to acquire the JVM arguments.
-          </p>
-          <p>
-            Use the prefix <code>jvmrunargs</code> to access JVM arguments.
-          </p>
-          <p>
-            See the Javadocs for
-            <a href="http://docs.oracle.com/javase/8/docs/api/java/lang/management/RuntimeMXBean.html#getInputArguments--">
-            java.lang.management.RuntimeMXBean.getInputArguments()
-            </a>.
-          </p>
-          <p><strong>Java's JMX module is not available on Android or on Google App Engine.</strong></p>
-        </subsection>
-        <a name="Log4jConfigLookup"/>
-        <subsection name="Log4j Configuration Location Lookup">
-          <p>
-            Log4j configuration properties. The expressions
-            <code>${log4j:configLocation}</code> and <code>${log4j:configParentLocation}</code>
-            respectively provide the absolute path to the log4j configuration file
-            and its parent folder.
-          </p><p>
-            The example below uses this lookup to place log files in a directory relative
-            to the log4j configuration file.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="${log4j:configParentLocation}/logs/application.log">
-  <PatternLayout>
-    <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-  </PatternLayout>
-</File>]]></pre>
-        </subsection>
-        <a name="AppMainArgsLookup"/>
-        <subsection name="Main Arguments Lookup (Application)">
-          <p>
-             This lookup requires that you manually provide
-             the main arguments of the application to Log4j:
-          </p>
-<pre class="prettyprint linenums"><![CDATA[
-import org.apache.logging.log4j.core.lookup.MainMapLookup;
-
-public static void main(String args[]) {
-  MainMapLookup.setMainArguments(args);
-  ...
-}]]></pre>
-        <p>
-          If the main arguments have been set, this lookup allows applications to retrieve
-          these main argument values from within the logging configuration.
-          The key that follows the <code>main:</code> prefix can either be a 0-based index into the argument list,
-          or a string, where <code>${main:myString}</code> is substituted with the value that follows
-          <code>myString</code> in the main argument list.
-        </p>
-        <p>
-          For example, suppose the static void main String[] arguments are:
-        </p>
-        <pre>--file foo.txt --verbose -x bar</pre>
-        <p>
-          Then the following substitutions are possible:
-        </p>
-        <table style="width: 40%">
-          <tr>
-            <th>Expression</th>
-            <th>Result</th>
-          </tr>
-          <tr>
-            <td>${main:0}</td>
-            <td>
-              <p><code>--file</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:1}</td>
-            <td>
-              <p><code>foo.txt</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:2}</td>
-            <td>
-              <p><code>--verbose</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:3}</td>
-            <td>
-              <p><code>-x</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:4}</td>
-            <td>
-              <p><code>bar</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:--file}</td>
-            <td>
-              <p><code>foo.txt</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:-x}</td>
-            <td>
-              <p><code>bar</code></p>
-            </td>
-          </tr>
-          <tr>
-            <td>${main:bar}</td>
-            <td>
-              <p><code>null</code></p>
-            </td>
-          </tr>
-        </table>
-          <p>
-            Example usage:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<File name="Application" fileName="application.log">
-  <PatternLayout header="File: ${main:--file}">
-    <Pattern>%d %m%n</Pattern>
-  </PatternLayout>
-</File>]]></pre>
-        </subsection>
-        <a name="MapLookup"/>
-        <subsection name="Map Lookup">
-          <p>
-            The MapLookup serves several purposes.
-          </p>
-            <ol>
-              <li>Provide the base for Properties declared in the configuration file.</li>
-              <li>Retrieve values from MapMessages in LogEvents.</li>
-              <li>Retrieve values set with <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/MapLookup.html#setMainArguments%28java.lang.String[]%29">MapLookup.setMainArguments(String[])</a></li>
-            </ol>
-          <p>
-            The first item simply means that the MapLookup is used to substitute properties that are defined
-            in the configuration file. These variables are specified without a prefix - e.g. <code>${name}</code>.
-            The second usage allows a value from the current
-            <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html">MapMessage</a>,
-            if one is part of the current log event, to be substituted. In the example below the RoutingAppender will
-            use a different RollingFileAppender for each unique value of the key named "type" in the MapMessage. Note
-            that when used this way a  value for "type" should be declared in the properties declaration to provide
-            a default value in case the message is not a MapMessage or the MapMessage does not contain the key. See the
-            <a href="./configuration.html#PropertySubstitution">Property Substitution</a> section of the
-            <a href="./configuration.html">Configuration</a> page for information on how to set the default values.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<Routing name="Routing">
-  <Routes pattern="$${map:type}">
-    <Route>
-      <RollingFile name="Rolling-${map:type}" fileName="${filename}"
-                   filePattern="target/rolling1/test1-${map:type}.%i.log.gz">
-        <PatternLayout>
-          <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-        </PatternLayout>
-        <SizeBasedTriggeringPolicy size="500" />
-      </RollingFile>
-    </Route>
-  </Routes>
-</Routing>]]></pre>
-        </subsection>
-        <subsection name="Marker Lookup">
-          <p>
-            The marker lookup allows you to use markers in interesting configurations like a routing appender.
-            Consider the following YAML configuration and code that logs to different files based on markers:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-Configuration:
-  status: debug
-
-  Appenders:
-    Console:
-    RandomAccessFile:
-      - name: SQL_APPENDER
-        fileName: logs/sql.log
-        PatternLayout:
-          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
-      - name: PAYLOAD_APPENDER
-        fileName: logs/payload.log
-        PatternLayout:
-          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
-      - name: PERFORMANCE_APPENDER
-        fileName: logs/performance.log
-        PatternLayout:
-          Pattern: "%d{ISO8601_BASIC} %-5level %logger{1} %X %msg%n"
-
-    Routing:
-      name: ROUTING_APPENDER
-      Routes:
-        pattern: "$${marker:}"
-        Route:
-        - key: PERFORMANCE
-          ref: PERFORMANCE_APPENDER
-        - key: PAYLOAD
-          ref: PAYLOAD_APPENDER
-        - key: SQL
-          ref: SQL_APPENDER
-
-  Loggers:
-    Root:
-      level: trace
-      AppenderRef:
-        - ref: ROUTING_APPENDER]]></pre>
-          <pre class="prettyprint linenums"><![CDATA[
-public static final Marker SQL = MarkerFactory.getMarker("SQL");
-public static final Marker PAYLOAD = MarkerFactory.getMarker("PAYLOAD");
-public static final Marker PERFORMANCE = MarkerFactory.getMarker("PERFORMANCE");
-
-final Logger logger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
-
-logger.info(SQL, "Message in Sql.log");
-logger.info(PAYLOAD, "Message in Payload.log");
-logger.info(PERFORMANCE, "Message in Performance.log");]]></pre>
-          <p>
-            Note the key part of the configuration is <code>pattern: "$${marker:}"</code>. This will produce three log files,
-            each with a log event for a specific marker. Log4j will route the log event with the <code>SQL</code> marker to
-            <code>sql.log</code>, the log event with the <code>PAYLOAD</code> marker to <code>payload.log</code>, and so on.
-          </p>
-          <p>
-            You can use the notation <code>"${marker:name}"</code> and <code>"$${marker:name}"</code> to check for the
-            existence of a marker where <code>name</code> is the marker name. If the marker exists, the expression returns
-            the name, otherwise <code>null</code>.
-          </p>
-        </subsection>
-        <a name="StructuredDataLookup"/>
-        <subsection name="Structured Data Lookup">
-          <p>
-            The StructuredDataLookup is very similar to the MapLookup in that it will retrieve values from
-            StructuredDataMessages. In addition to the Map values it will also return the name portion of the
-            id (not including the enterprise number) and the type field. The main difference between the
-            example below and the example for MapMessage is that the "type" is an attribute of the
-            <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html">StructuredDataMessage</a>
-            while "type" would have to be an item in the Map in a MapMessage.
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<Routing name="Routing">
-  <Routes pattern="$${sd:type}">
-    <Route>
-      <RollingFile name="Rolling-${sd:type}" fileName="${filename}"
-                   filePattern="target/rolling1/test1-${sd:type}.%i.log.gz">
-        <PatternLayout>
-          <pattern>%d %p %c{1.} [%t] %m%n</pattern>
-        </PatternLayout>
-        <SizeBasedTriggeringPolicy size="500" />
-      </RollingFile>
-    </Route>
-  </Routes>
-</Routing>]]></pre>
-        </subsection>
-        <a name="SystemPropertiesLookup"/>
-        <subsection name="System Properties Lookup">
-          <p>
-            As it is quite common to define values inside and outside the application by using System Properties,
-            it is only natural that they should be accessible via a Lookup. As system properties are often
-            defined outside the application it would be quite common to see something like:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<Appenders>
-  <File name="ApplicationLog" fileName="${sys:logPath}/app.log"/>
-</Appenders>]]></pre>
-          <p>
-            This lookup also supports default value syntax. In the sample below, when the <code>logPath</code> system
-            property is undefined, the default value <code>/var/logs</code> is used:
-          </p>
-          <pre class="prettyprint linenums"><![CDATA[
-<Appenders>
-  <File name="ApplicationLog" fileName="${sys:logPath:-/var/logs}/app.log"/>
-</Appenders>]]></pre>            
-        </subsection>
-        <a name="WebLookup"/>
-        <subsection name="Web Lookup">
-          <p>
-            The WebLookup allows applications to retrieve variables that are associated with the ServletContext.
-            In addition to being able to retrieve various fields in the ServletContext, WebLookup supports looking
-            up values stored as attributes or configured as initialization parameters. The following table lists
-            various keys that can be retrieved:
-          </p>
-          <table>
-            <tr>
-              <th>Key</th>
-              <th>Description</th>
-            </tr>
-            <tr>
-              <td>attr.<i>name</i></td>
-              <td>Returns the ServletContext attribute with the specified name</td>
-            </tr>
-            <tr>
-              <td>contextPath</td>
-              <td>The context path of the web application</td>
-            </tr>
-            <tr>
-              <td>effectiveMajorVersion</td>
-              <td>Gets the major version of the Servlet specification that the application represented by this
-                ServletContext is based on.</td>
-            </tr>
-            <tr>
-              <td>effectiveMinorVersion</td>
-              <td>Gets the minor version of the Servlet specification that the application represented by this
-                ServletContext is based on.</td>
-            </tr>
-            <tr>
-              <td>initParam.<i>name</i></td>
-              <td>Returns the ServletContext initialization parameter with the specified name</td>
-            </tr>
-            <tr>
-              <td>majorVersion</td>
-              <td>Returns the major version of the Servlet API that this servlet container supports.</td>
-            </tr>
-            <tr>
-              <td>minorVersion</td>
-              <td>Returns the minor version of the Servlet API that this servlet container supports.</td>
-            </tr>
-            <tr>
-              <td>rootDir</td>
-              <td>Returns the result of calling getRealPath with a value of "/".</td>
-            </tr>
-            <tr>
-              <td>serverInfo</td>
-              <td>Returns the name and version of the servlet container on which the servlet is running.</td>
-            </tr>
-            <tr>
-              <td>servletContextName</td>
-              <td>Returns the name of the web application as defined in the display-name element of the
-                deployment descriptor</td>
-            </tr>
-          </table>
-          <p>Any other key names specified will first be checked to see if a ServletContext attribute exists with
-            that name and then will be checked to see if an initialization parameter of that name exists. If the
-            key is located then the corresponding value will be returned.</p>
-          <pre class="prettyprint linenums"><![CDATA[
-<Appenders>
-  <File name="ApplicationLog" fileName="${web:rootDir}/app.log"/>
-</Appenders>]]></pre>
-        </subsection>
-
-      </section>
-    </body>
-</document>