"Fossies" - the Fresh Open Source Software Archive

Member "apache-log4j-2.12.4-src/src/site/xdoc/manual/async.xml" (20 Dec 2021, 47766 Bytes) of package /linux/misc/apache-log4j-2.12.4-src.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) XML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the last Fossies "Diffs" side-by-side code changes report for "async.xml": 2.18.0_vs_2.19.0.

    1 <?xml version="1.0"?>
    2 <!-- Licensed to the Apache Software Foundation (ASF) under one or more contributor
    3   license agreements. See the NOTICE file distributed with this work for additional
    4   information regarding copyright ownership. The ASF licenses this file to
    5   You under the Apache License, Version 2.0 (the "License"); you may not use
    6   this file except in compliance with the License. You may obtain a copy of
    7   the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required
    8   by applicable law or agreed to in writing, software distributed under the
    9   License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS
   10   OF ANY KIND, either express or implied. See the License for the specific
   11   language governing permissions and limitations under the License. -->
   12 <document xmlns="http://maven.apache.org/XDOC/2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   13   xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
   14   <properties>
   15     <title>Log4j 2 Lock-free Asynchronous Loggers for Low-Latency Logging</title>
   16     <author email="rpopma@apache.org">Remko Popma</author>
   17   </properties>
   18   <body>
   19     <section name="Asynchronous Loggers for Low-Latency Logging">
   20       <p>
   21         Asynchronous logging can improve your application's performance by executing the I/O operations
   22         in a separate thread. Log4j 2 makes a number of improvements in this area.
   23       </p>
   24       <ul>
   25         <li>
   26           <b>Asynchronous Loggers</b> are a new addition in Log4j 2.
   27           Their aim is to return from the call to Logger.log to the application as
   28           soon as possible. You can choose between making all Loggers asynchronous
   29           or using a mixture of synchronous and asynchronous Loggers. Making all
   30           Loggers asynchronous will give the best performance, while mixing
   31           gives you more flexibility.
   32         </li>
   33         <li>
   34           <b>LMAX Disruptor technology</b>. Asynchronous Loggers internally use the
   35           <a href="#UnderTheHood">Disruptor</a>, a lock-free inter-thread
   36           communication library, instead of queues, resulting in higher throughput and lower latency.
   37         </li>
   38         <li>
   39           As part of the work for Async Loggers, <b>Asynchronous Appenders</b> have
   40           been enhanced to flush to disk at the end of a batch (when the queue is empty).
   41           This produces the same result as configuring "immediateFlush=true", that is, all
   42           received log events are always available on disk, but is more efficient because it does not need to
   43           touch the disk on each and every log event. (Async Appenders use ArrayBlockingQueue internally and
   44           do not need the disruptor jar on the classpath.)
   45         </li>
   46       </ul>
   47       <a name="Trade-offs" />
   48       <subsection name="Trade-offs">
   49         <p>
   50           Although asynchronous logging can give significant performance benefits,
   51           there are situations where you may want to choose synchronous logging.
   52           This section describes some of the trade-offs of asynchronous logging.
   53         </p>
   54         <p>
   55           <b>Benefits</b>
   56         </p>
   57         <ul>
   58           <li>
   59             <p>Higher peak <a href="#Performance">throughput</a>. With an asynchronous logger
   60             your application can log messages at 6 - 68 times the rate of a synchronous logger.</p>
   61             <p>This is especially interesting for applications that occasionally need to log
   62               bursts of messages. Async logging can help prevent or dampen latency spikes by shortening
   63               the wait time until the next message can be logged. If the queue size is configured
   64               large enough to handle the burst, asynchronous logging will help prevent your
   65               application from falling behind (as much) during a sudden increase of activity.
   66             </p>
   67           </li>
   68           <li>
   69             Lower logging response time <a href="#Latency">latency</a>.
   70             Response time latency is the time it takes for a call to Logger.log to return under a given workload.
   71             Asynchronous Loggers have consistently lower latency than synchronous loggers or even
   72             queue-based asynchronous appenders.
   73           </li>
   74         </ul>
   75         <b>Drawbacks</b>
   76         <ul>
   77           <li>
   78             Error handling. If a problem happens during the logging process and an exception is thrown,
   79             it is less easy for an asynchronous logger or appender to signal this problem to the
   80             application. This can partly be alleviated by configuring an <tt>ExceptionHandler</tt>,
   81             but this may still not cover all cases. For this reason, if logging is part of your business logic,
   82             for example if you are using Log4j as an audit logging framework, we would
   83             recommend to synchronously log those audit messages.
   84             (Note that you can still <a href="#MixedSync-Async">combine</a> them
   85             and use asynchronous logging for debug/trace logging in addition to synchronous
   86             logging for the audit trail.)
   87           </li>
   88           <li>
   89             In some rare cases, care must be taken with mutable messages.
   90             Most of the time you don't need to worry about this. Log4 will ensure that log messages like
   91             <code>logger.debug("My object is {}", myObject)</code> will use the state of the
   92             <code>myObject</code> parameter at the time of the call to <code>logger.debug()</code>.
   93             The log message will not change even if <code>myObject</code> is modified later.
   94             It is safe to asynchronously log mutable objects because most
   95             <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/message/Message.html">Message</a>
   96             implementations built-in to Log4j take a snapshot of the parameters.
   97             There are some exceptions however:
   98             <a class="javadoc"
   99               href="../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html">MapMessage</a>
  100             and
  101             <a class="javadoc"
  102               href="../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html">StructuredDataMessage</a>
  103             are mutable by design: fields can be added to these messages after the message object was created.
  104             These messages should not be modified after they are logged with asynchronous loggers or
  105             asynchronous appenders; you may or may not see the modifications in the resulting log output.
  106             Similarly, custom
  107             <a class="javadoc"
  108               href="../log4j-api/apidocs/org/apache/logging/log4j/message/Message.html">Message</a>
  109             implementations should be designed with asynchronous use in mind, and either take a snapshot
  110             of their parameters at construction time, or document their thread-safety characteristics.
  111           </li>
  112           <li>If your application is running in an environment where CPU resources are scarce, like a machine
  113             with one CPU with a single core, starting another thread is not likely
  114             to give better performance.</li>
  115           <li>
  116             If the <em>sustained rate</em> at which your application is logging messages is faster than the
  117             maximum sustained throughput of the underlying appender, the queue will fill up and the
  118             application will end up logging at the speed of the slowest appender.
  119             If this happens, consider selecting a <a href="../performance.html#whichAppender">faster
  120             appender</a>, or logging less.
  121             If neither of these is an option, you may get better throughput and fewer latency spikes by
  122             logging synchronously.
  123           </li>
  124         </ul>
  125       </subsection>
  126       <a name="AllAsync" />
  127       <subsection name="Making All Loggers Asynchronous">
  128         <p>
  129           <i>Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath.
  130           Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.
  131           </i>
  132         </p>
  133         <p>
  134           This is simplest to configure and gives the best performance. To make all loggers asynchronous,
  135           add the disruptor jar to the classpath and set the system property <tt>log4j2.contextSelector</tt>
  136           to <tt>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</tt>.
  137         </p>
  138         <p>
  139           By default, <a href="#Location">location</a> is not passed to the I/O thread by
  140           asynchronous loggers. If one of your layouts or custom filters needs location information, you need to set
  141           "includeLocation=true" in the configuration of all relevant loggers, including the root logger.
  142         </p>
  143         <p>
  144           A configuration that does not require location might look like:
  145         </p>
  146         <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
  147 
  148 <!-- Don't forget to set system property
  149 -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
  150      to make all loggers asynchronous. -->
  151 
  152 <Configuration status="WARN">
  153   <Appenders>
  154     <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
  155     <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
  156       <PatternLayout>
  157         <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
  158       </PatternLayout>
  159     </RandomAccessFile>
  160   </Appenders>
  161   <Loggers>
  162     <Root level="info" includeLocation="false">
  163       <AppenderRef ref="RandomAccessFile"/>
  164     </Root>
  165   </Loggers>
  166 </Configuration>]]></pre>
  167         <p>
  168           When <tt>AsyncLoggerContextSelector</tt> is used to make all loggers asynchronous, make sure to use normal
  169           <tt>&lt;root&gt;</tt> and <tt>&lt;logger&gt;</tt> elements in the configuration. The
  170           AsyncLoggerContextSelector will ensure that all loggers are asynchronous, using a mechanism
  171           that is different from what happens when you configure <tt>&lt;asyncRoot&gt;</tt>
  172           or <tt>&lt;asyncLogger&gt;</tt>.
  173           The latter elements are intended for mixing async with sync loggers. If you use both mechanisms
  174           together you will end up with two background threads, where your application passes the log
  175           message to thread A, which passes the message to thread B, which then finally
  176           logs the message to disk. This works, but there will be an unnecessary step in the middle.
  177         </p>
  178         <p>
  179           There are a few system properties you can use to control aspects of the asynchronous logging subsystem.
  180           Some of these can be used to tune logging performance.
  181         </p>
  182         <p>
  183           The below properties can also be specified by creating a file named
  184           <tt>log4j2.component.properties</tt> and including this file in the classpath of the application.
  185         </p>
  186         <p>
  187           Note that system properties were renamed into a more consistent style in Log4j 2.10.0. All old property
  188           names are still supported which are documented <a href="configuration.html#SystemProperties">here</a>.
  189         </p>
  190         <a name="SysPropsAllAsync" />
  191         <table>
  192           <caption align="top">System Properties to configure all asynchronous loggers
  193           </caption>
  194           <tr>
  195             <th>System Property</th>
  196             <th>Default Value</th>
  197             <th>Description</th>
  198           </tr>
  199           <tr>
  200             <td>log4j2.asyncLoggerExceptionHandler</td>
  201             <td>
  202               <tt>default handler</tt>
  203             </td>
  204             <td>
  205               Fully qualified name of a class that implements the <tt>com.lmax.disruptor.ExceptionHandler</tt>
  206               interface. The class needs to have a public zero-argument constructor.
  207               If specified, this class will be notified when an exception occurs while logging the messages.
  208               <p>
  209                 If not specified, the default exception handler will print a message and stack trace to the standard
  210                 error output stream.
  211               </p>
  212             </td>
  213           </tr>
  214           <tr>
  215             <td>log4j2.asyncLoggerRingBufferSize</td>
  216             <td>256&#160;*&#160;1024</td>
  217             <td>
  218               Size (number of slots) in the RingBuffer used by the asynchronous logging subsystem.
  219               Make this value large enough to deal with bursts of activity. The minimum size is 128.
  220               The RingBuffer will be pre-allocated at first use and will never grow or shrink
  221               during the life of the system.
  222               <p>
  223                 When the application is logging faster than the underlying appender can keep up with
  224                 for a long enough time to fill up the queue, the behavious is determined by the
  225                 <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html">AsyncQueueFullPolicy</a>.
  226               </p>
  227             </td>
  228           </tr>
  229           <tr>
  230             <td>log4j2.asyncLoggerWaitStrategy</td>
  231             <td>
  232               <tt>Timeout</tt>
  233             </td>
  234             <td>
  235               Valid values: Block, Timeout, Sleep, Yield.
  236               <br />
  237               <tt>Block</tt> is a strategy that uses a lock and condition variable for the I/O thread waiting for log events.
  238               Block can be used when throughput and low-latency are not as important as CPU resource.
  239               Recommended for resource constrained/virtualised environments.
  240               <br />
  241               <tt>Timeout</tt> is a variation of the <tt>Block</tt> strategy that will periodically
  242               wake up from the lock condition await() call. This ensures that if a notification is missed somehow
  243               the consumer thread is not stuck but will recover with a small latency delay (default 10ms).
  244               <br />
  245               <tt>Sleep</tt> is a strategy that initially spins, then uses a Thread.yield(), and
  246               eventually parks for the minimum number of nanos the OS and JVM will allow
  247               while the I/O thread is waiting for log events. Sleep is a good compromise between performance
  248               and CPU resource.
  249               This strategy has very low impact on the application thread, in exchange for some additional
  250               latency for actually getting the message logged.
  251               <br />
  252               <tt>Yield</tt> is a strategy that uses a Thread.yield() for waiting for log events after an initially spinning.
  253               Yield is a good compromise between performance and CPU resource, but may use more CPU than Sleep
  254               in order to get the message logged to disk sooner.
  255             </td>
  256           </tr>
  257           <tr>
  258             <td>AsyncLogger.SynchronizeEnqueueWhenQueueFull</td>
  259             <td>
  260               <tt>true</tt>
  261             </td>
  262             <td>
  263               Synchronizes access to the Disruptor ring buffer for blocking enqueue operations when the queue is full.
  264               Users encountered excessive CPU utilization with Disruptor v3.4.2 when the application
  265               was logging more than the underlying appender could keep up with and the ring buffer became full,
  266               especially when the number of application threads vastly outnumbered the number of cores.
  267               CPU utilization is significantly reduced by restricting access to the enqueue operation. Setting this value
  268               to <tt>false</tt> may lead to very high CPU utilization when the async logging queue is full.
  269             </td>
  270           </tr>
  271           <tr>
  272             <td>log4j2.asyncLoggerThreadNameStrategy</td>
  273             <td>
  274               <tt>CACHED</tt>
  275             </td>
  276             <td>
  277               Valid values: CACHED, UNCACHED.
  278               <br />
  279               By default, AsyncLogger caches the thread name in a ThreadLocal variable to improve performance.
  280               Specify the <tt>UNCACHED</tt> option if your application modifies the thread name at runtime (with
  281               <tt>Thread.currentThread().setName()</tt>)
  282               and you want to see the new thread name reflected in the log.
  283             </td>
  284           </tr>
  285           <tr>
  286             <td>log4j2.clock</td>
  287             <td>
  288               <tt>SystemClock</tt>
  289             </td>
  290             <td>
  291               <p>
  292                 Implementation of the <tt>org.apache.logging.log4j.core.util.Clock</tt>
  293                 interface that is used for timestamping the log events when all loggers are asynchronous.
  294                 <br />
  295                 By default, <tt>System.currentTimeMillis</tt> is called on every log event.
  296               </p>
  297               <p>
  298                 <tt>CachedClock</tt> is an optimization intended for low-latency applications where
  299                 time stamps are generated from a clock that updates its internal time in a background thread once
  300                 every millisecond, or every 1024 log events, whichever comes first.
  301                 This reduces logging latency a little, at the cost of some precision in the logged time stamps.
  302                 Unless you are logging many events, you may see "jumps" of 10-16 milliseconds between log time stamps.
  303                 WEB APPLICATION WARNING: The use of a background thread may cause issues
  304                 for web applications and OSGi applications so CachedClock is not recommended for this kind
  305                 of applications.
  306               </p>
  307               <p>
  308                 You can also specify the fully qualified class name of a custom class that implements the
  309                 <tt>Clock</tt> interface.
  310               </p>
  311             </td>
  312           </tr>
  313         </table>
  314         <p>
  315           There are also a few system properties that can be used to maintain application throughput even when
  316           the underlying appender cannot keep up with the logging rate and the queue is filling up.
  317           See the details for system properties
  318           <a href="configuration.html#asyncQueueFullPolicy"><tt>log4j2.asyncQueueFullPolicy</tt> and
  319             <tt>log4j2.discardThreshold</tt></a>.
  320         </p>
  321       </subsection>
  322       <a name="MixedSync-Async" />
  323       <subsection name="Mixing Synchronous and Asynchronous Loggers">
  324         <p>
  325           <i>Log4j-2.9 and higher require disruptor-3.3.4.jar or higher on the classpath.
  326             Prior to Log4j-2.9, disruptor-3.0.0.jar or higher was required.
  327           There is no need to set system property "Log4jContextSelector" to any value.</i></p>
  328         <p>
  329           Synchronous and asynchronous loggers can be combined in configuration.
  330           This gives you more flexibility at the cost of a slight loss in performance (compared to making
  331           all loggers asynchronous). Use the <tt>&lt;asyncRoot&gt;</tt> or <tt>&lt;asyncLogger&gt;</tt>
  332           configuration elements to specify the loggers that need to be asynchronous.
  333           A configuration can contain only one root logger (either a <tt>&lt;root&gt;</tt>
  334           or an <tt>&lt;asyncRoot&gt;</tt> element), but otherwise async and non-async loggers may be
  335           combined.
  336           For example, a configuration file containing <tt>&lt;asyncLogger&gt;</tt> elements
  337           can also contain <tt>&lt;root&gt;</tt> and
  338           <tt>&lt;logger&gt;</tt> elements for the synchronous loggers.
  339         </p>
  340         <p>
  341           By default, <a href="#Location">location</a> is not passed to the I/O thread by asynchronous loggers.
  342           If one of your layouts or custom filters needs location information, you need to set
  343           "includeLocation=true" in the configuration of all relevant loggers, including the root logger.
  344         </p>
  345         <p>
  346           A configuration that mixes asynchronous loggers might look like:
  347         </p>
  348         <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
  349 
  350 <!-- No need to set system property "log4j2.contextSelector" to any value
  351      when using <asyncLogger> or <asyncRoot>. -->
  352 
  353 <Configuration status="WARN">
  354   <Appenders>
  355     <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
  356     <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
  357               immediateFlush="false" append="false">
  358       <PatternLayout>
  359         <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
  360       </PatternLayout>
  361     </RandomAccessFile>
  362   </Appenders>
  363   <Loggers>
  364     <!-- pattern layout actually uses location, so we need to include it -->
  365     <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
  366       <AppenderRef ref="RandomAccessFile"/>
  367     </AsyncLogger>
  368     <Root level="info" includeLocation="true">
  369       <AppenderRef ref="RandomAccessFile"/>
  370     </Root>
  371   </Loggers>
  372 </Configuration>]]></pre>
  373         <p>
  374           There are a few system properties you can use to control aspects of the asynchronous logging subsystem.
  375           Some of these can be used to tune logging performance.
  376         </p>
  377         <p>
  378           The below properties can also be specified by creating a file named
  379           <tt>log4j2.component.properties</tt> and including this file in the classpath of the application.
  380         </p>
  381         <p>
  382           Note that system properties were renamed into a more consistent style in Log4j 2.10. All old property
  383           names are still supported which are documented <a href="configuration.html#SystemProperties">here</a>.
  384         </p>
  385         <a name="SysPropsMixedSync-Async" />
  386         <table>
  387           <caption align="top">System Properties to configure mixed asynchronous and normal loggers</caption>
  388           <tr>
  389             <th>System Property</th>
  390             <th>Default Value</th>
  391             <th>Description</th>
  392           </tr>
  393           <tr>
  394             <td>log4j2.asyncLoggerConfigExceptionHandler</td>
  395             <td>
  396               <tt>default handler</tt>
  397             </td>
  398             <td>
  399               Fully qualified name of a class that implements the <tt>com.lmax.disruptor.ExceptionHandler</tt>
  400               interface. The class needs to have a public zero-argument constructor.
  401               If specified, this class will be notified when an exception occurs while logging the messages.
  402               <p>
  403                 If not specified, the default exception handler will print a message and stack trace to the standard
  404                 error output stream.
  405               </p>
  406             </td>
  407           </tr>
  408           <tr>
  409             <td>log4j2.asyncLoggerConfigRingBufferSize</td>
  410             <td>256&#160;*&#160;1024</td>
  411             <td>
  412               Size (number of slots) in the RingBuffer used by the asynchronous logging subsystem.
  413               Make this value large enough to deal with bursts of activity. The minimum size is 128.
  414               The RingBuffer will be pre-allocated at first use and will never grow
  415               or shrink during the life of the system.
  416               <p>
  417                 When the application is logging faster than the underlying appender can keep up with
  418                 for a long enough time to fill up the queue, the behavious is determined by the
  419                 <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncQueueFullPolicy.html">AsyncQueueFullPolicy</a>.
  420               </p>
  421             </td>
  422           </tr>
  423           <tr>
  424             <td>log4j2.asyncLoggerConfigWaitStrategy</td>
  425             <td>
  426               <tt>Timeout</tt>
  427             </td>
  428             <td>
  429               Valid values: Block, Timeout, Sleep, Yield.
  430               <br />
  431               <tt>Block</tt> is a strategy that uses a lock and condition variable for the I/O thread waiting for log events.
  432               Block can be used when throughput and low-latency are not as important as CPU resource.
  433               Recommended for resource constrained/virtualised environments.
  434               <br />
  435               <tt>Timeout</tt> is a variation of the <tt>Block</tt> strategy that will periodically
  436               wake up from the lock condition await() call. This ensures that if a notification is missed somehow
  437               the consumer thread is not stuck but will recover with a small latency delay (default 10ms).
  438               <br />
  439               <tt>Sleep</tt> is a strategy that initially spins, then uses a Thread.yield(), and
  440               eventually parks for the minimum number of nanos the OS and JVM will allow
  441               while the I/O thread is waiting for log events. Sleep is a good compromise between performance
  442               and CPU resource.
  443               This strategy has very low impact on the application thread, in exchange for some additional
  444               latency for actually getting the message logged.
  445               <br />
  446               <tt>Yield</tt> is a strategy that uses a Thread.yield() for waiting for log events after an initially spinning.
  447               Yield is a good compromise between performance and CPU resource, but may use more CPU than Sleep
  448               in order to get the message logged to disk sooner.
  449             </td>
  450           </tr>
  451           <tr>
  452             <td>AsyncLoggerConfig.SynchronizeEnqueueWhenQueueFull</td>
  453             <td>
  454               <tt>true</tt>
  455             </td>
  456             <td>
  457               Synchronizes access to the Disruptor ring buffer for blocking enqueue operations when the queue is full.
  458               Users encountered excessive CPU utilization with Disruptor v3.4.2 when the application
  459               was logging more than the underlying appender could keep up with and the ring buffer became full,
  460               especially when the number of application threads vastly outnumbered the number of cores.
  461               CPU utilization is significantly reduced by restricting access to the enqueue operation. Setting this value
  462               to <tt>false</tt> may lead to very high CPU utilization when the async logging queue is full.
  463             </td>
  464           </tr>
  465         </table>
  466         <p>
  467           There are also a few system properties that can be used to maintain application throughput even when
  468           the underlying appender cannot keep up with the logging rate and the queue is filling up.
  469           See the details for system properties
  470           <a href="configuration.html#asyncQueueFullPolicy"><tt>log4j2.asyncQueueFullPolicy</tt> and
  471             <tt>log4j2.discardThreshold</tt></a>.
  472         </p>
  473       </subsection>
  474       <a name="Location" />
  475       <subsection name="Location, location, location...">
  476         <p>
  477           If one of the layouts is configured with a location-related attribute like HTML
  478           <a href="layouts.html#HtmlLocationInfo">locationInfo</a>,
  479           or one of the patterns <a href="layouts.html#PatternClass">%C or $class</a>,
  480           <a href="layouts.html#PatternFile">%F or %file</a>,
  481           <a href="layouts.html#PatternLocation">%l or %location</a>,
  482           <a href="layouts.html#PatternLine">%L or %line</a>,
  483           <a href="layouts.html#PatternMethod">%M or %method</a>,
  484           Log4j will take a snapshot of the stack, and walk the stack trace to find the location information.
  485         </p>
  486         <p>
  487           This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. Synchronous loggers wait as
  488           long as possible before they take this stack snapshot. If no location is required, the snapshot will never be taken.
  489         </p>
  490         <p>
  491           However, asynchronous loggers need to make this decision before passing the
  492           log message to another thread; the location information will be lost after that point.
  493           The <a href="../performance.html#asyncLoggingWithLocation">performance impact</a> of taking a stack trace snapshot is even higher for asynchronous loggers:
  494           logging with location is 30-100 times slower than without location.
  495           For this reason, asynchronous loggers and asynchronous appenders do not include location information by default.
  496         </p>
  497         <p>
  498           You can override the default behaviour in your logger or asynchronous appender configuration
  499           by specifying <tt>includeLocation="true"</tt>.
  500         </p>
  501         <p>
  502         </p>
  503       </subsection>
  504       <a name="Performance" />
  505       <subsection name="Asynchronous Logging Performance">
  506         <p>
  507           The throughput performance results below were derived from running the PerfTest, MTPerfTest and PerfTestDriver
  508           classes which can be found in the Log4j 2 unit test source directory.
  509           For throughput tests, the methodology used was:
  510         </p>
  511         <ul>
  512           <li>First, warm up the JVM by logging 200,000 log messages of 500 characters.
  513           </li>
  514           <li>Repeat the warm-up 10 times, then wait 10 seconds for the I/O thread to catch up and buffers to drain.</li>
  515           <li>Measure how long it takes to execute 256 * 1024 / threadCount calls to Logger.log
  516             and express the result in messages per second.
  517           </li>
  518           <li>Repeat the test 5 times and average the results.</li>
  519         </ul>
  520         <p>The results below were obtained with log4j-2.0-beta5, disruptor-3.0.0.beta3,
  521           log4j-1.2.17 and logback-1.0.10.
  522         </p>
  523         <h4>Logging Peak Throughput</h4>
  524         <p>
  525           The graph below compares the throughput of synchronous loggers, asynchronous appenders and asynchronous
  526           loggers. This is the total throughput of all threads together. In the test with 64 threads,
  527           asynchronous loggers are 12 times faster than asynchronous appenders, and 68 times faster than
  528           synchronous loggers.
  529         </p>
  530         <p>
  531           Asynchronous loggers' throughput increases with the number of threads,
  532           whereas both synchronous loggers and asynchronous appenders
  533           have more or less constant throughput regardless of the number of
  534           threads that are doing the logging.
  535         </p>
  536         <p>
  537           <img src="../images/async-vs-sync-throughput.png"
  538             alt="Async loggers have much higher throughput than sync loggers." />
  539         </p>
  540 
  541         <h4>Asynchronous Throughput Comparison with Other Logging Packages</h4>
  542         <p>
  543           We also compared peak throughput of asynchronous loggers to the synchronous loggers and asynchronous
  544           appenders available in other logging packages, specifically log4j-1.2.17 and
  545           logback-1.0.10, with similar results. For asynchronous appenders, total logging throughput of all
  546           threads together remains roughly constant when adding more threads.
  547           Asynchronous loggers make more effective use of the multiple cores
  548           available on the machine in multi-threaded scenarios.
  549         </p>
  550         <p>
  551           <img src="../images/async-throughput-comparison.png" alt="Async loggers have the highest throughput." />
  552         </p>
  553         <p>On Solaris 10 (64bit) with JDK1.7.0_06, 4-core Xeon X5570 dual CPU
  554           @2.93Ghz with hyperthreading switched on (16 virtual cores):
  555         </p>
  556         <table>
  557           <caption align="top">Throughput per thread in
  558             messages/second</caption>
  559           <tr>
  560             <th>Logger</th>
  561             <th>1 thread</th>
  562             <th>2 threads</th>
  563             <th>4 threads</th>
  564             <th>8 threads</th>
  565             <th>16 threads</th>
  566             <th>32 threads</th>
  567             <th>64 threads</th>
  568           </tr>
  569           <tr>
  570             <td>Log4j 2: Loggers all asynchronous</td>
  571             <td align="right">2,652,412</td>
  572             <td align="right">909,119</td>
  573             <td align="right">776,993</td>
  574             <td align="right">516,365</td>
  575             <td align="right">239,246</td>
  576             <td align="right">253,791</td>
  577             <td align="right">288,997</td>
  578           </tr>
  579           <tr>
  580             <td>Log4j 2: Loggers mixed sync/async</td>
  581             <td align="right">2,454,358</td>
  582             <td align="right">839,394</td>
  583             <td align="right">854,578</td>
  584             <td align="right">597,913</td>
  585             <td align="right">261,003</td>
  586             <td align="right">216,863</td>
  587             <td align="right">218,937</td>
  588           </tr>
  589           <tr>
  590             <td>Log4j 2: Async Appender</td>
  591             <td align="right">1,713,429</td>
  592             <td align="right">603,019</td>
  593             <td align="right">331,506</td>
  594             <td align="right">149,408</td>
  595             <td align="right">86,107</td>
  596             <td align="right">45,529</td>
  597             <td align="right">23,980</td>
  598           </tr>
  599           <tr>
  600             <td>Log4j1: Async Appender</td>
  601             <td align="right">2,239,664</td>
  602             <td align="right">494,470</td>
  603             <td align="right">221,402</td>
  604             <td align="right">109,314</td>
  605             <td align="right">60,580</td>
  606             <td align="right">31,706</td>
  607             <td align="right">14,072</td>
  608           </tr>
  609           <tr>
  610             <td>Logback: Async Appender</td>
  611             <td align="right">2,206,907</td>
  612             <td align="right">624,082</td>
  613             <td align="right">307,500</td>
  614             <td align="right">160,096</td>
  615             <td align="right">85,701</td>
  616             <td align="right">43,422</td>
  617             <td align="right">21,303</td>
  618           </tr>
  619           <tr>
  620             <td>Log4j 2: Synchronous</td>
  621             <td align="right">273,536</td>
  622             <td align="right">136,523</td>
  623             <td align="right">67,609</td>
  624             <td align="right">34,404</td>
  625             <td align="right">15,373</td>
  626             <td align="right">7,903</td>
  627             <td align="right">4,253</td>
  628           </tr>
  629           <tr>
  630             <td>Log4j1: Synchronous</td>
  631             <td align="right">326,894</td>
  632             <td align="right">105,591</td>
  633             <td align="right">57,036</td>
  634             <td align="right">30,511</td>
  635             <td align="right">13,900</td>
  636             <td align="right">7,094</td>
  637             <td align="right">3,509</td>
  638           </tr>
  639           <tr>
  640             <td>Logback: Synchronous</td>
  641             <td align="right">178,063</td>
  642             <td align="right">65,000</td>
  643             <td align="right">34,372</td>
  644             <td align="right">16,903</td>
  645             <td align="right">8,334</td>
  646             <td align="right">3,985</td>
  647             <td align="right">1,967</td>
  648           </tr>
  649         </table>
  650         <p />
  651         <p>On Windows 7 (64bit) with JDK1.7.0_11, 2-core Intel i5-3317u CPU
  652           @1.70Ghz with hyperthreading switched on (4 virtual cores):
  653         </p>
  654         <table>
  655           <caption align="top">Throughput per thread in
  656             messages/second</caption>
  657           <tr>
  658             <th>Logger</th>
  659             <th>1 thread</th>
  660             <th>2 threads</th>
  661             <th>4 threads</th>
  662             <th>8 threads</th>
  663             <th>16 threads</th>
  664             <th>32 threads</th>
  665           </tr>
  666           <tr>
  667             <td>Log4j 2: Loggers all asynchronous</td>
  668             <td align="right">1,715,344</td>
  669             <td align="right">928,951</td>
  670             <td align="right">1,045,265</td>
  671             <td align="right">1,509,109</td>
  672             <td align="right">1,708,989</td>
  673             <td align="right">773,565</td>
  674           </tr>
  675           <tr>
  676             <td>Log4j 2: Loggers mixed sync/async</td>
  677             <td align="right">571,099</td>
  678             <td align="right">1,204,774</td>
  679             <td align="right">1,632,204</td>
  680             <td align="right">1,368,041</td>
  681             <td align="right">462,093</td>
  682             <td align="right">908,529</td>
  683           </tr>
  684           <tr>
  685             <td>Log4j 2: Async Appender</td>
  686             <td align="right">1,236,548</td>
  687             <td align="right">1,006,287</td>
  688             <td align="right">511,571</td>
  689             <td align="right">302,230</td>
  690             <td align="right">160,094</td>
  691             <td align="right">60,152</td>
  692           </tr>
  693           <tr>
  694             <td>Log4j1: Async Appender</td>
  695             <td align="right">1,373,195</td>
  696             <td align="right">911,657</td>
  697             <td align="right">636,899</td>
  698             <td align="right">406,405</td>
  699             <td align="right">202,777</td>
  700             <td align="right">162,964</td>
  701           </tr>
  702           <tr>
  703             <td>Logback: Async Appender</td>
  704             <td align="right">1,979,515</td>
  705             <td align="right">783,722</td>
  706             <td align="right">582,935</td>
  707             <td align="right">289,905</td>
  708             <td align="right">172,463</td>
  709             <td align="right">133,435</td>
  710           </tr>
  711           <tr>
  712             <td>Log4j 2: Synchronous</td>
  713             <td align="right">281,250</td>
  714             <td align="right">225,731</td>
  715             <td align="right">129,015</td>
  716             <td align="right">66,590</td>
  717             <td align="right">34,401</td>
  718             <td align="right">17,347</td>
  719           </tr>
  720           <tr>
  721             <td>Log4j1: Synchronous</td>
  722             <td align="right">147,824</td>
  723             <td align="right">72,383</td>
  724             <td align="right">32,865</td>
  725             <td align="right">18,025</td>
  726             <td align="right">8,937</td>
  727             <td align="right">4,440</td>
  728           </tr>
  729           <tr>
  730             <td>Logback: Synchronous</td>
  731             <td align="right">149,811</td>
  732             <td align="right">66,301</td>
  733             <td align="right">32,341</td>
  734             <td align="right">16,962</td>
  735             <td align="right">8,431</td>
  736             <td align="right">3,610</td>
  737           </tr>
  738         </table>
  739 
  740         <a name="Latency" />
  741         <h4>Response Time Latency</h4>
  742         <table>
  743           <tr><td>This section has been rewritten with the Log4j 2.6 release.
  744             The previous version only reported <em>service time</em> instead of <em>response time</em>.
  745             See the <a href="../performance.html#responseTime">response time</a> side bar on the
  746             performance page on why this is too optimistic.
  747             Furthermore the previous version reported average latency, which does not make sense since
  748             latency is not a normal distribution.
  749             Finally, the previous version of this section only reported the maximum latency of up to 99.99%
  750             of the measurements, which does not tell you how bad the worst 0.01% were.
  751             This is unfortunate because often the "outliers" are all that matter when it comes to response time.
  752             From this release we will try to do better and report response time latency
  753             across the full range of percentages, including all the outliers.
  754             Our thanks to Gil Tene for his
  755             <a href="http://www.infoq.com/presentations/latency-response-time">How NOT to measure latency</a>
  756             presentation. (Now we know why this is also known as the "Oh s#@t!" presentation.)
  757           </td></tr>
  758         </table>
  759         <p><a href="../performance.html#responseTime">Response time</a> is how long it takes to log a message under a certain load.
  760           What is often reported as latency is actually <em>service time</em>: how long it took to perform the operation.
  761           This hides the fact that a single spike in service time adds queueing delay for many of the subsequent operations.
  762           Service time is easy to measure (and often looks good on paper) but is irrelevant for users since it
  763           omits the time spent waiting for service.
  764           For this reason we report response time: service time plus wait time.
  765         </p>
  766         <p>The response time test results below were all derived from running the ResponseTimeTest class
  767           which can be found in the Log4j 2 unit test source directory. If you want to run these tests yourself,
  768           here are the command line options we used:
  769         </p>
  770         <ul>
  771           <li>-Xms1G -Xmx1G (prevent heap resizing during the test)</li>
  772           <!--
  773           <li>-XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=500000 (by default Hotspot schedules a
  774             safepoint pause every second. Reduce jitter by postponing this for the duration of the test.)</li>
  775             -->
  776           <li>-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
  777             -DAsyncLogger.WaitStrategy=busyspin (to use Async Loggers. The BusySpin wait strategy reduces some jitter.)</li>
  778           <li><b>classic mode: </b>-Dlog4j2.enable.threadlocals=false -Dlog4j2.enable.direct.encoders=false<br />
  779             <b>garbage-free mode: </b>-Dlog4j2.enable.threadlocals=true -Dlog4j2.enable.direct.encoders=true</li>
  780           <li>-XX:CompileCommand=dontinline,org.apache.logging.log4j.core.async.perftest.NoOpIdleStrategy::idle</li>
  781           <li>-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -XX:+PrintTenuringDistribution
  782             -XX:+PrintGCApplicationConcurrentTime -XX:+PrintGCApplicationStoppedTime (to eyeball GC and safepoint pauses)</li>
  783         </ul>
  784         <p>
  785           The graph below compares response time latency of the
  786           ArrayBlockingQueue-based asynchronous appenders in Logback 1.1.7, Log4j 1.2.17 to the
  787           various options for asynchronous logging that Log4j 2.6 offers.
  788           Under a workload of 128,000 messages per second, using 16 threads (each logging at a rate of 8,000 messages
  789           per second), we see that Logback 1.1.7, Log4j 1.2.17 experience latency spikes that are orders
  790           of magnitude larger than Log4j 2.
  791         </p>
  792         <p>
  793           <img src="../images/ResponseTimeAsyncLogging16Threads@8kEach.png"
  794                alt="When 16 threads generate a total workload of 128,000 msg/sec, Logback 1.1.7 and
  795                Log4j 1.2.17 experience latency spikes that are orders of magnitude larger than Log4j 2" />
  796         </p>
  797         <p>
  798           The graph below zooms in on the Log4j 2 results for the same test.
  799           We see that the worst-case response time is highest for the ArrayBlockingQueue-based Async Appender.
  800           <a href="garbagefree.html">Garbage-free</a> async loggers have the best response time behaviour.
  801         </p>
  802         <p>
  803           <img src="../images/ResponseTimeAsyncLogging16Threads@8kEachLog4j2Only-labeled.png" alt="" />
  804         </p>
  805 
  806       </subsection>
  807       <!-- <a name="PerformanceTuning" /> <subsection name="Async Logger
  808         Performance Tuning"> <p>While the default settings should give good results
  809         out of the box, you may want to change settings to improve your logging throughput
  810         and/or latency. We suggest the following steps for tuning your logging performance:</p>
  811         <ol> <li>Create a base line by running the performance tests in your environment.</li>
  812         <li>Change a parameter (e.g. WaitStrategy or RingBufferSize) and run the
  813         tests again. Check performance results.</li> <li>Repeat (2) until you find
  814         a parameter combination that gives acceptable performance.</li> </ol> <p>Use
  815         the following command to run the performance tests:</p> <blockquote> <tt>java
  816         -cp log4j-async-2.0-tests.jar:log4j-async-2.0.jar:disruptor-3.0.0.jar:log4j-api-2.0.jar:log4j-core-2.0.jar
  817         \<br /> [-DWaitStrategy=Sleep] [-DRingBufferSize=262144] org.apache.logging.log4j.async.perftest.PerfTestDriver
  818         [path-to-java] [repeats]</tt> <br /><br /> [<b>WaitStrategy</b>] is an optional
  819         system property with valid values "Block", "Sleep", or "Yield". Details are
  820         documented under "System Properties to configure ... loggers". <br /> [<b>RingBufferSize</b>]
  821         is an optional system property with an integer value of at least 128. Details
  822         are documented under "System Properties to configure ... loggers". <br />
  823         [<b>path-to-java</b>] is an optional parameter that is the full path to the
  824         "java" executable. Specify this if just running "java" in the current directory
  825         does not specify the version of java that you want to test with. <br /> [<b>repeats</b>]
  826         is an optional parameter that specifies how often each test is repeated.
  827         The default is 5. </blockquote> <p>For reference, below are some of the numbers
  828         we used to determine the default settings. (Solaris 10 (64bit), 2.93GHz Xeon
  829         X5570 with JDK1.7.0_06):</p> <table> <caption align="top">Throughput in log
  830         messages/second per thread</caption> <tr> <th>Logger</th> <th>WaitStrategy</th>
  831         <th>1 thread</th> <th>2 threads</th> <th>4 threads</th> <th>8 threads</th>
  832         </tr> <tr> <td rowspan="3" valign="top">All Async System Clock</td> <td align="center">Block</td>
  833         <td align="right">1,717,261</td> <td align="right">727,075</td> <td align="right">263,760</td>
  834         <td align="right">150,533</td> </tr> <tr> <td align="center">Sleep</td> <td
  835         align="right">1,568,623</td> <td align="right">948,653</td> <td align="right">629,951</td>
  836         <td align="right">651,340</td> </tr> <tr> <td align="center">Yield</td> <td
  837         align="right">1,618,103</td> <td align="right">884,314</td> <td align="right">628,008</td>
  838         <td align="right">675,879</td> </tr> <tr> <td rowspan="3" valign="top">All
  839         Async Cached Clock</td> <td align="center">Block</td> <td align="right">2,771,734</td>
  840         <td align="right">642,899</td> <td align="right">331,003</td> <td align="right">172,877</td>
  841         </tr> <tr> <td align="center">Sleep</td> <td align="right">2,393,901</td>
  842         <td align="right">1,211,425</td> <td align="right">770,416</td> <td align="right">632,361</td>
  843         </tr> <tr> <td align="center">Yield</td> <td align="right">2,331,763</td>
  844         <td align="right">1,132,529</td> <td align="right">684,109</td> <td align="right">671,957</td>
  845         </tr> <tr> <td rowspan="3" valign="top">Mixed Async</td> <td align="center">Block</td>
  846         <td align="right">1,347,853</td> <td align="right">443,652</td> <td align="right">251,433</td>
  847         <td align="right">136,152</td> </tr> <tr> <td align="center">Sleep</td> <td
  848         align="right">1,371,511</td> <td align="right">567,829</td> <td align="right">407,676</td>
  849         <td align="right">408,071</td> </tr> <tr> <td align="center">Yield</td> <td
  850         align="right">1,360,267</td> <td align="right">675,570</td> <td align="right">389,609</td>
  851         <td align="right">391,969</td> </tr> </table> </subsection> -->
  852       <a name="UnderTheHood" />
  853       <subsection name="Under The Hood">
  854         <p>
  855           Asynchronous Loggers are implemented using the
  856           <a href="http://lmax-exchange.github.com/disruptor/">LMAX Disruptor</a>
  857           inter-thread messaging library. From the LMAX web site:
  858         </p>
  859         <blockquote>
  860           <p>... using queues to pass data between stages of the system was introducing latency, so we
  861             focused on optimising this area. The Disruptor is the result of our research and testing.
  862             We found that cache misses at the CPU-level, and locks requiring kernel arbitration are both
  863             extremely costly, so we created a framework which has "mechanical sympathy" for
  864             the hardware it's running on, and that's lock-free.
  865           </p>
  866         </blockquote>
  867 
  868         <p>
  869           LMAX Disruptor internal performance comparisons with <tt>java.util.concurrent.ArrayBlockingQueue</tt>
  870           can be found
  871           <a href="https://github.com/LMAX-Exchange/disruptor/wiki/Performance-Results">here</a>.
  872         </p>
  873       </subsection>
  874     </section>
  875   </body>
  876 </document>