pax_global_header00006660000000000000000000000064125775626240014532gustar00rootroot0000000000000052 comment=383a8194acab4a740d22b69c023ca3af6cb9c664 logging-log4j2-log4j-2.4/000077500000000000000000000000001257756262400151415ustar00rootroot00000000000000logging-log4j2-log4j-2.4/.gitignore000066400000000000000000000000701257756262400171260ustar00rootroot00000000000000/.project /.idea **/*.iml **/target /target/ /.settings logging-log4j2-log4j-2.4/BUILDING.txt000066400000000000000000000017051257756262400171020ustar00rootroot00000000000000Building Log4j 2 To build Log4j 2, you need a JDK implementation version 1.6 or greater, and Apache Maven. Note that building the site requires Maven 3.0.5, while everything else works fine with any version of Maven 3. To perform a RAT check, run: mvn apache-rat:check To perform a Clirr check on the API modules, run: cd log4j-api mvn clirr:check cd log4j-1.2-api mvn clirr:check To build the site, from a command line, run: mvn clean install mvn site On Windows, use a local staging directory, for example: mvn site:stage-deploy -DstagingSiteURL=file:///%HOME%/log4j On UNIX, use a local staging directory, for example: mvn site:stage-deploy -DstagingSiteURL=file:///$HOME/log4j To test, run: mvn test Then, to test OSGi, you must first create the jars: mvn install -DskipTests mvn package -DskipTests Next, you can run the tests as usual, which will pick up the jar files to use as OSGi bundles from the various target directories: mvn test logging-log4j2-log4j-2.4/LICENSE.txt000066400000000000000000000261461257756262400167750ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 1999-2005 The Apache Software Foundation Licensed 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. logging-log4j2-log4j-2.4/NOTICE.txt000066400000000000000000000005431257756262400166650ustar00rootroot00000000000000Apache Log4j Copyright 1999-2014 Apache Software Foundation This product includes software developed at The Apache Software Foundation (http://www.apache.org/). ResolverUtil.java Copyright 2005-2006 Tim Fennell Dumbster SMTP test server Copyright 2004 Jason Paul Kitchen TypeUtil.java Copyright 2002-2012 Ramnivas Laddad, Juergen Hoeller, Chris Beams logging-log4j2-log4j-2.4/RELEASE-NOTES.txt000066400000000000000000000222001257756262400176440ustar00rootroot00000000000000 Apache Log4j 2.4 RELEASE NOTES The Apache Log4j 2 team is pleased to announce the Log4j 2.4 release! Apache log4j is a well known framework for logging application behavior. Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j 1.x, and provides many other modern features such as support for Markers, property substitution using Lookups, and asynchronous Loggers. In addition, Log4j 2 will not lose events while reconfiguring. This is the eighth GA release. It contains several bugfixes and new features. As of this release Log4j now requires a minimum of Java 7. GA Release 2.4 Changes in this version include: New features: o LOG4J2-635: Add support for configuration via Properties. o LOG4J2-952: Add ConfigurationBuilder. o LOG4J2-599: Added support for Java 8 lambda expressions to lazily construct a log message only if the requested log level is enabled. o LOG4J2-1118: Updated Logger wrapper generator tool to add Java 8 lambda support for custom log levels. o LOG4J2-1107: New Appender for Apache Kafka. Thanks to Mikael Ståldal. o LOG4J2-1113: New publisher Appender for ZeroMQ (using JeroMQ). Thanks to Gary Gregory. o LOG4J2-1088: Add Comma Separated Value (CSV) layouts for parameter and event logging. Thanks to Gary Gregory. o LOG4J2-1090: Add Core Configurator APIs to change a logger's level. o LOG4J2-1105: Add API org.apache.logging.log4j.Level.isInRange(Level, Level). Thanks to Gary Gregory. o LOG4J2-1106: Add a LevelRangeFilter class. Thanks to Gary Gregory. o LOG4J2-1076: Added support for system nanosecond time in pattern layout. o LOG4J2-1075: Added support for compressing to bzip2 format on file rollover. o LOG4J2-1077: Support additional Apache Commons Compress compression formats on rollover: Deflate, Pack200, XY. o LOG4J2-767: New module for Liquibase integration. Thanks to Mikael Ståldal. o LOG4J2-1023: New RewritePolicy for changing level of a log event. Thanks to Mikael Ståldal. o LOG4J2-1015: Add a way to route messages based on the %marker in Layout for RoutingAppender. Thanks to Daniel Marcotte. o LOG4J2-1050: Add a Log4jLookup class to help write log files relative to log4j2.xml. Thanks to Adam Retter. o LOG4J2-1057: Add API org.apache.logging.log4j.LogManager.getFormatterLogger(). o LOG4J2-1066: Expose Log4jContextFactory's ShutdownCallbackRegistry. Thanks to Charles Allen. Fixed Bugs: o LOG4J2-1121: Fixed potential race condition on reconfiguration. Introduced ReliabilityStrategy to facilitate switching between different mechanisms for preventing log events from being dropped on reconfiguration. o LOG4J2-1123: Core Configurator.initialize(String, ClassLoader, String) fails to work when config location is a file path. Thanks to Gary Gregory. o LOG4J2-1117: OutputStreamManager in ConsoleAppender leaking managers. Thanks to Marcus Thiesen. o LOG4J2-1044: Write pending events to Flume when the appender is stopped. o LOG4J2-1108: NullPointerException when passing null to java.util.logging.Logger.setLevel(). Thanks to Mikael Ståldal. o LOG4J2-1110: org.apache.logging.log4j.jul.CoreLogger.setLevel() checks for security permission too late. o LOG4J2-1084: Misleading StatusLogger WARN event in LogManager with java.util.Map. Thanks to Philipp Schneider. o LOG4J2-1051: NoClassDefFoundError when starting app on Google App Engine. Thanks to Lukasz Lenart. o LOG4J2-684: ExtendedThrowablePatternConverter does not print suppressed exceptions. Thanks to Joern Huxhorn, Mauro Molinari. o LOG4J2-1069: Improper handling of JSON escape chars when deserializing JSON log events. Thanks to Sam Braam. o LOG4J2-1068: Exceptions not logged when using TcpSocketServer + SerializedLayout. Thanks to Andy McMullan. o LOG4J2-1067: ThrowableProxy getExtendedStackTraceAsString throws NPE on deserialized nested exceptions. Thanks to Sam Braam. o LOG4J2-1049: AsyncAppender now resets the thread interrupted flag after catching InterruptedException. Thanks to Robert Schaft. o LOG4J2-1048: FileConfigurationMonitor unnecessarily calls System.currentTimeMillis() causing high CPU usage. Thanks to Nikhil. o LOG4J2-1037: Backward compatibility issue in log4j-1.2-api NDC pop() and peek(). Thanks to Marc Dergacz. o LOG4J2-1025: Custom java.util.logging.Level gives null Log4j Level and causes NPE. Thanks to Mikael Ståldal. o LOG4J2-1033: SimpleLogger creates unnecessary Map objects by calling ThreadContext.getContext() instead of getImmutableContext(). Thanks to Mikael Ståldal. o LOG4J2-1026: HighlightConverter does not obey noConsoleNoAnsi. o LOG4J2-1019: ZipCompressAction leaves files open until GC when an IO error takes place. o LOG4J2-1020: GzCompressAction leaves files open until GC when an IO error takes place. o LOG4J2-1038: Incorrect documentation for layout default charset. Thanks to Gili. o LOG4J2-1042: Socket and Syslog appenders don't take timeout into account at startup. Thanks to Guillaume Turri. o LOG4J2-934: Circular suppressed Exception throws StackOverflowError. Thanks to Kenneth Gendron. o LOG4J2-1046: Circular Exception cause throws StackOverflowError. Thanks to Kenneth Gendron. o LOG4J2-982: Use System.nanoTime() to measure time intervals. Thanks to Mikhail Mazurskiy. o LOG4J2-1045: Externalize log4j2.xml via URL resource. Thanks to Günter Albrecht. o LOG4J2-1058: Log4jMarker#contains(String) does not respect org.slf4j.Marker contract. Thanks to Daniel Branzea. o LOG4J2-1060: Log4jMarker#contains(Marker) does not respect org.slf4j.Marker contract. o LOG4J2-1061: Log4jMarker#remove(Marker) does not respect org.slf4j.Marker contract. o LOG4J2-1062: Log4jMarker#add(Marker) does not respect org.slf4j.Marker contract. o LOG4J2-1064: org.apache.logging.slf4j.Log4jMarker does not implement org.slf4j.Marker.equals(Object) org.slf4j.Marker.hashCode(). o LOG4J2-889: Header in layout should not be written on application startup if appending to an existing file. Fixes LOG4J2-1030. Thanks to Maciej Karaś, Kenneth Leider. o LOG4J2-918: Clarify documentation for combining async with sync loggers. o LOG4J2-1078: GelfLayout throws exception if some log event fields are null. Thanks to Mikael Ståldal. Changes: o LOG4J2-1017: Update Java platform from Java 6 to 7. From this version onwards, log4j 2 requires Java 7. o LOG4J2-812: PatternLayout timestamp formatting performance improvement: replaced synchronized SimpleDateFormat with Apache Commons FastDateFormat. This and better caching resulted in a ~3-30X faster timestamp formatting. o LOG4J2-1097: PatternLayout timestamp formatting performance improvement: predefined date formats (and variants using a period '.' millisecond separator instead of ',') are now formatted ~2-10X faster than other date formats. o LOG4J2-1096: Improved performance of ParameterizedMessage::getFormattedMessage by ~2X. o LOG4J2-1120: LoggerConfig performance improvements: avoid unnecessary lock acquisition, use more efficient data structure. o LOG4J2-1125: PatternLayout performance improvement by caching and reusing a ThreadLocal StringBuilder. o LOG4J2-1114: Add thread name to status logger layout. o LOG4J2-1010: Pass log event when interpolating logger properties. o LOG4J2-1044: Support batchSize in FlumeAvroManager. o LOG4J2-1065: Define org.apache.logging.log4j.Marker.equals(Object) and org.apache.logging.log4j.Marker.hashCode(). o LOG4J2-1063: Avoid creating temporary array object in org.apache.logging.slf4j.Log4jMarker.iterator(). o LOG4J2-890: log4j-web-2.1 should workaround a bug in JBOSS EAP 6.2. Thanks to Hassan Kalaldeh, Robert Andersson, Remko Popma. o LOG4J2-403: MongoDB appender, username and password should be optional. Thanks to Poorna Subhash P, Jeremy Lautman. o LOG4J2-1035: Log4j2 tries to SystemClassLoader when running on Google AppEngine. o LOG4J2-1022: Allow a list of keys to be specified in the MDC pattern converter. o LOG4J2-959: Fix FindBugs DM_DEFAULT_ENCODING bug in SimpleLogger.logMessage() and simplify code. o LOG4J2-1036: Update Apache Flume from 1.5.2 to 1.6.0. o LOG4J2-1041: Update MongoDB driver from 2.11.2 to 2.13.2. o LOG4J2-1018: Update database tests from H2 1.3.175 to 1.3.176. o LOG4J2-1070: Update Java Mail from 1.5.2 to 1.5.4. o LOG4J2-1079: Update Jackson from 2.5.3 to 2.5.4. o LOG4J2-1879: Update Jackson from 2.5.4 to 2.6.0. o LOG4J2-1092: Update Jackson from 2.6.0 to 2.6.1. o LOG4J2-1104: Update Apache Commons Compress from 1.9 to 1.10. Removed: o Removed experimental interface LevelLogger which got committed to master by mistake. Apache Log4j 2.4 requires a minimum of Java 7 to build and run. Log4j 2.4 and greater requires Java 7, version 2.3 required Java 6. Basic compatibility with Log4j 1.x is provided through the log4j-1.2-api component, however it does not implement some of the very implementation specific classes and methods. The package names and Maven groupId have been changed to org.apache.logging.log4j to avoid any conflicts with log4j 1.x. For complete information on Apache Log4j 2, including instructions on how to submit bug reports, patches, or suggestions for improvement, see the Apache Apache Log4j 2 website: http://logging.apache.org/log4j/2.x/logging-log4j2-log4j-2.4/Vagrantfile000066400000000000000000000056641257756262400173410ustar00rootroot00000000000000# -*- mode: ruby -*- # vi: set ft=ruby : # 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. $script = <} *
  • define style rules. See the example page for examples. *
  • mark the {@code
    } and {@code } tags in your source with
     *    {@code class=prettyprint.}
     *    You can also use the (html deprecated) {@code } tag, but the pretty
     *    printer needs to do more substantial DOM manipulations to support that, so
     *    some css styles may not be preserved.
     * </ol>
     * That's it.  I wanted to keep the API as simple as possible, so there's no
     * need to specify which language the code is in, but if you wish, you can add
     * another class to the {@code <pre>} or {@code <code>} element to specify the
     * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
     * starts with "lang-" followed by a file extension, specifies the file type.
     * See the "lang-*.js" files in this directory for code that implements
     * per-language file handlers.
     * <p>
     * Change log:<br>
     * cbeust, 2006/08/22
     * <blockquote>
     *   Java annotations (start with "@") are now captured as literals ("lit")
     * </blockquote>
     * @requires console
     */
    
    // JSLint declarations
    /*global console, document, navigator, setTimeout, window */
    
    /**
     * Split {@code prettyPrint} into multiple timeouts so as not to interfere with
     * UI events.
     * If set to {@code false}, {@code prettyPrint()} is synchronous.
     */
    window['PR_SHOULD_USE_CONTINUATION'] = true;
    
    (function () {
      // Keyword lists for various languages.
      // We use things that coerce to strings to make them compact when minified
      // and to defeat aggressive optimizers that fold large string constants.
      var FLOW_CONTROL_KEYWORDS = ["break,continue,do,else,for,if,return,while"];
      var C_KEYWORDS = [FLOW_CONTROL_KEYWORDS,"auto,case,char,const,default," + 
          "double,enum,extern,float,goto,int,long,register,short,signed,sizeof," +
          "static,struct,switch,typedef,union,unsigned,void,volatile"];
      var COMMON_KEYWORDS = [C_KEYWORDS,"catch,class,delete,false,import," +
          "new,operator,private,protected,public,this,throw,true,try,typeof"];
      var CPP_KEYWORDS = [COMMON_KEYWORDS,"alignof,align_union,asm,axiom,bool," +
          "concept,concept_map,const_cast,constexpr,decltype," +
          "dynamic_cast,explicit,export,friend,inline,late_check," +
          "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast," +
          "template,typeid,typename,using,virtual,where"];
      var JAVA_KEYWORDS = [COMMON_KEYWORDS,
          "abstract,boolean,byte,extends,final,finally,implements,import," +
          "instanceof,null,native,package,strictfp,super,synchronized,throws," +
          "transient"];
      var CSHARP_KEYWORDS = [JAVA_KEYWORDS,
          "as,base,by,checked,decimal,delegate,descending,dynamic,event," +
          "fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock," +
          "object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed," +
          "stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];
      var COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally," +
          "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then," +
          "true,try,unless,until,when,while,yes";
      var JSCRIPT_KEYWORDS = [COMMON_KEYWORDS,
          "debugger,eval,export,function,get,null,set,undefined,var,with," +
          "Infinity,NaN"];
      var PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for," +
          "goto,if,import,last,local,my,next,no,our,print,package,redo,require," +
          "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
      var PYTHON_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "and,as,assert,class,def,del," +
          "elif,except,exec,finally,from,global,import,in,is,lambda," +
          "nonlocal,not,or,pass,print,raise,try,with,yield," +
          "False,True,None"];
      var RUBY_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "alias,and,begin,case,class," +
          "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo," +
          "rescue,retry,self,super,then,true,undef,unless,until,when,yield," +
          "BEGIN,END"];
      var SH_KEYWORDS = [FLOW_CONTROL_KEYWORDS, "case,done,elif,esac,eval,fi," +
          "function,in,local,set,then,until"];
      var ALL_KEYWORDS = [
          CPP_KEYWORDS, CSHARP_KEYWORDS, JSCRIPT_KEYWORDS, PERL_KEYWORDS +
          PYTHON_KEYWORDS, RUBY_KEYWORDS, SH_KEYWORDS];
      var C_TYPES = /^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;
    
      // token style names.  correspond to css classes
      /**
       * token style for a string literal
       * @const
       */
      var PR_STRING = 'str';
      /**
       * token style for a keyword
       * @const
       */
      var PR_KEYWORD = 'kwd';
      /**
       * token style for a comment
       * @const
       */
      var PR_COMMENT = 'com';
      /**
       * token style for a type
       * @const
       */
      var PR_TYPE = 'typ';
      /**
       * token style for a literal value.  e.g. 1, null, true.
       * @const
       */
      var PR_LITERAL = 'lit';
      /**
       * token style for a punctuation string.
       * @const
       */
      var PR_PUNCTUATION = 'pun';
      /**
       * token style for a punctuation string.
       * @const
       */
      var PR_PLAIN = 'pln';
    
      /**
       * token style for an sgml tag.
       * @const
       */
      var PR_TAG = 'tag';
      /**
       * token style for a markup declaration such as a DOCTYPE.
       * @const
       */
      var PR_DECLARATION = 'dec';
      /**
       * token style for embedded source.
       * @const
       */
      var PR_SOURCE = 'src';
      /**
       * token style for an sgml attribute name.
       * @const
       */
      var PR_ATTRIB_NAME = 'atn';
      /**
       * token style for an sgml attribute value.
       * @const
       */
      var PR_ATTRIB_VALUE = 'atv';
    
      /**
       * A class that indicates a section of markup that is not code, e.g. to allow
       * embedding of line numbers within code listings.
       * @const
       */
      var PR_NOCODE = 'nocode';
    
    
    
    /**
     * A set of tokens that can precede a regular expression literal in
     * javascript
     * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
     * has the full list, but I've removed ones that might be problematic when
     * seen in languages that don't support regular expression literals.
     *
     * <p>Specifically, I've removed any keywords that can't precede a regexp
     * literal in a syntactically legal javascript program, and I've removed the
     * "in" keyword since it's not a keyword in many languages, and might be used
     * as a count of inches.
     *
     * <p>The link a above does not accurately describe EcmaScript rules since
     * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
     * very well in practice.
     *
     * @private
     * @const
     */
    var REGEXP_PRECEDER_PATTERN = '(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*';
    
    // CAVEAT: this does not properly handle the case where a regular
    // expression immediately follows another since a regular expression may
    // have flags for case-sensitivity and the like.  Having regexp tokens
    // adjacent is not valid in any language I'm aware of, so I'm punting.
    // TODO: maybe style special characters inside a regexp as punctuation.
    
    
      /**
       * Given a group of {@link RegExp}s, returns a {@code RegExp} that globally
       * matches the union of the sets of strings matched by the input RegExp.
       * Since it matches globally, if the input strings have a start-of-input
       * anchor (/^.../), it is ignored for the purposes of unioning.
       * @param {Array.<RegExp>} regexs non multiline, non-global regexs.
       * @return {RegExp} a global regex.
       */
      function combinePrefixPatterns(regexs) {
        var capturedGroupIndex = 0;
      
        var needToFoldCase = false;
        var ignoreCase = false;
        for (var i = 0, n = regexs.length; i < n; ++i) {
          var regex = regexs[i];
          if (regex.ignoreCase) {
            ignoreCase = true;
          } else if (/[a-z]/i.test(regex.source.replace(
                         /\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi, ''))) {
            needToFoldCase = true;
            ignoreCase = false;
            break;
          }
        }
      
        var escapeCharToCodeUnit = {
          'b': 8,
          't': 9,
          'n': 0xa,
          'v': 0xb,
          'f': 0xc,
          'r': 0xd
        };
      
        function decodeEscape(charsetPart) {
          var cc0 = charsetPart.charCodeAt(0);
          if (cc0 !== 92 /* \\ */) {
            return cc0;
          }
          var c1 = charsetPart.charAt(1);
          cc0 = escapeCharToCodeUnit[c1];
          if (cc0) {
            return cc0;
          } else if ('0' <= c1 && c1 <= '7') {
            return parseInt(charsetPart.substring(1), 8);
          } else if (c1 === 'u' || c1 === 'x') {
            return parseInt(charsetPart.substring(2), 16);
          } else {
            return charsetPart.charCodeAt(1);
          }
        }
      
        function encodeEscape(charCode) {
          if (charCode < 0x20) {
            return (charCode < 0x10 ? '\\x0' : '\\x') + charCode.toString(16);
          }
          var ch = String.fromCharCode(charCode);
          if (ch === '\\' || ch === '-' || ch === '[' || ch === ']') {
            ch = '\\' + ch;
          }
          return ch;
        }
      
        function caseFoldCharset(charSet) {
          var charsetParts = charSet.substring(1, charSet.length - 1).match(
              new RegExp(
                  '\\\\u[0-9A-Fa-f]{4}'
                  + '|\\\\x[0-9A-Fa-f]{2}'
                  + '|\\\\[0-3][0-7]{0,2}'
                  + '|\\\\[0-7]{1,2}'
                  + '|\\\\[\\s\\S]'
                  + '|-'
                  + '|[^-\\\\]',
                  'g'));
          var groups = [];
          var ranges = [];
          var inverse = charsetParts[0] === '^';
          for (var i = inverse ? 1 : 0, n = charsetParts.length; i < n; ++i) {
            var p = charsetParts[i];
            if (/\\[bdsw]/i.test(p)) {  // Don't muck with named groups.
              groups.push(p);
            } else {
              var start = decodeEscape(p);
              var end;
              if (i + 2 < n && '-' === charsetParts[i + 1]) {
                end = decodeEscape(charsetParts[i + 2]);
                i += 2;
              } else {
                end = start;
              }
              ranges.push([start, end]);
              // If the range might intersect letters, then expand it.
              // This case handling is too simplistic.
              // It does not deal with non-latin case folding.
              // It works for latin source code identifiers though.
              if (!(end < 65 || start > 122)) {
                if (!(end < 65 || start > 90)) {
                  ranges.push([Math.max(65, start) | 32, Math.min(end, 90) | 32]);
                }
                if (!(end < 97 || start > 122)) {
                  ranges.push([Math.max(97, start) & ~32, Math.min(end, 122) & ~32]);
                }
              }
            }
          }
      
          // [[1, 10], [3, 4], [8, 12], [14, 14], [16, 16], [17, 17]]
          // -> [[1, 12], [14, 14], [16, 17]]
          ranges.sort(function (a, b) { return (a[0] - b[0]) || (b[1]  - a[1]); });
          var consolidatedRanges = [];
          var lastRange = [NaN, NaN];
          for (var i = 0; i < ranges.length; ++i) {
            var range = ranges[i];
            if (range[0] <= lastRange[1] + 1) {
              lastRange[1] = Math.max(lastRange[1], range[1]);
            } else {
              consolidatedRanges.push(lastRange = range);
            }
          }
      
          var out = ['['];
          if (inverse) { out.push('^'); }
          out.push.apply(out, groups);
          for (var i = 0; i < consolidatedRanges.length; ++i) {
            var range = consolidatedRanges[i];
            out.push(encodeEscape(range[0]));
            if (range[1] > range[0]) {
              if (range[1] + 1 > range[0]) { out.push('-'); }
              out.push(encodeEscape(range[1]));
            }
          }
          out.push(']');
          return out.join('');
        }
      
        function allowAnywhereFoldCaseAndRenumberGroups(regex) {
          // Split into character sets, escape sequences, punctuation strings
          // like ('(', '(?:', ')', '^'), and runs of characters that do not
          // include any of the above.
          var parts = regex.source.match(
              new RegExp(
                  '(?:'
                  + '\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]'  // a character set
                  + '|\\\\u[A-Fa-f0-9]{4}'  // a unicode escape
                  + '|\\\\x[A-Fa-f0-9]{2}'  // a hex escape
                  + '|\\\\[0-9]+'  // a back-reference or octal escape
                  + '|\\\\[^ux0-9]'  // other escape sequence
                  + '|\\(\\?[:!=]'  // start of a non-capturing group
                  + '|[\\(\\)\\^]'  // start/emd of a group, or line start
                  + '|[^\\x5B\\x5C\\(\\)\\^]+'  // run of other characters
                  + ')',
                  'g'));
          var n = parts.length;
      
          // Maps captured group numbers to the number they will occupy in
          // the output or to -1 if that has not been determined, or to
          // undefined if they need not be capturing in the output.
          var capturedGroups = [];
      
          // Walk over and identify back references to build the capturedGroups
          // mapping.
          for (var i = 0, groupIndex = 0; i < n; ++i) {
            var p = parts[i];
            if (p === '(') {
              // groups are 1-indexed, so max group index is count of '('
              ++groupIndex;
            } else if ('\\' === p.charAt(0)) {
              var decimalValue = +p.substring(1);
              if (decimalValue && decimalValue <= groupIndex) {
                capturedGroups[decimalValue] = -1;
              }
            }
          }
      
          // Renumber groups and reduce capturing groups to non-capturing groups
          // where possible.
          for (var i = 1; i < capturedGroups.length; ++i) {
            if (-1 === capturedGroups[i]) {
              capturedGroups[i] = ++capturedGroupIndex;
            }
          }
          for (var i = 0, groupIndex = 0; i < n; ++i) {
            var p = parts[i];
            if (p === '(') {
              ++groupIndex;
              if (capturedGroups[groupIndex] === undefined) {
                parts[i] = '(?:';
              }
            } else if ('\\' === p.charAt(0)) {
              var decimalValue = +p.substring(1);
              if (decimalValue && decimalValue <= groupIndex) {
                parts[i] = '\\' + capturedGroups[groupIndex];
              }
            }
          }
      
          // Remove any prefix anchors so that the output will match anywhere.
          // ^^ really does mean an anchored match though.
          for (var i = 0, groupIndex = 0; i < n; ++i) {
            if ('^' === parts[i] && '^' !== parts[i + 1]) { parts[i] = ''; }
          }
      
          // Expand letters to groups to handle mixing of case-sensitive and
          // case-insensitive patterns if necessary.
          if (regex.ignoreCase && needToFoldCase) {
            for (var i = 0; i < n; ++i) {
              var p = parts[i];
              var ch0 = p.charAt(0);
              if (p.length >= 2 && ch0 === '[') {
                parts[i] = caseFoldCharset(p);
              } else if (ch0 !== '\\') {
                // TODO: handle letters in numeric escapes.
                parts[i] = p.replace(
                    /[a-zA-Z]/g,
                    function (ch) {
                      var cc = ch.charCodeAt(0);
                      return '[' + String.fromCharCode(cc & ~32, cc | 32) + ']';
                    });
              }
            }
          }
      
          return parts.join('');
        }
      
        var rewritten = [];
        for (var i = 0, n = regexs.length; i < n; ++i) {
          var regex = regexs[i];
          if (regex.global || regex.multiline) { throw new Error('' + regex); }
          rewritten.push(
              '(?:' + allowAnywhereFoldCaseAndRenumberGroups(regex) + ')');
        }
      
        return new RegExp(rewritten.join('|'), ignoreCase ? 'gi' : 'g');
      }
    
    
      /**
       * Split markup into a string of source code and an array mapping ranges in
       * that string to the text nodes in which they appear.
       *
       * <p>
       * The HTML DOM structure:</p>
       * <pre>
       * (Element   "p"
       *   (Element "b"
       *     (Text  "print "))       ; #1
       *   (Text    "'Hello '")      ; #2
       *   (Element "br")            ; #3
       *   (Text    "  + 'World';")) ; #4
       * </pre>
       * <p>
       * corresponds to the HTML
       * {@code <p><b>print </b>'Hello '<br>  + 'World';</p>}.</p>
       *
       * <p>
       * It will produce the output:</p>
       * <pre>
       * {
       *   sourceCode: "print 'Hello '\n  + 'World';",
       *   //                 1         2
       *   //       012345678901234 5678901234567
       *   spans: [0, #1, 6, #2, 14, #3, 15, #4]
       * }
       * </pre>
       * <p>
       * where #1 is a reference to the {@code "print "} text node above, and so
       * on for the other text nodes.
       * </p>
       *
       * <p>
       * The {@code} spans array is an array of pairs.  Even elements are the start
       * indices of substrings, and odd elements are the text nodes (or BR elements)
       * that contain the text for those substrings.
       * Substrings continue until the next index or the end of the source.
       * </p>
       *
       * @param {Node} node an HTML DOM subtree containing source-code.
       * @return {Object} source code and the text nodes in which they occur.
       */
      function extractSourceSpans(node) {
        var nocode = /(?:^|\s)nocode(?:\s|$)/;
      
        var chunks = [];
        var length = 0;
        var spans = [];
        var k = 0;
      
        var whitespace;
        if (node.currentStyle) {
          whitespace = node.currentStyle.whiteSpace;
        } else if (window.getComputedStyle) {
          whitespace = document.defaultView.getComputedStyle(node, null)
              .getPropertyValue('white-space');
        }
        var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
      
        function walk(node) {
          switch (node.nodeType) {
            case 1:  // Element
              if (nocode.test(node.className)) { return; }
              for (var child = node.firstChild; child; child = child.nextSibling) {
                walk(child);
              }
              var nodeName = node.nodeName;
              if ('BR' === nodeName || 'LI' === nodeName) {
                chunks[k] = '\n';
                spans[k << 1] = length++;
                spans[(k++ << 1) | 1] = node;
              }
              break;
            case 3: case 4:  // Text
              var text = node.nodeValue;
              if (text.length) {
                if (!isPreformatted) {
                  text = text.replace(/[ \t\r\n]+/g, ' ');
                } else {
                  text = text.replace(/\r\n?/g, '\n');  // Normalize newlines.
                }
                // TODO: handle tabs here?
                chunks[k] = text;
                spans[k << 1] = length;
                length += text.length;
                spans[(k++ << 1) | 1] = node;
              }
              break;
          }
        }
      
        walk(node);
      
        return {
          sourceCode: chunks.join('').replace(/\n$/, ''),
          spans: spans
        };
      }
    
    
      /**
       * Apply the given language handler to sourceCode and add the resulting
       * decorations to out.
       * @param {number} basePos the index of sourceCode within the chunk of source
       *    whose decorations are already present on out.
       */
      function appendDecorations(basePos, sourceCode, langHandler, out) {
        if (!sourceCode) { return; }
        var job = {
          sourceCode: sourceCode,
          basePos: basePos
        };
        langHandler(job);
        out.push.apply(out, job.decorations);
      }
    
      var notWs = /\S/;
    
      /**
       * Given an element, if it contains only one child element and any text nodes
       * it contains contain only space characters, return the sole child element.
       * Otherwise returns undefined.
       * <p>
       * This is meant to return the CODE element in {@code <pre><code ...>} when
       * there is a single child element that contains all the non-space textual
       * content, but not to return anything where there are multiple child elements
       * as in {@code <pre><code>...</code><code>...</code></pre>} or when there
       * is textual content.
       */
      function childContentWrapper(element) {
        var wrapper = undefined;
        for (var c = element.firstChild; c; c = c.nextSibling) {
          var type = c.nodeType;
          wrapper = (type === 1)  // Element Node
              ? (wrapper ? element : c)
              : (type === 3)  // Text Node
              ? (notWs.test(c.nodeValue) ? element : wrapper)
              : wrapper;
        }
        return wrapper === element ? undefined : wrapper;
      }
    
      /** Given triples of [style, pattern, context] returns a lexing function,
        * The lexing function interprets the patterns to find token boundaries and
        * returns a decoration list of the form
        * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
        * where index_n is an index into the sourceCode, and style_n is a style
        * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
        * all characters in sourceCode[index_n-1:index_n].
        *
        * The stylePatterns is a list whose elements have the form
        * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
        *
        * Style is a style constant like PR_PLAIN, or can be a string of the
        * form 'lang-FOO', where FOO is a language extension describing the
        * language of the portion of the token in $1 after pattern executes.
        * E.g., if style is 'lang-lisp', and group 1 contains the text
        * '(hello (world))', then that portion of the token will be passed to the
        * registered lisp handler for formatting.
        * The text before and after group 1 will be restyled using this decorator
        * so decorators should take care that this doesn't result in infinite
        * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
        * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
        * '<script>foo()<\/script>', which would cause the current decorator to
        * be called with '<script>' which would not match the same rule since
        * group 1 must not be empty, so it would be instead styled as PR_TAG by
        * the generic tag rule.  The handler registered for the 'js' extension would
        * then be called with 'foo()', and finally, the current decorator would
        * be called with '<\/script>' which would not match the original rule and
        * so the generic tag rule would identify it as a tag.
        *
        * Pattern must only match prefixes, and if it matches a prefix, then that
        * match is considered a token with the same style.
        *
        * Context is applied to the last non-whitespace, non-comment token
        * recognized.
        *
        * Shortcut is an optional string of characters, any of which, if the first
        * character, gurantee that this pattern and only this pattern matches.
        *
        * @param {Array} shortcutStylePatterns patterns that always start with
        *   a known character.  Must have a shortcut string.
        * @param {Array} fallthroughStylePatterns patterns that will be tried in
        *   order if the shortcut ones fail.  May have shortcuts.
        *
        * @return {function (Object)} a
        *   function that takes source code and returns a list of decorations.
        */
      function createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns) {
        var shortcuts = {};
        var tokenizer;
        (function () {
          var allPatterns = shortcutStylePatterns.concat(fallthroughStylePatterns);
          var allRegexs = [];
          var regexKeys = {};
          for (var i = 0, n = allPatterns.length; i < n; ++i) {
            var patternParts = allPatterns[i];
            var shortcutChars = patternParts[3];
            if (shortcutChars) {
              for (var c = shortcutChars.length; --c >= 0;) {
                shortcuts[shortcutChars.charAt(c)] = patternParts;
              }
            }
            var regex = patternParts[1];
            var k = '' + regex;
            if (!regexKeys.hasOwnProperty(k)) {
              allRegexs.push(regex);
              regexKeys[k] = null;
            }
          }
          allRegexs.push(/[\0-\uffff]/);
          tokenizer = combinePrefixPatterns(allRegexs);
        })();
    
        var nPatterns = fallthroughStylePatterns.length;
    
        /**
         * Lexes job.sourceCode and produces an output array job.decorations of
         * style classes preceded by the position at which they start in
         * job.sourceCode in order.
         *
         * @param {Object} job an object like <pre>{
         *    sourceCode: {string} sourceText plain text,
         *    basePos: {int} position of job.sourceCode in the larger chunk of
         *        sourceCode.
         * }</pre>
         */
        var decorate = function (job) {
          var sourceCode = job.sourceCode, basePos = job.basePos;
          /** Even entries are positions in source in ascending order.  Odd enties
            * are style markers (e.g., PR_COMMENT) that run from that position until
            * the end.
            * @type {Array.<number|string>}
            */
          var decorations = [basePos, PR_PLAIN];
          var pos = 0;  // index into sourceCode
          var tokens = sourceCode.match(tokenizer) || [];
          var styleCache = {};
    
          for (var ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
            var token = tokens[ti];
            var style = styleCache[token];
            var match = void 0;
    
            var isEmbedded;
            if (typeof style === 'string') {
              isEmbedded = false;
            } else {
              var patternParts = shortcuts[token.charAt(0)];
              if (patternParts) {
                match = token.match(patternParts[1]);
                style = patternParts[0];
              } else {
                for (var i = 0; i < nPatterns; ++i) {
                  patternParts = fallthroughStylePatterns[i];
                  match = token.match(patternParts[1]);
                  if (match) {
                    style = patternParts[0];
                    break;
                  }
                }
    
                if (!match) {  // make sure that we make progress
                  style = PR_PLAIN;
                }
              }
    
              isEmbedded = style.length >= 5 && 'lang-' === style.substring(0, 5);
              if (isEmbedded && !(match && typeof match[1] === 'string')) {
                isEmbedded = false;
                style = PR_SOURCE;
              }
    
              if (!isEmbedded) { styleCache[token] = style; }
            }
    
            var tokenStart = pos;
            pos += token.length;
    
            if (!isEmbedded) {
              decorations.push(basePos + tokenStart, style);
            } else {  // Treat group 1 as an embedded block of source code.
              var embeddedSource = match[1];
              var embeddedSourceStart = token.indexOf(embeddedSource);
              var embeddedSourceEnd = embeddedSourceStart + embeddedSource.length;
              if (match[2]) {
                // If embeddedSource can be blank, then it would match at the
                // beginning which would cause us to infinitely recurse on the
                // entire token, so we catch the right context in match[2].
                embeddedSourceEnd = token.length - match[2].length;
                embeddedSourceStart = embeddedSourceEnd - embeddedSource.length;
              }
              var lang = style.substring(5);
              // Decorate the left of the embedded source
              appendDecorations(
                  basePos + tokenStart,
                  token.substring(0, embeddedSourceStart),
                  decorate, decorations);
              // Decorate the embedded source
              appendDecorations(
                  basePos + tokenStart + embeddedSourceStart,
                  embeddedSource,
                  langHandlerForExtension(lang, embeddedSource),
                  decorations);
              // Decorate the right of the embedded section
              appendDecorations(
                  basePos + tokenStart + embeddedSourceEnd,
                  token.substring(embeddedSourceEnd),
                  decorate, decorations);
            }
          }
          job.decorations = decorations;
        };
        return decorate;
      }
    
      /** returns a function that produces a list of decorations from source text.
        *
        * This code treats ", ', and ` as string delimiters, and \ as a string
        * escape.  It does not recognize perl's qq() style strings.
        * It has no special handling for double delimiter escapes as in basic, or
        * the tripled delimiters used in python, but should work on those regardless
        * although in those cases a single string literal may be broken up into
        * multiple adjacent string literals.
        *
        * It recognizes C, C++, and shell style comments.
        *
        * @param {Object} options a set of optional parameters.
        * @return {function (Object)} a function that examines the source code
        *     in the input job and builds the decoration list.
        */
      function sourceDecorator(options) {
        var shortcutStylePatterns = [], fallthroughStylePatterns = [];
        if (options['tripleQuotedStrings']) {
          // '''multi-line-string''', 'single-line-string', and double-quoted
          shortcutStylePatterns.push(
              [PR_STRING,  /^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,
               null, '\'"']);
        } else if (options['multiLineStrings']) {
          // 'multi-line-string', "multi-line-string"
          shortcutStylePatterns.push(
              [PR_STRING,  /^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,
               null, '\'"`']);
        } else {
          // 'single-line-string', "single-line-string"
          shortcutStylePatterns.push(
              [PR_STRING,
               /^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,
               null, '"\'']);
        }
        if (options['verbatimStrings']) {
          // verbatim-string-literal production from the C# grammar.  See issue 93.
          fallthroughStylePatterns.push(
              [PR_STRING, /^@\"(?:[^\"]|\"\")*(?:\"|$)/, null]);
        }
        var hc = options['hashComments'];
        if (hc) {
          if (options['cStyleComments']) {
            if (hc > 1) {  // multiline hash comments
              shortcutStylePatterns.push(
                  [PR_COMMENT, /^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/, null, '#']);
            } else {
              // Stop C preprocessor declarations at an unclosed open comment
              shortcutStylePatterns.push(
                  [PR_COMMENT, /^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,
                   null, '#']);
            }
            fallthroughStylePatterns.push(
                [PR_STRING,
                 /^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,
                 null]);
          } else {
            shortcutStylePatterns.push([PR_COMMENT, /^#[^\r\n]*/, null, '#']);
          }
        }
        if (options['cStyleComments']) {
          fallthroughStylePatterns.push([PR_COMMENT, /^\/\/[^\r\n]*/, null]);
          fallthroughStylePatterns.push(
              [PR_COMMENT, /^\/\*[\s\S]*?(?:\*\/|$)/, null]);
        }
        if (options['regexLiterals']) {
          /**
           * @const
           */
          var REGEX_LITERAL = (
              // A regular expression literal starts with a slash that is
              // not followed by * or / so that it is not confused with
              // comments.
              '/(?=[^/*])'
              // and then contains any number of raw characters,
              + '(?:[^/\\x5B\\x5C]'
              // escape sequences (\x5C),
              +    '|\\x5C[\\s\\S]'
              // or non-nesting character sets (\x5B\x5D);
              +    '|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+'
              // finally closed by a /.
              + '/');
          fallthroughStylePatterns.push(
              ['lang-regex',
               new RegExp('^' + REGEXP_PRECEDER_PATTERN + '(' + REGEX_LITERAL + ')')
               ]);
        }
    
        var types = options['types'];
        if (types) {
          fallthroughStylePatterns.push([PR_TYPE, types]);
        }
    
        var keywords = ("" + options['keywords']).replace(/^ | $/g, '');
        if (keywords.length) {
          fallthroughStylePatterns.push(
              [PR_KEYWORD,
               new RegExp('^(?:' + keywords.replace(/[\s,]+/g, '|') + ')\\b'),
               null]);
        }
    
        shortcutStylePatterns.push([PR_PLAIN,       /^\s+/, null, ' \r\n\t\xA0']);
        fallthroughStylePatterns.push(
            // TODO(mikesamuel): recognize non-latin letters and numerals in idents
            [PR_LITERAL,     /^@[a-z_$][a-z_$@0-9]*/i, null],
            [PR_TYPE,        /^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/, null],
            [PR_PLAIN,       /^[a-z_$][a-z_$@0-9]*/i, null],
            [PR_LITERAL,
             new RegExp(
                 '^(?:'
                 // A hex number
                 + '0x[a-f0-9]+'
                 // or an octal or decimal number,
                 + '|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)'
                 // possibly in scientific notation
                 + '(?:e[+\\-]?\\d+)?'
                 + ')'
                 // with an optional modifier like UL for unsigned long
                 + '[a-z]*', 'i'),
             null, '0123456789'],
            // Don't treat escaped quotes in bash as starting strings.  See issue 144.
            [PR_PLAIN,       /^\\[\s\S]?/, null],
            [PR_PUNCTUATION, /^.[^\s\w\.$@\'\"\`\/\#\\]*/, null]);
    
        return createSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
      }
    
      var decorateSource = sourceDecorator({
            'keywords': ALL_KEYWORDS,
            'hashComments': true,
            'cStyleComments': true,
            'multiLineStrings': true,
            'regexLiterals': true
          });
    
      /**
       * Given a DOM subtree, wraps it in a list, and puts each line into its own
       * list item.
       *
       * @param {Node} node modified in place.  Its content is pulled into an
       *     HTMLOListElement, and each line is moved into a separate list item.
       *     This requires cloning elements, so the input might not have unique
       *     IDs after numbering.
       */
      function numberLines(node, opt_startLineNum) {
        var nocode = /(?:^|\s)nocode(?:\s|$)/;
        var lineBreak = /\r\n?|\n/;
      
        var document = node.ownerDocument;
      
        var whitespace;
        if (node.currentStyle) {
          whitespace = node.currentStyle.whiteSpace;
        } else if (window.getComputedStyle) {
          whitespace = document.defaultView.getComputedStyle(node, null)
              .getPropertyValue('white-space');
        }
        // If it's preformatted, then we need to split lines on line breaks
        // in addition to <BR>s.
        var isPreformatted = whitespace && 'pre' === whitespace.substring(0, 3);
      
        var li = document.createElement('LI');
        while (node.firstChild) {
          li.appendChild(node.firstChild);
        }
        // An array of lines.  We split below, so this is initialized to one
        // un-split line.
        var listItems = [li];
      
        function walk(node) {
          switch (node.nodeType) {
            case 1:  // Element
              if (nocode.test(node.className)) { break; }
              if ('BR' === node.nodeName) {
                breakAfter(node);
                // Discard the <BR> since it is now flush against a </LI>.
                if (node.parentNode) {
                  node.parentNode.removeChild(node);
                }
              } else {
                for (var child = node.firstChild; child; child = child.nextSibling) {
                  walk(child);
                }
              }
              break;
            case 3: case 4:  // Text
              if (isPreformatted) {
                var text = node.nodeValue;
                var match = text.match(lineBreak);
                if (match) {
                  var firstLine = text.substring(0, match.index);
                  node.nodeValue = firstLine;
                  var tail = text.substring(match.index + match[0].length);
                  if (tail) {
                    var parent = node.parentNode;
                    parent.insertBefore(
                        document.createTextNode(tail), node.nextSibling);
                  }
                  breakAfter(node);
                  if (!firstLine) {
                    // Don't leave blank text nodes in the DOM.
                    node.parentNode.removeChild(node);
                  }
                }
              }
              break;
          }
        }
      
        // Split a line after the given node.
        function breakAfter(lineEndNode) {
          // If there's nothing to the right, then we can skip ending the line
          // here, and move root-wards since splitting just before an end-tag
          // would require us to create a bunch of empty copies.
          while (!lineEndNode.nextSibling) {
            lineEndNode = lineEndNode.parentNode;
            if (!lineEndNode) { return; }
          }
      
          function breakLeftOf(limit, copy) {
            // Clone shallowly if this node needs to be on both sides of the break.
            var rightSide = copy ? limit.cloneNode(false) : limit;
            var parent = limit.parentNode;
            if (parent) {
              // We clone the parent chain.
              // This helps us resurrect important styling elements that cross lines.
              // E.g. in <i>Foo<br>Bar</i>
              // should be rewritten to <li><i>Foo</i></li><li><i>Bar</i></li>.
              var parentClone = breakLeftOf(parent, 1);
              // Move the clone and everything to the right of the original
              // onto the cloned parent.
              var next = limit.nextSibling;
              parentClone.appendChild(rightSide);
              for (var sibling = next; sibling; sibling = next) {
                next = sibling.nextSibling;
                parentClone.appendChild(sibling);
              }
            }
            return rightSide;
          }
      
          var copiedListItem = breakLeftOf(lineEndNode.nextSibling, 0);
      
          // Walk the parent chain until we reach an unattached LI.
          for (var parent;
               // Check nodeType since IE invents document fragments.
               (parent = copiedListItem.parentNode) && parent.nodeType === 1;) {
            copiedListItem = parent;
          }
          // Put it on the list of lines for later processing.
          listItems.push(copiedListItem);
        }
      
        // Split lines while there are lines left to split.
        for (var i = 0;  // Number of lines that have been split so far.
             i < listItems.length;  // length updated by breakAfter calls.
             ++i) {
          walk(listItems[i]);
        }
      
        // Make sure numeric indices show correctly.
        if (opt_startLineNum === (opt_startLineNum|0)) {
          listItems[0].setAttribute('value', opt_startLineNum);
        }
      
        var ol = document.createElement('OL');
        ol.className = 'linenums';
        var offset = Math.max(0, ((opt_startLineNum - 1 /* zero index */)) | 0) || 0;
        for (var i = 0, n = listItems.length; i < n; ++i) {
          li = listItems[i];
          // Stick a class on the LIs so that stylesheets can
          // color odd/even rows, or any other row pattern that
          // is co-prime with 10.
          li.className = 'L' + ((i + offset) % 10);
          if (!li.firstChild) {
            li.appendChild(document.createTextNode('\xA0'));
          }
          ol.appendChild(li);
        }
      
        node.appendChild(ol);
      }
    
      /**
       * Breaks {@code job.sourceCode} around style boundaries in
       * {@code job.decorations} and modifies {@code job.sourceNode} in place.
       * @param {Object} job like <pre>{
       *    sourceCode: {string} source as plain text,
       *    spans: {Array.<number|Node>} alternating span start indices into source
       *       and the text node or element (e.g. {@code <BR>}) corresponding to that
       *       span.
       *    decorations: {Array.<number|string} an array of style classes preceded
       *       by the position at which they start in job.sourceCode in order
       * }</pre>
       * @private
       */
      function recombineTagsAndDecorations(job) {
        var isIE = /\bMSIE\b/.test(navigator.userAgent);
        var newlineRe = /\n/g;
      
        var source = job.sourceCode;
        var sourceLength = source.length;
        // Index into source after the last code-unit recombined.
        var sourceIndex = 0;
      
        var spans = job.spans;
        var nSpans = spans.length;
        // Index into spans after the last span which ends at or before sourceIndex.
        var spanIndex = 0;
      
        var decorations = job.decorations;
        var nDecorations = decorations.length;
        // Index into decorations after the last decoration which ends at or before
        // sourceIndex.
        var decorationIndex = 0;
      
        // Remove all zero-length decorations.
        decorations[nDecorations] = sourceLength;
        var decPos, i;
        for (i = decPos = 0; i < nDecorations;) {
          if (decorations[i] !== decorations[i + 2]) {
            decorations[decPos++] = decorations[i++];
            decorations[decPos++] = decorations[i++];
          } else {
            i += 2;
          }
        }
        nDecorations = decPos;
      
        // Simplify decorations.
        for (i = decPos = 0; i < nDecorations;) {
          var startPos = decorations[i];
          // Conflate all adjacent decorations that use the same style.
          var startDec = decorations[i + 1];
          var end = i + 2;
          while (end + 2 <= nDecorations && decorations[end + 1] === startDec) {
            end += 2;
          }
          decorations[decPos++] = startPos;
          decorations[decPos++] = startDec;
          i = end;
        }
      
        nDecorations = decorations.length = decPos;
      
        var decoration = null;
        while (spanIndex < nSpans) {
          var spanStart = spans[spanIndex];
          var spanEnd = spans[spanIndex + 2] || sourceLength;
      
          var decStart = decorations[decorationIndex];
          var decEnd = decorations[decorationIndex + 2] || sourceLength;
      
          var end = Math.min(spanEnd, decEnd);
      
          var textNode = spans[spanIndex + 1];
          var styledText;
          if (textNode.nodeType !== 1  // Don't muck with <BR>s or <LI>s
              // Don't introduce spans around empty text nodes.
              && (styledText = source.substring(sourceIndex, end))) {
            // This may seem bizarre, and it is.  Emitting LF on IE causes the
            // code to display with spaces instead of line breaks.
            // Emitting Windows standard issue linebreaks (CRLF) causes a blank
            // space to appear at the beginning of every line but the first.
            // Emitting an old Mac OS 9 line separator makes everything spiffy.
            if (isIE) { styledText = styledText.replace(newlineRe, '\r'); }
            textNode.nodeValue = styledText;
            var document = textNode.ownerDocument;
            var span = document.createElement('SPAN');
            span.className = decorations[decorationIndex + 1];
            var parentNode = textNode.parentNode;
            parentNode.replaceChild(span, textNode);
            span.appendChild(textNode);
            if (sourceIndex < spanEnd) {  // Split off a text node.
              spans[spanIndex + 1] = textNode
                  // TODO: Possibly optimize by using '' if there's no flicker.
                  = document.createTextNode(source.substring(end, spanEnd));
              parentNode.insertBefore(textNode, span.nextSibling);
            }
          }
      
          sourceIndex = end;
      
          if (sourceIndex >= spanEnd) {
            spanIndex += 2;
          }
          if (sourceIndex >= decEnd) {
            decorationIndex += 2;
          }
        }
      }
    
    
      /** Maps language-specific file extensions to handlers. */
      var langHandlerRegistry = {};
      /** Register a language handler for the given file extensions.
        * @param {function (Object)} handler a function from source code to a list
        *      of decorations.  Takes a single argument job which describes the
        *      state of the computation.   The single parameter has the form
        *      {@code {
        *        sourceCode: {string} as plain text.
        *        decorations: {Array.<number|string>} an array of style classes
        *                     preceded by the position at which they start in
        *                     job.sourceCode in order.
        *                     The language handler should assigned this field.
        *        basePos: {int} the position of source in the larger source chunk.
        *                 All positions in the output decorations array are relative
        *                 to the larger source chunk.
        *      } }
        * @param {Array.<string>} fileExtensions
        */
      function registerLangHandler(handler, fileExtensions) {
        for (var i = fileExtensions.length; --i >= 0;) {
          var ext = fileExtensions[i];
          if (!langHandlerRegistry.hasOwnProperty(ext)) {
            langHandlerRegistry[ext] = handler;
          } else if (window['console']) {
            console['warn']('cannot override language handler %s', ext);
          }
        }
      }
      function langHandlerForExtension(extension, source) {
        if (!(extension && langHandlerRegistry.hasOwnProperty(extension))) {
          // Treat it as markup if the first non whitespace character is a < and
          // the last non-whitespace character is a >.
          extension = /^\s*</.test(source)
              ? 'default-markup'
              : 'default-code';
        }
        return langHandlerRegistry[extension];
      }
      registerLangHandler(decorateSource, ['default-code']);
      registerLangHandler(
          createSimpleLexer(
              [],
              [
               [PR_PLAIN,       /^[^<?]+/],
               [PR_DECLARATION, /^<!\w[^>]*(?:>|$)/],
               [PR_COMMENT,     /^<\!--[\s\S]*?(?:-\->|$)/],
               // Unescaped content in an unknown language
               ['lang-',        /^<\?([\s\S]+?)(?:\?>|$)/],
               ['lang-',        /^<%([\s\S]+?)(?:%>|$)/],
               [PR_PUNCTUATION, /^(?:<[%?]|[%?]>)/],
               ['lang-',        /^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],
               // Unescaped content in javascript.  (Or possibly vbscript).
               ['lang-js',      /^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],
               // Contains unescaped stylesheet content
               ['lang-css',     /^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],
               ['lang-in.tag',  /^(<\/?[a-z][^<>]*>)/i]
              ]),
          ['default-markup', 'htm', 'html', 'mxml', 'xhtml', 'xml', 'xsl']);
      registerLangHandler(
          createSimpleLexer(
              [
               [PR_PLAIN,        /^[\s]+/, null, ' \t\r\n'],
               [PR_ATTRIB_VALUE, /^(?:\"[^\"]*\"?|\'[^\']*\'?)/, null, '\"\'']
               ],
              [
               [PR_TAG,          /^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],
               [PR_ATTRIB_NAME,  /^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],
               ['lang-uq.val',   /^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
               [PR_PUNCTUATION,  /^[=<>\/]+/],
               ['lang-js',       /^on\w+\s*=\s*\"([^\"]+)\"/i],
               ['lang-js',       /^on\w+\s*=\s*\'([^\']+)\'/i],
               ['lang-js',       /^on\w+\s*=\s*([^\"\'>\s]+)/i],
               ['lang-css',      /^style\s*=\s*\"([^\"]+)\"/i],
               ['lang-css',      /^style\s*=\s*\'([^\']+)\'/i],
               ['lang-css',      /^style\s*=\s*([^\"\'>\s]+)/i]
               ]),
          ['in.tag']);
      registerLangHandler(
          createSimpleLexer([], [[PR_ATTRIB_VALUE, /^[\s\S]+/]]), ['uq.val']);
      registerLangHandler(sourceDecorator({
              'keywords': CPP_KEYWORDS,
              'hashComments': true,
              'cStyleComments': true,
              'types': C_TYPES
            }), ['c', 'cc', 'cpp', 'cxx', 'cyc', 'm']);
      registerLangHandler(sourceDecorator({
              'keywords': 'null,true,false'
            }), ['json']);
      registerLangHandler(sourceDecorator({
              'keywords': CSHARP_KEYWORDS,
              'hashComments': true,
              'cStyleComments': true,
              'verbatimStrings': true,
              'types': C_TYPES
            }), ['cs']);
      registerLangHandler(sourceDecorator({
              'keywords': JAVA_KEYWORDS,
              'cStyleComments': true
            }), ['java']);
      registerLangHandler(sourceDecorator({
              'keywords': SH_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true
            }), ['bsh', 'csh', 'sh']);
      registerLangHandler(sourceDecorator({
              'keywords': PYTHON_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'tripleQuotedStrings': true
            }), ['cv', 'py']);
      registerLangHandler(sourceDecorator({
              'keywords': PERL_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'regexLiterals': true
            }), ['perl', 'pl', 'pm']);
      registerLangHandler(sourceDecorator({
              'keywords': RUBY_KEYWORDS,
              'hashComments': true,
              'multiLineStrings': true,
              'regexLiterals': true
            }), ['rb']);
      registerLangHandler(sourceDecorator({
              'keywords': JSCRIPT_KEYWORDS,
              'cStyleComments': true,
              'regexLiterals': true
            }), ['js']);
      registerLangHandler(sourceDecorator({
              'keywords': COFFEE_KEYWORDS,
              'hashComments': 3,  // ### style block comments
              'cStyleComments': true,
              'multilineStrings': true,
              'tripleQuotedStrings': true,
              'regexLiterals': true
            }), ['coffee']);
      registerLangHandler(createSimpleLexer([], [[PR_STRING, /^[\s\S]+/]]), ['regex']);
    
      function applyDecorator(job) {
        var opt_langExtension = job.langExtension;
    
        try {
          // Extract tags, and convert the source code to plain text.
          var sourceAndSpans = extractSourceSpans(job.sourceNode);
          /** Plain text. @type {string} */
          var source = sourceAndSpans.sourceCode;
          job.sourceCode = source;
          job.spans = sourceAndSpans.spans;
          job.basePos = 0;
    
          // Apply the appropriate language handler
          langHandlerForExtension(opt_langExtension, source)(job);
    
          // Integrate the decorations and tags back into the source code,
          // modifying the sourceNode in place.
          recombineTagsAndDecorations(job);
        } catch (e) {
          if ('console' in window) {
            console['log'](e && e['stack'] ? e['stack'] : e);
          }
        }
      }
    
      /**
       * @param sourceCodeHtml {string} The HTML to pretty print.
       * @param opt_langExtension {string} The language name to use.
       *     Typically, a filename extension like 'cpp' or 'java'.
       * @param opt_numberLines {number|boolean} True to number lines,
       *     or the 1-indexed number of the first line in sourceCodeHtml.
       */
      function prettyPrintOne(sourceCodeHtml, opt_langExtension, opt_numberLines) {
        var container = document.createElement('PRE');
        // This could cause images to load and onload listeners to fire.
        // E.g. <img onerror="alert(1337)" src="nosuchimage.png">.
        // We assume that the inner HTML is from a trusted source.
        container.innerHTML = sourceCodeHtml;
        if (opt_numberLines) {
          numberLines(container, opt_numberLines);
        }
    
        var job = {
          langExtension: opt_langExtension,
          numberLines: opt_numberLines,
          sourceNode: container
        };
        applyDecorator(job);
        return container.innerHTML;
      }
    
      function prettyPrint(opt_whenDone) {
        function byTagName(tn) { return document.getElementsByTagName(tn); }
        // fetch a list of nodes to rewrite
        var codeSegments = [byTagName('pre'), byTagName('code'), byTagName('xmp')];
        var elements = [];
        for (var i = 0; i < codeSegments.length; ++i) {
          for (var j = 0, n = codeSegments[i].length; j < n; ++j) {
            elements.push(codeSegments[i][j]);
          }
        }
        codeSegments = null;
    
        var clock = Date;
        if (!clock['now']) {
          clock = { 'now': function () { return +(new Date); } };
        }
    
        // The loop is broken into a series of continuations to make sure that we
        // don't make the browser unresponsive when rewriting a large page.
        var k = 0;
        var prettyPrintingJob;
    
        var langExtensionRe = /\blang(?:uage)?-([\w.]+)(?!\S)/;
        var prettyPrintRe = /\bprettyprint\b/;
    
        function doWork() {
          var endTime = (window['PR_SHOULD_USE_CONTINUATION'] ?
                         clock['now']() + 250 /* ms */ :
                         Infinity);
          for (; k < elements.length && clock['now']() < endTime; k++) {
            var cs = elements[k];
            var className = cs.className;
            if (className.indexOf('prettyprint') >= 0) {
              // If the classes includes a language extensions, use it.
              // Language extensions can be specified like
              //     <pre class="prettyprint lang-cpp">
              // the language extension "cpp" is used to find a language handler as
              // passed to PR.registerLangHandler.
              // HTML5 recommends that a language be specified using "language-"
              // as the prefix instead.  Google Code Prettify supports both.
              // http://dev.w3.org/html5/spec-author-view/the-code-element.html
              var langExtension = className.match(langExtensionRe);
              // Support <pre class="prettyprint"><code class="language-c">
              var wrapper;
              if (!langExtension && (wrapper = childContentWrapper(cs))
                  && "CODE" === wrapper.tagName) {
                langExtension = wrapper.className.match(langExtensionRe);
              }
    
              if (langExtension) {
                langExtension = langExtension[1];
              }
    
              // make sure this is not nested in an already prettified element
              var nested = false;
              for (var p = cs.parentNode; p; p = p.parentNode) {
                if ((p.tagName === 'pre' || p.tagName === 'code' ||
                     p.tagName === 'xmp') &&
                    p.className && p.className.indexOf('prettyprint') >= 0) {
                  nested = true;
                  break;
                }
              }
              if (!nested) {
                // Look for a class like linenums or linenums:<n> where <n> is the
                // 1-indexed number of the first line.
                var lineNums = cs.className.match(/\blinenums\b(?::(\d+))?/);
                lineNums = lineNums
                      ? lineNums[1] && lineNums[1].length ? +lineNums[1] : true
                      : false;
                if (lineNums) { numberLines(cs, lineNums); }
    
                // do the pretty printing
                prettyPrintingJob = {
                  langExtension: langExtension,
                  sourceNode: cs,
                  numberLines: lineNums
                };
                applyDecorator(prettyPrintingJob);
              }
            }
          }
          if (k < elements.length) {
            // finish up in a continuation
            setTimeout(doWork, 250);
          } else if (opt_whenDone) {
            opt_whenDone();
          }
        }
    
        doWork();
      }
    
       /**
        * Find all the {@code <pre>} and {@code <code>} tags in the DOM with
        * {@code class=prettyprint} and prettify them.
        *
        * @param {Function?} opt_whenDone if specified, called when the last entry
        *     has been finished.
        */
      window['prettyPrintOne'] = prettyPrintOne;
       /**
        * Pretty print a chunk of code.
        *
        * @param {string} sourceCodeHtml code as html
        * @return {string} code as html, but prettier
        */
      window['prettyPrint'] = prettyPrint;
       /**
        * Contains functions for creating and registering new language handlers.
        * @type {Object}
        */
      window['PR'] = {
            'createSimpleLexer': createSimpleLexer,
            'registerLangHandler': registerLangHandler,
            'sourceDecorator': sourceDecorator,
            'PR_ATTRIB_NAME': PR_ATTRIB_NAME,
            'PR_ATTRIB_VALUE': PR_ATTRIB_VALUE,
            'PR_COMMENT': PR_COMMENT,
            'PR_DECLARATION': PR_DECLARATION,
            'PR_KEYWORD': PR_KEYWORD,
            'PR_LITERAL': PR_LITERAL,
            'PR_NOCODE': PR_NOCODE,
            'PR_PLAIN': PR_PLAIN,
            'PR_PUNCTUATION': PR_PUNCTUATION,
            'PR_SOURCE': PR_SOURCE,
            'PR_STRING': PR_STRING,
            'PR_TAG': PR_TAG,
            'PR_TYPE': PR_TYPE
          };
    })();
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/resources/js/prettify.min.js��������������������������������������0000664�0000000�0000000�00000033621�12577562624�0024315�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������// Copyright (C) 2006 Google Inc.
    //
    // Licensed 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.
    var q=null;window.PR_SHOULD_USE_CONTINUATION=!0;
    (function(){function L(a){function m(a){var f=a.charCodeAt(0);if(f!==92)return f;var b=a.charAt(1);return(f=r[b])?f:"0"<=b&&b<="7"?parseInt(a.substring(1),8):b==="u"||b==="x"?parseInt(a.substring(2),16):a.charCodeAt(1)}function e(a){if(a<32)return(a<16?"\\x0":"\\x")+a.toString(16);a=String.fromCharCode(a);if(a==="\\"||a==="-"||a==="["||a==="]")a="\\"+a;return a}function h(a){for(var f=a.substring(1,a.length-1).match(/\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\[0-3][0-7]{0,2}|\\[0-7]{1,2}|\\[\S\s]|[^\\]/g),a=
    [],b=[],o=f[0]==="^",c=o?1:0,i=f.length;c<i;++c){var j=f[c];if(/\\[bdsw]/i.test(j))a.push(j);else{var j=m(j),d;c+2<i&&"-"===f[c+1]?(d=m(f[c+2]),c+=2):d=j;b.push([j,d]);d<65||j>122||(d<65||j>90||b.push([Math.max(65,j)|32,Math.min(d,90)|32]),d<97||j>122||b.push([Math.max(97,j)&-33,Math.min(d,122)&-33]))}}b.sort(function(a,f){return a[0]-f[0]||f[1]-a[1]});f=[];j=[NaN,NaN];for(c=0;c<b.length;++c)i=b[c],i[0]<=j[1]+1?j[1]=Math.max(j[1],i[1]):f.push(j=i);b=["["];o&&b.push("^");b.push.apply(b,a);for(c=0;c<
    f.length;++c)i=f[c],b.push(e(i[0])),i[1]>i[0]&&(i[1]+1>i[0]&&b.push("-"),b.push(e(i[1])));b.push("]");return b.join("")}function y(a){for(var f=a.source.match(/\[(?:[^\\\]]|\\[\S\s])*]|\\u[\dA-Fa-f]{4}|\\x[\dA-Fa-f]{2}|\\\d+|\\[^\dux]|\(\?[!:=]|[()^]|[^()[\\^]+/g),b=f.length,d=[],c=0,i=0;c<b;++c){var j=f[c];j==="("?++i:"\\"===j.charAt(0)&&(j=+j.substring(1))&&j<=i&&(d[j]=-1)}for(c=1;c<d.length;++c)-1===d[c]&&(d[c]=++t);for(i=c=0;c<b;++c)j=f[c],j==="("?(++i,d[i]===void 0&&(f[c]="(?:")):"\\"===j.charAt(0)&&
    (j=+j.substring(1))&&j<=i&&(f[c]="\\"+d[i]);for(i=c=0;c<b;++c)"^"===f[c]&&"^"!==f[c+1]&&(f[c]="");if(a.ignoreCase&&s)for(c=0;c<b;++c)j=f[c],a=j.charAt(0),j.length>=2&&a==="["?f[c]=h(j):a!=="\\"&&(f[c]=j.replace(/[A-Za-z]/g,function(a){a=a.charCodeAt(0);return"["+String.fromCharCode(a&-33,a|32)+"]"}));return f.join("")}for(var t=0,s=!1,l=!1,p=0,d=a.length;p<d;++p){var g=a[p];if(g.ignoreCase)l=!0;else if(/[a-z]/i.test(g.source.replace(/\\u[\da-f]{4}|\\x[\da-f]{2}|\\[^UXux]/gi,""))){s=!0;l=!1;break}}for(var r=
    {b:8,t:9,n:10,v:11,f:12,r:13},n=[],p=0,d=a.length;p<d;++p){g=a[p];if(g.global||g.multiline)throw Error(""+g);n.push("(?:"+y(g)+")")}return RegExp(n.join("|"),l?"gi":"g")}function M(a){function m(a){switch(a.nodeType){case 1:if(e.test(a.className))break;for(var g=a.firstChild;g;g=g.nextSibling)m(g);g=a.nodeName;if("BR"===g||"LI"===g)h[s]="\n",t[s<<1]=y++,t[s++<<1|1]=a;break;case 3:case 4:g=a.nodeValue,g.length&&(g=p?g.replace(/\r\n?/g,"\n"):g.replace(/[\t\n\r ]+/g," "),h[s]=g,t[s<<1]=y,y+=g.length,
    t[s++<<1|1]=a)}}var e=/(?:^|\s)nocode(?:\s|$)/,h=[],y=0,t=[],s=0,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=document.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);m(a);return{a:h.join("").replace(/\n$/,""),c:t}}function B(a,m,e,h){m&&(a={a:m,d:a},e(a),h.push.apply(h,a.e))}function x(a,m){function e(a){for(var l=a.d,p=[l,"pln"],d=0,g=a.a.match(y)||[],r={},n=0,z=g.length;n<z;++n){var f=g[n],b=r[f],o=void 0,c;if(typeof b===
    "string")c=!1;else{var i=h[f.charAt(0)];if(i)o=f.match(i[1]),b=i[0];else{for(c=0;c<t;++c)if(i=m[c],o=f.match(i[1])){b=i[0];break}o||(b="pln")}if((c=b.length>=5&&"lang-"===b.substring(0,5))&&!(o&&typeof o[1]==="string"))c=!1,b="src";c||(r[f]=b)}i=d;d+=f.length;if(c){c=o[1];var j=f.indexOf(c),k=j+c.length;o[2]&&(k=f.length-o[2].length,j=k-c.length);b=b.substring(5);B(l+i,f.substring(0,j),e,p);B(l+i+j,c,C(b,c),p);B(l+i+k,f.substring(k),e,p)}else p.push(l+i,b)}a.e=p}var h={},y;(function(){for(var e=a.concat(m),
    l=[],p={},d=0,g=e.length;d<g;++d){var r=e[d],n=r[3];if(n)for(var k=n.length;--k>=0;)h[n.charAt(k)]=r;r=r[1];n=""+r;p.hasOwnProperty(n)||(l.push(r),p[n]=q)}l.push(/[\S\s]/);y=L(l)})();var t=m.length;return e}function u(a){var m=[],e=[];a.tripleQuotedStrings?m.push(["str",/^(?:'''(?:[^'\\]|\\[\S\s]|''?(?=[^']))*(?:'''|$)|"""(?:[^"\\]|\\[\S\s]|""?(?=[^"]))*(?:"""|$)|'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$))/,q,"'\""]):a.multiLineStrings?m.push(["str",/^(?:'(?:[^'\\]|\\[\S\s])*(?:'|$)|"(?:[^"\\]|\\[\S\s])*(?:"|$)|`(?:[^\\`]|\\[\S\s])*(?:`|$))/,
    q,"'\"`"]):m.push(["str",/^(?:'(?:[^\n\r'\\]|\\.)*(?:'|$)|"(?:[^\n\r"\\]|\\.)*(?:"|$))/,q,"\"'"]);a.verbatimStrings&&e.push(["str",/^@"(?:[^"]|"")*(?:"|$)/,q]);var h=a.hashComments;h&&(a.cStyleComments?(h>1?m.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,q,"#"]):m.push(["com",/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\n\r]*)/,q,"#"]),e.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,q])):m.push(["com",/^#[^\n\r]*/,
    q,"#"]));a.cStyleComments&&(e.push(["com",/^\/\/[^\n\r]*/,q]),e.push(["com",/^\/\*[\S\s]*?(?:\*\/|$)/,q]));a.regexLiterals&&e.push(["lang-regex",/^(?:^^\.?|[!+-]|!=|!==|#|%|%=|&|&&|&&=|&=|\(|\*|\*=|\+=|,|-=|->|\/|\/=|:|::|;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|[?@[^]|\^=|\^\^|\^\^=|{|\||\|=|\|\||\|\|=|~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\s*(\/(?=[^*/])(?:[^/[\\]|\\[\S\s]|\[(?:[^\\\]]|\\[\S\s])*(?:]|$))+\/)/]);(h=a.types)&&e.push(["typ",h]);a=(""+a.keywords).replace(/^ | $/g,
    "");a.length&&e.push(["kwd",RegExp("^(?:"+a.replace(/[\s,]+/g,"|")+")\\b"),q]);m.push(["pln",/^\s+/,q," \r\n\t\xa0"]);e.push(["lit",/^@[$_a-z][\w$@]*/i,q],["typ",/^(?:[@_]?[A-Z]+[a-z][\w$@]*|\w+_t\b)/,q],["pln",/^[$_a-z][\w$@]*/i,q],["lit",/^(?:0x[\da-f]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+-]?\d+)?)[a-z]*/i,q,"0123456789"],["pln",/^\\[\S\s]?/,q],["pun",/^.[^\s\w"-$'./@\\`]*/,q]);return x(m,e)}function D(a,m){function e(a){switch(a.nodeType){case 1:if(k.test(a.className))break;if("BR"===a.nodeName)h(a),
    a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)e(a);break;case 3:case 4:if(p){var b=a.nodeValue,d=b.match(t);if(d){var c=b.substring(0,d.index);a.nodeValue=c;(b=b.substring(d.index+d[0].length))&&a.parentNode.insertBefore(s.createTextNode(b),a.nextSibling);h(a);c||a.parentNode.removeChild(a)}}}}function h(a){function b(a,d){var e=d?a.cloneNode(!1):a,f=a.parentNode;if(f){var f=b(f,1),g=a.nextSibling;f.appendChild(e);for(var h=g;h;h=g)g=h.nextSibling,f.appendChild(h)}return e}
    for(;!a.nextSibling;)if(a=a.parentNode,!a)return;for(var a=b(a.nextSibling,0),e;(e=a.parentNode)&&e.nodeType===1;)a=e;d.push(a)}var k=/(?:^|\s)nocode(?:\s|$)/,t=/\r\n?|\n/,s=a.ownerDocument,l;a.currentStyle?l=a.currentStyle.whiteSpace:window.getComputedStyle&&(l=s.defaultView.getComputedStyle(a,q).getPropertyValue("white-space"));var p=l&&"pre"===l.substring(0,3);for(l=s.createElement("LI");a.firstChild;)l.appendChild(a.firstChild);for(var d=[l],g=0;g<d.length;++g)e(d[g]);m===(m|0)&&d[0].setAttribute("value",
    m);var r=s.createElement("OL");r.className="linenums";for(var n=Math.max(0,m-1|0)||0,g=0,z=d.length;g<z;++g)l=d[g],l.className="L"+(g+n)%10,l.firstChild||l.appendChild(s.createTextNode("\xa0")),r.appendChild(l);a.appendChild(r)}function k(a,m){for(var e=m.length;--e>=0;){var h=m[e];A.hasOwnProperty(h)?window.console&&console.warn("cannot override language handler %s",h):A[h]=a}}function C(a,m){if(!a||!A.hasOwnProperty(a))a=/^\s*</.test(m)?"default-markup":"default-code";return A[a]}function E(a){var m=
    a.g;try{var e=M(a.h),h=e.a;a.a=h;a.c=e.c;a.d=0;C(m,h)(a);var k=/\bMSIE\b/.test(navigator.userAgent),m=/\n/g,t=a.a,s=t.length,e=0,l=a.c,p=l.length,h=0,d=a.e,g=d.length,a=0;d[g]=s;var r,n;for(n=r=0;n<g;)d[n]!==d[n+2]?(d[r++]=d[n++],d[r++]=d[n++]):n+=2;g=r;for(n=r=0;n<g;){for(var z=d[n],f=d[n+1],b=n+2;b+2<=g&&d[b+1]===f;)b+=2;d[r++]=z;d[r++]=f;n=b}for(d.length=r;h<p;){var o=l[h+2]||s,c=d[a+2]||s,b=Math.min(o,c),i=l[h+1],j;if(i.nodeType!==1&&(j=t.substring(e,b))){k&&(j=j.replace(m,"\r"));i.nodeValue=
    j;var u=i.ownerDocument,v=u.createElement("SPAN");v.className=d[a+1];var x=i.parentNode;x.replaceChild(v,i);v.appendChild(i);e<o&&(l[h+1]=i=u.createTextNode(t.substring(b,o)),x.insertBefore(i,v.nextSibling))}e=b;e>=o&&(h+=2);e>=c&&(a+=2)}}catch(w){"console"in window&&console.log(w&&w.stack?w.stack:w)}}var v=["break,continue,do,else,for,if,return,while"],w=[[v,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
    "catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],F=[w,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],G=[w,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"],
    H=[G,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"],w=[w,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"],I=[v,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],
    J=[v,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],v=[v,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],K=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/,N=/\S/,O=u({keywords:[F,H,w,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END"+
    I,J,v],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),A={};k(O,["default-code"]);k(x([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\S\s]*?(?:--\>|$)/],["lang-",/^<\?([\S\s]+?)(?:\?>|$)/],["lang-",/^<%([\S\s]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",/^<xmp\b[^>]*>([\S\s]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\S\s]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\S\s]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),
    ["default-markup","htm","html","mxml","xhtml","xml","xsl"]);k(x([["pln",/^\s+/,q," \t\r\n"],["atv",/^(?:"[^"]*"?|'[^']*'?)/,q,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w-.:]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^\s"'>]*(?:[^\s"'/>]|\/(?=\s)))/],["pun",/^[/<->]+/],["lang-js",/^on\w+\s*=\s*"([^"]+)"/i],["lang-js",/^on\w+\s*=\s*'([^']+)'/i],["lang-js",/^on\w+\s*=\s*([^\s"'>]+)/i],["lang-css",/^style\s*=\s*"([^"]+)"/i],["lang-css",/^style\s*=\s*'([^']+)'/i],["lang-css",
    /^style\s*=\s*([^\s"'>]+)/i]]),["in.tag"]);k(x([],[["atv",/^[\S\s]+/]]),["uq.val"]);k(u({keywords:F,hashComments:!0,cStyleComments:!0,types:K}),["c","cc","cpp","cxx","cyc","m"]);k(u({keywords:"null,true,false"}),["json"]);k(u({keywords:H,hashComments:!0,cStyleComments:!0,verbatimStrings:!0,types:K}),["cs"]);k(u({keywords:G,cStyleComments:!0}),["java"]);k(u({keywords:v,hashComments:!0,multiLineStrings:!0}),["bsh","csh","sh"]);k(u({keywords:I,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),
    ["cv","py"]);k(u({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["perl","pl","pm"]);k(u({keywords:J,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb"]);k(u({keywords:w,cStyleComments:!0,regexLiterals:!0}),["js"]);k(u({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes",
    hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);k(x([],[["str",/^[\S\s]+/]]),["regex"]);window.prettyPrintOne=function(a,m,e){var h=document.createElement("PRE");h.innerHTML=a;e&&D(h,e);E({g:m,i:e,h:h});return h.innerHTML};window.prettyPrint=function(a){function m(){for(var e=window.PR_SHOULD_USE_CONTINUATION?l.now()+250:Infinity;p<h.length&&l.now()<e;p++){var n=h[p],k=n.className;if(k.indexOf("prettyprint")>=0){var k=k.match(g),f,b;if(b=
    !k){b=n;for(var o=void 0,c=b.firstChild;c;c=c.nextSibling)var i=c.nodeType,o=i===1?o?b:c:i===3?N.test(c.nodeValue)?b:o:o;b=(f=o===b?void 0:o)&&"CODE"===f.tagName}b&&(k=f.className.match(g));k&&(k=k[1]);b=!1;for(o=n.parentNode;o;o=o.parentNode)if((o.tagName==="pre"||o.tagName==="code"||o.tagName==="xmp")&&o.className&&o.className.indexOf("prettyprint")>=0){b=!0;break}b||((b=(b=n.className.match(/\blinenums\b(?::(\d+))?/))?b[1]&&b[1].length?+b[1]:!0:!1)&&D(n,b),d={g:k,h:n,i:b},E(d))}}p<h.length?setTimeout(m,
    250):a&&a()}for(var e=[document.getElementsByTagName("pre"),document.getElementsByTagName("code"),document.getElementsByTagName("xmp")],h=[],k=0;k<e.length;++k)for(var t=0,s=e[k].length;t<s;++t)h.push(e[k][t]);var e=q,l=Date;l.now||(l={now:function(){return+new Date}});var p=0,d,g=/\blang(?:uage)?-([\w.]+)(?!\S)/;m()};window.PR={createSimpleLexer:x,registerLangHandler:k,sourceDecorator:u,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",
    PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ"}})();
    ���������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/resources/js/site.js����������������������������������������������0000664�0000000�0000000�00000005710�12577562624�0022627�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������/*
    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.
    */
    
    /* Executed on page load. */
    $(document).ready(function() {
    
    	//
    	// This is a hack to enable google-code-prettify to work with maven.
    	//
    	// The problem is that maven, when building the site, replaces:
    	// <pre class="prettyprint">...</pre>
    	// with:
    	// <div class="prettyprint"><pre>...</pre></div>
    	//
    	// Effectively, it removes the class parameter from the <pre> element, which
    	// is required for google-code-prettify to work.
    	// 
    	// This hack restores the class of all <pre> elements which are the child of 
    	// a <div class="prettyprint">.
    	//
    	$('pre').each(function() {
    		var parent = $(this).parent();
    		
    		if (parent.hasClass('prettyprint')) {
    			parent.removeClass('prettyprint');
    			$(this).addClass('prettyprint');
    		}
    		
    		if (parent.hasClass('linenums')) {
    			parent.removeClass('linenums');
    			$(this).addClass('linenums');
    		}
    	})
    	
    	// Hack to add default visuals to tables
    	$('table').each(function() {
    		if ($(this).hasClass('bodyTable')) {
    			
    			// Remove border="1" which is added by maven
    			this.border = 0;
    			
    			// Add bootstrap table styling
    			$(this).addClass('table table-striped table-bordered');
    		}
    	});
    	
    	// Render tabs
    	$('.auto-tabs').each(function(groupid) {
    
    		// Find tab bar
    		$(this).find('ul').each(function() {
    
    			// Add styling
    			$(this).addClass('nav nav-tabs');
    
    			// Go tab bar items
    			$(this).find('li').each(function(itemid) {
    			
    				// Set first tab as active
    				if (itemid == 0) {
    					$(this).addClass('active');
    				}
    				
    				// Replace text with a link to tab contents
    				var name = $(this).html();
    				var link = $('<a>')
    					.attr('href', '#' + 'tab-' + groupid + '-' + itemid)
    					.attr('data-toggle', 'tab')
    					.html(name);
    				$(this).html(link);
    			});
    		});
    		
    		// Find tab contents
    		$(this).find('.tab-content .tab-pane').each(function(itemid) {
    			
    			// Set first tab as active
    			if (itemid == 0) {
    				$(this).addClass('active');
    			}
    			
    			// Set the tab id
    			$(this).attr('id', 'tab-' + groupid + '-' + itemid);
    		});
    	});
    	
    	// Make external links open in new tab
    	$('a.external').attr('target', '_blank');
    	
    	// Trigger prettyprint
    	prettyPrint();
    });
    ��������������������������������������������������������logging-log4j2-log4j-2.4/src/site/resources/pdf-config.xml������������������������������������������0000664�0000000�0000000�00000004062�12577562624�0023446�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    
    <!--
    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.
    -->
    
    <!-- START SNIPPET: foConfig -->
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:fo="http://www.w3.org/1999/XSL/Format">
      <!-- <xsl:attribute-set name="layout.master.set.base">
        <xsl:attribute name="page-width">8.5in</xsl:attribute>
        <xsl:attribute name="page-height">11.0in</xsl:attribute>
        <xsl:attribute name="margin-top">0.625in</xsl:attribute>
        <xsl:attribute name="margin-bottom">0.6in</xsl:attribute>
        <xsl:attribute name="margin-left">1in</xsl:attribute>
        <xsl:attribute name="margin-right">1in</xsl:attribute>
      </xsl:attribute-set> -->
      <xsl:template match="processing-instruction('hard-pagebreak')">
        <fo:block break-after='page'/>
      </xsl:template>
      <xsl:attribute-set name="body.pre" use-attribute-sets="base.pre.style">
        <xsl:attribute name="font-size">8pt</xsl:attribute>
      </xsl:attribute-set>
      <!-- <xsl:attribute-set name="body.source" use-attribute-sets="body.pre">
        <xsl:attribute name="color">black</xsl:attribute>
        <xsl:attribute name="start-indent">inherited-property-value(start-indent) + 1.5em</xsl:attribute>
        <xsl:attribute name="end-indent">inherited-property-value(end-indent) + 1.5em</xsl:attribute>
      </xsl:attribute-set> -->
    </xsl:stylesheet>
        <!-- END SNIPPET: foConfig -->������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/site.vm�����������������������������������������������������������0000664�0000000�0000000�00000043755�12577562624�0020222�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <!--
       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.
    -->
    <!-- Generated by Apache Maven Doxia at $dateFormat.format( $currentDate ) -->
    #macro ( link $href $name $target $img $position $alt $border $width $height )
    	#set ( $linkTitle = ' title="' + $name + '"' )
    	#if( $target )
    		#set ( $linkTarget = ' target="' + $target + '"' )
    	#else
    		#set ( $linkTarget = "" )
    	#end
    	#if ( $href.toLowerCase().startsWith("http:/") || $href.toLowerCase().startsWith("https:/") ||
    		$href.toLowerCase().startsWith("ftp:/") || $href.toLowerCase().startsWith("mailto:/") ||
    		$href.toLowerCase().startsWith("file:/") || ($href.toLowerCase().indexOf("://") != -1) )
    		#set ( $linkClass = ' class="external" target="_blank"' )
    
    		#if ( $linkTarget )
    		#else
    			#set ( $linkTarget = "_blank" )
    		#end
    
    	#else
    		#set ( $linkClass = "" )
    	#end
    	#if ( $img )
    		#if ( $position == "left" )
    			<a href="$href"$linkClass$linkTarget$linkTitle>#image($img $alt $border $width $height)$name</a>
    		#else
    			<a href="$href"$linkClass$linkTarget$linkTitle>$name #image($img $alt $border $width $height)</a>
    		#end
    	#else
    		<a href="$href"$linkClass$linkTarget$linkTitle>$name</a>
    	#end
    #end
    ##
    #macro ( image $img $alt $border $width $height )
    	#if( $img )
    		#if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") ||
    						$img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:/") ||
    						$img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) )
    			#set ( $imgSrc = $PathTool.calculateLink( $img, $relativePath ) )
    			#set ( $imgSrc = $imgSrc.replaceAll( '\\', '/' ) )
    			#set ( $imgSrc = ' src="' + $imgSrc + '"' )
    		#else
    			#set ( $imgSrc = ' src="' + $img + '"' )
    		#end
    		#if( $alt )
    			#set ( $imgAlt = ' alt="' + $alt + '"' )
    		#else
    			#set ( $imgAlt = ' alt=""' )
    		#end
    		#if( $border )
    			#set ( $imgBorder = ' border="' + $border + '"' )
    		#else
    			#set ( $imgBorder = "" )
    		#end
    		#if( $width )
    			#set ( $imgWidth = ' width="' + $width + '"' )
    		#else
    			#set ( $imgWidth = "" )
    		#end
    		#if( $height )
    			#set ( $imgHeight = ' height="' + $height + '"' )
    		#else
    			#set ( $imgHeight = "" )
    		#end
    		<img class="imageLink"$imgSrc$imgAlt$imgBorder$imgWidth$imgHeight/>
    	#end
    #end
    #macro ( banner $banner $id )
    	#if ( $banner )
    		#if( $banner.href )
    			#set ( $hrf = $banner.href )
    			#if ( ! ( $hrf.toLowerCase().startsWith("http:/") || $hrf.toLowerCase().startsWith("https:/") ||
    				$hrf.toLowerCase().startsWith("ftp:/") || $hrf.toLowerCase().startsWith("mailto:/") ||
    				$hrf.toLowerCase().startsWith("file:/") || ($hrf.toLowerCase().indexOf("://") != -1) ) )
    				#set ( $hrf = $PathTool.calculateLink( $hrf, $relativePath ) )
    				#set ( $hrf = $hrf.replaceAll( '\\', '/' ) )
    				#if ( ( $hrf == '' ) )
    					#set ( $hrf = './' )
    				#end
    			#end
    			<a href="$hrf" id="$id"#if( $banner.alt ) title="$banner.alt"#end>
    		#else
    				<div id="$id">
    		#end
    ##
    		#if( $banner.src )
    				#set ( $src = $banner.src )
    				#if ( ! ( $src.toLowerCase().startsWith("http:/") || $src.toLowerCase().startsWith("https:/") ||
    								$src.toLowerCase().startsWith("ftp:/") || $src.toLowerCase().startsWith("mailto:/") ||
    								$src.toLowerCase().startsWith("file:/") || ($src.toLowerCase().indexOf("://") != -1) ) )
    						#set ( $src = $PathTool.calculateLink( $src, $relativePath ) )
    						#set ( $src = $src.replaceAll( '\\', '/' ) )
    				#end
    				#if ( $banner.alt )
    						#set ( $alt = $banner.alt )
    				#else
    						#set ( $alt = $banner.name )
    				#end
    				<img src="$src" alt="$alt" />
    		#else
    				$banner.name
    		#end
    ##
    		#if( $banner.href )
    				</a>
    		#else
    				</div>
    		#end
    	#end
    #end
    ##
    #macro ( links $links )
    	<ul class="nav">
    	#set ( $counter = 0 )
    	#foreach( $item in $links )
    		#set ( $counter = $counter + 1 )
    		#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
    		#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
    		#set ( $activeClass = "" )
    		#if ( $alignedFileName == $currentItemHref)
    			#set ( $activeClass = ' class="active"' )
    		#end
    		<li$activeClass>
    		#link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height )
    		</li>
    	#end
    	</ul>
    #end
    ##
    #macro ( breadcrumbs $breadcrumbs )
    	#foreach( $item in $breadcrumbs )
    		#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
    		#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
    		#if ( ( $currentItemHref == '' ) )
    			#set ( $currentItemHref = './' )
    		#end
    ##
    			#link( $currentItemHref $item.name $item.target $item.img $item.position $item.alt $item.border $item.width $item.height )
    			<span class="divider">&gt;</span>
    	#end
    	$title
    #end
    ##
    #macro ( displayTree $display $item )
    	#if ( $item && $item.items && $item.items.size() > 0 )
    		#foreach( $subitem in $item.items )
    			#set ( $subitemHref = $PathTool.calculateLink( $subitem.href, $relativePath ) )
    			#set ( $subitemHref = $subitemHref.replaceAll( '\\', '/' ) )
    ##
    			#if ( $alignedFileName == $subitemHref )
    				#set ( $display = true )
    			#end
    ##
    			#displayTree( $display $subitem )
    		#end
    	#end
    #end
    ##
    #macro ( menuItem $item $isComponentDocumentation )
    	#set ( $collapse = "none" )
    	#set ( $currentItemHref = $PathTool.calculateLink( $item.href, $relativePath ) )
    	#set ( $currentItemHref = $currentItemHref.replaceAll( '\\', '/' ) )
    ##
    	#if ( $item && $item.items && $item.items.size() > 0 )
    		#if ( $item.collapse == false )
    			#set ( $collapse = "expanded" )
    		#else
    			## By default collapsed
    			#set ( $collapse = "collapsed" )
    		#end
    ##
    		#set ( $display = false )
    		#displayTree( $display $item )
    ##
    		#if ( $alignedFileName == $currentItemHref || $display )
    			#set ( $collapse = "expanded" )
    		#end
    	#end
    	#set ( $active = "" )
    	#if ( $alignedFileName == $currentItemHref )
    	#set ($active = " active")
    	#end
    	#set ( $thisProjectDir = "../${project.artifactId}" )
    	#if ($thisProjectDir == $PathTool.getDirectoryComponent( $item.href ))
    	#set ($active = " active")
    	#end
    	#if (${project.artifactId} != "log4j" && $isComponentDocumentation && 
    				($item.href == "team-list.html" || $item.href == "mail-lists.html" 
    				|| $item.href == "issue-tracking.html" || $item.href == "license.html" 
    				|| $item.href == "source-repository.html"))
    	<!-- Removing overall project item $item.name from component-specific menu -->
    	#else
    		#set ($thisItemName = $item.name)
    		#if (${project.artifactId} != "log4j" && $isComponentDocumentation )
    		#set ($thisItemName = $item.name.replace("Project Information", "Component Project"))
    		#set ($thisItemName = $item.name.replace("Project", "Component"))
    		#end
    		<li class="$collapse$active">
    		#link($currentItemHref $thisItemName $item.target $item.img $item.position $item.alt $item.border $item.width $item.height )
    		#if ( $item && $item.items && $item.items.size() > 0 )
    			#if ( $collapse == "expanded" )
    				<ul>
    					#foreach( $subitem in $item.items )
    						#menuItem( $subitem $isComponentDocumentation )
    					#end
    				</ul>
    			#end
    		#end
    		</li>
     	#end
    #end
    ##
    #macro ( mainMenu $menus )
    	#foreach( $menu in $menus )
    		<ul class="nav nav-list">
    		#set ($isComponentDocumentation = false)
     		#if ( $menu.name )
    			#set ( $menuName = $menu.name )
    			#if ( $menuName == "Project Documentation" )
    			#set ( $menuName = "Component Documentation" )
    			#set ($isComponentDocumentation = true)
    			#end
    			#if ( $menu.img )
    			 <li class="nav-header"><i class="$menu.img"></i>$menuName</li>
    			#else
    			 <li class="nav-header">$menuName</li>
    			#end
    		#end
    		#if ( $menu.items && $menu.items.size() > 0 )
    			#foreach( $item in $menu.items )
    				#menuItem( $item $isComponentDocumentation )
    			#end
    		#end
    		</ul>
    	#end
    #end
    ##
    #macro ( copyright )
    	#if ( $project )
    		#if ( ${project.organization} && ${project.organization.name} )
    			#set ( $period = "" )
    		#else
    			#set ( $period = "." )
    	 #end
    ##
    	 #set ( $currentYear = ${currentDate.year} + 1900 )
    ##
    		#if ( ${project.inceptionYear} && ( ${project.inceptionYear} != ${currentYear.toString()} ) )
    			${project.inceptionYear}-${currentYear}${period}
    		#else
    			${currentYear}${period}
    		#end
    ##
    		#if ( ${project.organization} )
    			#if ( ${project.organization.name} && ${project.organization.url} )
    					<a href="$project.organization.url">${project.organization.name}</a>.
    			#elseif ( ${project.organization.name} )
    				${project.organization.name}.
    			#end
    		#end
    	#end
    #end
    ##
    #macro ( publishDate $position $publishDate $version )
    	#if ( $publishDate && $publishDate.format )
    		#set ( $format = $publishDate.format )
    	#else
    		#set ( $format = "yyyy-MM-dd" )
    	#end
    ##
    	$dateFormat.applyPattern( $format )
    ##
    	#set ( $dateToday = $dateFormat.format( $currentDate ) )
    ##
    	#if ( $publishDate && $publishDate.position )
    		#set ( $datePosition = $publishDate.position )
    	#else
    		#set ( $datePosition = "left" )
    	#end
    ##
    	#if ( $version )
    		#if ( $version.position )
    			#set ( $versionPosition = $version.position )
    		#else
    			#set ( $versionPosition = "left" )
    		#end
    	#else
    		#set ( $version = "" )
    		#set ( $versionPosition = "left" )
    	#end
    ##
    	#set ( $breadcrumbs = $decoration.body.breadcrumbs )
    	#set ( $links = $decoration.body.links )
    
    	#if ( $datePosition.equalsIgnoreCase( $position ) )
    		#if ( ( $datePosition.equalsIgnoreCase( "right" ) ) || ( $datePosition.equalsIgnoreCase( "bottom" ) ) )
    			<span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday</span>
    			#if ( $versionPosition.equalsIgnoreCase( $position ) )
    				<span class="divider">|</span> <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    			#end
    		#elseif ( ( $datePosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $datePosition.equalsIgnoreCase( "navigation-top" ) ) )
    			<div id="lastPublished">
    				<span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday</span>
    				#if ( $versionPosition.equalsIgnoreCase( $position ) )
    					<span class="divider">|</span> <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    				#end
    			</div>
    		#elseif ( $datePosition.equalsIgnoreCase("left") )
    			<div class="pull-left">
    				<span id="publishDate">$i18n.getString( "site-renderer", $locale, "template.lastpublished" ): $dateToday</span>
    				#if ( $versionPosition.equalsIgnoreCase( $position ) )
    					<span class="divider">|</span> <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    				#end
    				#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
    					<span class="divider">|</span> #breadcrumbs( $breadcrumbs )
    				#end
    			</div>
    		#end
    	#elseif ( $versionPosition.equalsIgnoreCase( $position ) )
    		#if ( ( $versionPosition.equalsIgnoreCase( "right" ) ) || ( $versionPosition.equalsIgnoreCase( "bottom" ) ) )
    			$prefix <span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    		#elseif ( ( $versionPosition.equalsIgnoreCase( "navigation-bottom" ) ) || ( $versionPosition.equalsIgnoreCase( "navigation-top" ) ) )
    			<div id="lastPublished">
    				<span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    			</div>
    		#elseif ( $versionPosition.equalsIgnoreCase("left") )
    			<div class="pull-left">
    				<span id="projectVersion">$i18n.getString( "site-renderer", $locale, "template.version" ): ${project.version}</span>
    				#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
    					<span class="divider">|</span> #breadcrumbs( $breadcrumbs )
    				#end
    			</div>
    		#end
    	#elseif ( $position.equalsIgnoreCase( "left" ) )
    		#if ( $breadcrumbs && $breadcrumbs.size() > 0 )
    			<div class="pull-left">
    				#breadcrumbs( $breadcrumbs )
    			</div>
    		#end
    	#end
    #end
    ##
    #macro ( poweredByLogo $poweredBy )
    	#if( $poweredBy )
    		#foreach ($item in $poweredBy)
    			#if( $item.href )
    				#set ( $href = $PathTool.calculateLink( $item.href, $relativePath ) )
    				#set ( $href = $href.replaceAll( '\\', '/' ) )
    			#else
    				#set ( $href="http://maven.apache.org/" )
    			#end
    ##
    			#if( $item.name )
    				#set ( $name = $item.name )
    			#else
    				#set ( $name = $i18n.getString( "site-renderer", $locale, "template.builtby" )	)
    				#set ( $name = "${name} Maven"	)
    			#end
    ##
    			#if( $item.img )
    				#set ( $img = $item.img )
    			#else
    				#set ( $img = "images/maven-feather.png" )
    			#end
    ##
    			#if ( ! ( $img.toLowerCase().startsWith("http:/") || $img.toLowerCase().startsWith("https:/") ||
    						$img.toLowerCase().startsWith("ftp:/") || $img.toLowerCase().startsWith("mailto:/") ||
    						$img.toLowerCase().startsWith("file:/") || ($img.toLowerCase().indexOf("://") != -1) ) )
    				#set ( $img = $PathTool.calculateLink( $img, $relativePath ) )
    				#set ( $img = $img.replaceAll( '\\', '/' ) )
    			#end
    ##
    			#if( $item.alt )
    				#set ( $alt = ' alt="' + $item.alt + '"' )
    			#else
    				#set ( $alt = ' alt="' + $name + '"' )
    			#end
    ##
    			#if( $item.border )
    				#set ( $border = ' border="' + $item.border + '"' )
    			#else
    				#set ( $border = "" )
    			#end
    ##
    			#if( $item.width )
    				#set ( $width = ' width="' + $item.width + '"' )
    			#else
    				#set ( $width = "" )
    			#end
    			#if( $item.height )
    				#set ( $height = ' height="' + $item.height + '"' )
    			#else
    				#set ( $height = "" )
    			#end
    ##
    			<a href="$href" title="$name" class="poweredBy">
    				<img class="poweredBy" $alt src="$img" $border $width $height />
    			</a>
    		#end
    		#if( $poweredBy.isEmpty() )
    			<a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
    				<img class="poweredBy" alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/maven-feather.png" />
    			</a>
    		#end
    	#else
    		<a href="http://maven.apache.org/" title="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" class="poweredBy">
    			<img class="poweredBy" alt="$i18n.getString( "site-renderer", $locale, "template.builtby" ) Maven" src="$relativePath/images/maven-feather.png" />
    		</a>
    	#end
    #end
    ##
    #macro ( googleAnalytics $accountId )
    	#if( $accountId && $accountId != "" )
    		<!-- Google Analytics -->
    		<script type="text/javascript">
    
    			var _gaq = _gaq || [];
    			_gaq.push(['_setAccount', '$accountId']);
    			_gaq.push (['_gat._anonymizeIp']);
    			_gaq.push(['_trackPageview']);
    
    			(function() {
    				var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    				ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    				var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
    			})();
    
    		</script>
    	#end
    #end
    ##
    <html xmlns="http://www.w3.org/1999/xhtml"#if ( $locale ) xml:lang="$locale.language" lang="$locale.language"#end>
    	<head>
    		<meta http-equiv="Content-Type" content="text/html; charset=${outputEncoding}" />
    		<title>$title - $project.name</title>
    		<link rel="stylesheet" href="$relativePath/css/bootstrap.min.css" type="text/css" />
    		<link rel="stylesheet" href="$relativePath/css/site.css" type="text/css" />
    		<script type="text/javascript" src="$relativePath/js/jquery.min.js"></script>
    		<script type="text/javascript" src="$relativePath/js/bootstrap.min.js"></script>
    		<script type="text/javascript" src="$relativePath/js/prettify.min.js"></script>
    		<script type="text/javascript" src="$relativePath/js/site.js"></script>
    #foreach( $author in $authors )
    			<meta name="author" content="$author" />
    #end
    #if ( $dateCreation )
    		<meta name="Date-Creation-yyyymmdd" content="$dateCreation" />
    #end
    #if ( $dateRevision )
    		<meta name="Date-Revision-yyyymmdd" content="$dateRevision" />
    #end
    #if ( $locale )
    		<meta http-equiv="Content-Language" content="$locale.language" />
    #end
    		$headContent
    		#googleAnalytics( $decoration.googleAnalyticsAccountId )
    	</head>
    	<body class="composite">
    		<a href="https://logging.apache.org/">
    			<img class="logo-left" src="$relativePath/images/ls-logo.jpg" alt="Apache logging services logo" />
    		</a>
    		<img class="logo-right" src="$relativePath/images/logo.jpg" alt="Apache log4j logo" />
    		<div class="clear"></div>
    
    		<div class="navbar">
    			<div class="navbar-inner">
    				<div class="container-fluid">
    					<a class="brand" href="$project.url">$project.name &trade;</a>
    					#links( $decoration.body.links )
    				</div>
    			</div>
    		</div>
    
    		<div class="container-fluid">
    			<table class="layout-table">
    				<tr>
    					<td class="sidebar">
    						<div class="well sidebar-nav">
    							#mainMenu( $decoration.body.menus )
    						</div>
    						<div id="poweredBy">
    							#poweredByLogo( $decoration.poweredBy )
    						</div>
    					</td>
    					<td class="content">
    						$bodyContent
    					</td>
    				</tr>
    			</table>
    		</div>
    
    		<div class="footer">
    			#set ( $currentYear = ${currentDate.year} + 1900 )
    				<p>Copyright &copy; ${project.inceptionYear}-${currentYear} <a class="external" href="$project.organization.url">${project.organization.name}</a>. All Rights Reserved.</p>
    				<p>Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, and the Apache Logging project logo are trademarks of The Apache Software Foundation.</p>
    				<p>Site powered by <a class="external" href="http://getbootstrap.com/">Twitter Bootstrap</a>. Icons from <a class="external" href="http://glyphicons.com/">Glyphicons Free</a>.</p>
    			</div>
    		</div>
    	</body>
    </html>
    �������������������logging-log4j2-log4j-2.4/src/site/site.xml����������������������������������������������������������0000664�0000000�0000000�00000035241�12577562624�0020367�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<!--
     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.
    
    -->
    <project name="Log4j"
             xmlns="http://maven.apache.org/DECORATION/1.4.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/DECORATION/1.4.0 http://maven.apache.org/xsd/decoration-1.4.0.xsd">
      <body>
        <links>
          <item name="Logging Wiki" href="http://wiki.apache.org/logging"/>
          <item name="Apache" href="http://www.apache.org/"/>
          <item name="Logging Services" href="http://logging.apache.org/"/>
          <item name="Sonar" href="https://analysis.apache.org/dashboard/index/org.apache.logging.log4j:log4j"/>
        </links>
    
        <menu name="Apache Log4j™ 2" inherit="top" img="icon-home">
          <item name="About" href="/index.html"/>
          <item name="Download" href="/download.html"/>
          <item name="Maven and Ivy" href="/maven-artifacts.html"/>
          <item name="Build" href="/build.html"/>
          <item name="Guidelines" href="/guidelines.html"/>
          <item name="Style Guide" href="/javastyle.html"/>
          <item name="Changelog" href="/changelog.html"/>
          <item name="Javadoc" href="/javadoc.html" collapse="true">
            <item name="Log4j 2 API" href="/log4j-api/apidocs/index.html" />
            <item name="Implementation" href="/log4j-core/apidocs/index.html" />
            <item name="JSP Tag Library" href="/log4j-taglib/apidocs/index.html" />
            <item name="JSP Tag Library (TLD Doc)" href="/log4j-taglib/tlddoc/index.html" />
          </item>
          <item name="Runtime Dependencies" href="/runtime-dependencies.html"/>
          <item name="FAQ" href="/faq.html"/>
          <item name="Articles" href="/articles.html"/>
        </menu>
    
        <menu name="Manual" inherit="top" img="icon-book">
          <item name="Introduction" href="/manual/index.html"/>
          <item name="Architecture" href="/manual/architecture.html"/>
          <item name="Log4j 1.x Migration" href="manual/migration.html"/>
    
          <item name="API" href="/manual/api.html" collapse="true">
            <item name="Flow Tracing" href="manual/flowtracing.html"/>
            <item name="Markers" href="manual/markers.html"/>
            <item name="Event Logging" href="/manual/eventlogging.html"/>
            <item name="Messages" href="/manual/messages.html"/>
            <item name="ThreadContext" href="/manual/thread-context.html"/>
          </item>
    
          <item name="Configuration" href="/manual/configuration.html" collapse="true">
            <item name="Automatic Configuration" href="/manual/configuration.html#AutomaticConfiguration"/>
            <item name="Additivity" href="/manual/configuration.html#Additivity"/>
            <item name="Automatic Reconfiguration" href="/manual/configuration.html#AutomaticReconfiguration"/>
            <item name="Chainsaw Support" href="/manual/configuration.html#ChainsawSupport"/>
            <item name="Configuration Syntax" href="/manual/configuration.html#ConfigurationSyntax" />
            <item name="XML Syntax" href="/manual/configuration.html#XML"/>
            <item name="JSON Syntax" href="/manual/configuration.html#JSON"/>
            <item name="Properties Syntax" href="/manual/configuration.html#Properties"/>
            <item name="Configuring Loggers" href="/manual/configuration.html#Loggers"/>
            <item name="Configuring Appenders" href="/manual/configuration.html#Appenders"/>
            <item name="Configuring Filters" href="/manual/configuration.html#Filters"/>
            <item name="Property Substitution" href="/manual/configuration.html#PropertySubstitution"/>
            <item name="XInclude" href="/manual/configuration.html#XInclude"/>
            <item name="Status Messages" href="/manual/configuration.html#StatusMessages"/>
            <item name="Unit Testing in Maven" href="/manual/configuration.html#UnitTestingInMaven"/>
            <item name="System Properties" href="/manual/configuration.html#SystemProperties"/>
          </item>
    
          <item name="Web Applications and JSPs" href="/manual/webapp.html" collapse="true">
            <item name="Servlet 3.0 and Newer" href="/manual/webapp.html#Servlet-3.0" />
            <item name="Servlet 2.5" href="/manual/webapp.html#Servlet-2.5" />
            <item name="Context Parameters" href="/manual/webapp.html#ContextParams" />
            <item name="Configuration Lookups" href="/manual/webapp.html#WebLookup" />
            <item name="JavaServer Pages Logging" href="/manual/webapp.html#JspLogging" />
            <item name="Asynchronous Requests" href="/manual/webapp.html#Async" />
          </item>
    
          <item name="Plugins" href="/manual/plugins.html" collapse="true">
            <item name="Core" href="/manual/plugins.html#Core"/>
            <item name="Converters" href="/manual/plugins.html#Converters"/>
            <item name="Key Providers" href="/manual/plugins.html#KeyProviders"/>
            <item name="Lookups" href="/manual/plugins.html#Lookups"/>
            <item name="Preloading" href="/manual/plugins.html#Plugin_Preloading"/>
          </item>
    
          <item name="Lookups" href="/manual/lookups.html" collapse="true">
            <item name="Context Map" href="/manual/lookups.html#ContextMapLookup"/>
            <item name="Date" href="/manual/lookups.html#DateLookup"/>
            <item name="Environment" href="/manual/lookups.html#EnvironmentLookup"/>
            <item name="Java" href="/manual/lookups.html#JavaLookup"/>
            <item name="JNDI" href="/manual/lookups.html#JndiLookup"/>
            <item name="JVM Arguments" href="/manual/lookups.html#JmxRuntimeInputArgumentsLookup"/>
            <item name="Log4j Config" href="/manual/lookups.html#Log4jConfigLookup"/>
            <item name="Main Arguments" href="/manual/lookups.html#AppMainArgsLookup"/>
            <item name="Map" href="/manual/lookups.html#MapLookup"/>
            <item name="Structured Data" href="/manual/lookups.html#StructuredDataLookup"/>
            <item name="System Properties" href="/manual/lookups.html#SystemPropertiesLookup"/>
            <item name="Web" href="/manual/lookups.html#WebLookup"/>
          </item>
    
          <item name="Appenders" href="/manual/appenders.html" collapse="true">
            <item name="Async" href="/manual/appenders.html#AsyncAppender"/>
            <item name="Console" href="/manual/appenders.html#ConsoleAppender"/>
            <item name="Failover" href="/manual/appenders.html#FailoverAppender"/>
            <item name="File" href="/manual/appenders.html#FileAppender"/>
            <item name="Flume" href="/manual/appenders.html#FlumeAppender"/>
            <item name="JDBC" href="/manual/appenders.html#JDBCAppender"/>
            <item name="JMS Queue" href="/manual/appenders.html#JMSQueueAppender"/>
            <item name="JMS Topic" href="/manual/appenders.html#JMSTopicAppender"/>
            <item name="JPA" href="/manual/appenders.html#JPAAppender"/>
            <item name="Memory Mapped File" href="/manual/appenders.html#MemoryMappedFileAppender"/>
            <item name="NoSQL" href="/manual/appenders.html#NoSQLAppender"/>
            <item name="Output Stream" href="/manual/appenders.html#OutputStreamAppender"/>
            <item name="Random Access File" href="/manual/appenders.html#RandomAccessFileAppender"/>
            <item name="Rewrite" href="/manual/appenders.html#RewriteAppender"/>
            <item name="Rolling File" href="/manual/appenders.html#RollingFileAppender"/>
            <item name="Rolling Random Access File" href="/manual/appenders.html#RollingRandomAccessFileAppender"/>
            <item name="Routing" href="/manual/appenders.html#RoutingAppender"/>
            <item name="SMTP" href="/manual/appenders.html#SMTPAppender"/>
            <item name="Socket" href="/manual/appenders.html#SocketAppender"/>
            <item name="Syslog" href="/manual/appenders.html#SyslogAppender"/>
            <item name="ZeroMQ" href="/manual/appenders.html#ZeroMQAppender"/>        
          </item>
    
          <item name="Layouts" href="/manual/layouts.html" collapse="true">
            <item name="HTML" href="/manual/layouts.html#HTMLLayout"/>
            <item name="JSON" href="/manual/layouts.html#JSONLayout"/>
            <item name="Pattern" href="/manual/layouts.html#PatternLayout"/>
            <item name="RFC-5424" href="/manual/layouts.html#RFC5424Layout"/>
            <item name="Serialized" href="/manual/layouts.html#SerializedLayout"/>
            <item name="Syslog" href="/manual/layouts.html#SyslogLayout"/>
            <item name="XML" href="/manual/layouts.html#XMLLayout"/>
            <item name="GELF" href="/manual/layouts.html#GELFLayout"/>
            <item name="Location Information" href="/manual/layouts.html#LocationInformation"/>
          </item>
    
          <item name="Filters" href="/manual/filters.html" collapse="true">
            <item name="Burst" href="/manual/filters.html#BurstFilter"/>
            <item name="Composite Filter" href="/manual/filters.html#CompositeFilter"/>
            <item name="Dynamic Threshold" href="/manual/filters.html#DynamicThresholdFilter"/>
            <item name="Map" href="/manual/filters.html#MapFilter"/>
            <item name="Marker" href="/manual/filters.html#MarkerFilter"/>
            <item name="Regex" href="/manual/filters.html#RegexFilter"/>
            <item name="Structured Data" href="/manual/filters.html#StructuredDataFilter"/>
            <item name="Thread Context Map" href="/manual/filters.html#ThreadContextMapFilter"/>
            <item name="Threshold" href="/manual/filters.html#ThresholdFilter"/>
            <item name="Time" href="/manual/filters.html#TimeFilter"/>
          </item>
    
          <item name="Async Loggers" href="/manual/async.html" collapse="true">
            <item name="Trade-offs" href="/manual/async.html#Trade-offs"/>
            <item name="All Loggers Async" href="/manual/async.html#AllAsync"/>
            <item name="Mixed Sync &amp; Async" href="/manual/async.html#MixedSync-Async"/>
            <item name="Location" href="/manual/async.html#Location"/>
            <item name="Performance" href="/manual/async.html#Performance"/>
            <item name="Under The Hood" href="/manual/async.html#UnderTheHood"/>
          </item>
    
          <item name="JMX" href="/manual/jmx.html"/>
          <item name="Logging Separation" href="/manual/logsep.html"/>
    
          <item name="Extending Log4j" href="/manual/extending.html" collapse="true">
            <item name="LoggerContextFactory" href="/manual/extending.html#LoggerContextFactory"/>
            <item name="ContextSelector" href="/manual/extending.html#ContextSelector"/>
            <item name="ConfigurationFactory" href="/manual/extending.html#ConfigurationFactory"/>
            <item name="LoggerConfig" href="/manual/extending.html#LoggerConfig"/>
            <item name="Lookups" href="/manual/extending.html#Lookups"/>
            <item name="Filters" href="/manual/extending.html#Filters"/>
            <item name="Appenders" href="/manual/extending.html#Appenders"/>
            <item name="Layouts" href="/manual/extending.html#Layouts"/>
            <item name="PatternConverters" href="/manual/extending.html#PatternConverters"/>
            <item name="Custom Plugins" href="/manual/extending.html#Custom_Plugins"/>
          </item>
    
          <item name="Extending Log4j Configuration" href="/manual/customconfig.html" collapse="true">
            <item name="ConfigurationBuilder API" href="/manual/customconfig.html#ConfigurationBuilder"/>
            <item name="Understanding ConfigurationFactory" href="/manual/customconfig.html#ConfigurationFactory"/>
            <item name="Example" href="/manual/customconfig.html#Example"/>
            <item name="Using Configurator" href="/manual/customconfig.html#Configurator"/>
            <item name="Config File and Code" href="/manual/customconfig.html#Hybrid"/>
            <item name="After Initialization" href="/manual/customconfig.html#AddingToCurrent"/>
          </item>
    
          <item name="Custom Log Levels" href="/manual/customloglevels.html" collapse="true">
            <item name="In Code" href="/manual/customloglevels.html#DefiningLevelsInCode"/>
            <item name="In Configuration" href="/manual/customloglevels.html#DefiningLevelsInConfiguration"/>
            <item name="Adding or Replacing Levels" href="/manual/customloglevels.html#AddingOrReplacingLevels"/>
            <item name="Custom Loggers" href="/manual/customloglevels.html#CustomLoggers"/>
            <item name="Custom Logger Example" href="/manual/customloglevels.html#ExampleUsage"/>
            <item name="Code Generation Tool" href="/manual/customloglevels.html#CodeGen"/>
          </item>
        </menu>
    
        <menu name="Components" inherit="top" img="icon-cog">
          <item name="API" href="log4j-api/index.html"/>
          <item name="Implementation" href="log4j-core/index.html"/>
          <item name="Commons Logging Bridge" href="log4j-jcl/index.html"/>
          <item name="Log4j 1.2 API" href="log4j-1.2-api/index.html"/>
          <item name="SLF4J Binding" href="log4j-slf4j-impl/index.html"/>
          <item name="JUL Adapter" href="log4j-jul/index.html"/>
          <item name="Log4j 2 to SLF4J Adapter" href="log4j-to-slf4j/index.html"/>
          <item name="Apache Flume Appender" href="log4j-flume-ng/index.html"/>
          <item name="Log4j Tag Library" href="log4j-taglib/index.html"/>
          <item name="Log4j JMX GUI" href="log4j-jmx-gui/index.html"/>
          <item name="Log4j Web Application Support" href="log4j-web/index.html"/>
          <item name="Log4j NoSQL support" href="log4j-nosql/index.html"/>
          <item name="Log4j IO Streams" href="log4j-iostreams/index.html"/>
          <item name="Log4j Liquibase Binding" href="log4j-liquibase/index.html"/>
        </menu>
    
        <menu name="Project Information" img="icon-info-sign">
          <item name="Dependencies" href="/dependencies.html" />
          <item name="Dependency Convergence" href="/dependency-convergence.html" />
          <item name="Dependency Management" href="/dependency-management.html" />
          <item name="Project Team" href="/team-list.html" />
          <item name="Mailing Lists" href="/mail-lists.html" />
          <item name="Issue Tracking" href="/issue-tracking.html" />
          <item name="Project License" href="/license.html" />
          <item name="Source Repository" href="/source-repository.html" />
          <item name="Project Summary" href="/project-summary.html" />
        </menu>
    
        <menu name="Project Reports" img="icon-cog">
          <item name="Changes Report" href="/changes-report.html" />
          <item name="JIRA Report" href="/jira-report.html" />
          <item name="Surefire Report" href="/surefire-report.html" />
          <item name="RAT Report" href="/rat-report.html" />
        </menu>
      </body>
    </project>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/�������������������������������������������������������������0000775�0000000�0000000�00000000000�12577562624�0017631�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/articles.xml�������������������������������������������������0000664�0000000�0000000�00000010777�12577562624�0022175�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>
      <properties>
        <title>Articles</title>
        <author email="ggregory@apache.org">Gary Gregory</author>
      </properties>
    
      <body>
        <section name="Articles">
          <p>
            A collection of articles about Log4j 2.
          </p>
          <a name="English"/>
          <subsection name="English">
          <ul>
            <li>
              <a href="http://www.infoq.com/news/2015/09/interview-log4j-pmc">The Transition to a New Log4j: a Q&amp;A with Log4j's Project Management Committee</a>
              (September 8, 2015)
            </li>
            <li>
              <a href="http://www.infoq.com/news/2015/08/log4j-version-1-reaches-eol">Log4j Version 1 Reaches End of Life</a>
              (August 26, 2015)
            </li>
            <li>
              <a href="https://blogs.apache.org/foundation/entry/apache_logging_services_project_announces">Apache Logging Services Project Announces Log4j 1 End-Of-Life; Recommends Upgrade to Log4j 2</a>
              (August 6, 2015)
            </li>
            <li>
              <a href="https://www.innoq.com/en/blog/per-request-debugging-with-log4j2/">Per request debugging with Log4j 2 filters</a>
              (May 8, 2015)
            </li>
            <li>
              <a
                href="http://www.journaldev.com/7128/apache-log4j-2-tutorial-configuration-levels-appenders-lookup-layouts-and-filters-example">Apache Log4j 2 Tutorial – Configuration, Levels, Appenders, Lookup, Layouts and
                Filters Example</a>
              (March 16, 2015)
            </li>
            <li>
              <a href="http://blogs.mulesoft.com/dev/mule-dev/mule-3-6-asynchronous-logging/">Disrupting your Asynchronous Loggers</a>
              (March 5, 2015)
            </li>
            <li>
              <a href="http://andrew-flower.com/blog/Create_Custom_Log4j_Plugins">Extending Log4j2 - Creating Custom Log4j2 Plugins</a>
              (February 20, 2015)
            </li>
            <li>
              <a href="http://blogs.mulesoft.com/dev/mule-dev/mule-3-6-asynchronous-logging/">Asynchronous Logging in Mule 3.6</a>
              (January 20, 2015)
            </li>
            <li>
              <a href="http://www.infoq.com/news/2014/07/apache-log4j2">Apache Log4j 2.0 - Worth the Upgrade?</a>
              (Jul 31, 2014)
            </li>
            <li>
              <a href="http://tech.finn.no/2014/07/01/log4j2-in-production-making-it-fly/">Log4j 2 in Production – Making it Fly</a>
              (July 2, 2014)
            </li>
            <li>
              <a href="http://www.grobmeier.de/log4j-2-performance-close-to-insane-20072013.html">Log4j 2: Performance Close to Insane</a>
              (July 20, 2013)
            </li>
            <li>
              <a href="http://www.grobmeier.de/the-new-log4j-2-0-05122012.html">The New Log4j 2.0</a>
              (December 5, 2012)
            </li>
          </ul>
          </subsection>
    
          <a name="German"/>
          <subsection name="German">
          <ul>
            <li>
              <a
                href="https://www.innoq.com/en/articles/2015/01/logging-konsolidieren-log4j2/">Logging konsolidieren und Performance gewinnen</a>
              (January 23, 2015)
            </li>
          </ul>
          </subsection>
    
          <a name="Japanese"/>
          <subsection name="Japanese">
          <ul>
            <li>
              <a
                href="http://d.hatena.ne.jp/Kazuhira/20140628/1403959552">Log4j2を試してみる</a>
              (June 28, 2014)
            </li>
          </ul>
          </subsection>
    
          <a name="Korean"/>
          <subsection name="Korean">
          <ul>
            <li>
              <a
                href="http://www.egovframe.go.kr/wiki/doku.php?id=egovframework:rte3:fdl:%EC%84%A4%EC%A0%95_%ED%8C%8C%EC%9D%BC%EC%9D%84_%EC%82%AC%EC%9A%A9%ED%95%98%EB%8A%94_%EB%B0%A9%EB%B2%95">Log4j 2 환경설정 [설정 파일 사용 시]</a>
              (May 14, 2014)
            </li>
          </ul>
          </subsection>
        </section>
    
      </body>
    </document>
    �logging-log4j2-log4j-2.4/src/site/xdoc/build.xml.vm�������������������������������������������������0000664�0000000�0000000�00000006070�12577562624�0022076�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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>Building and Installing Log4j</title>
    	</properties>
    
    	<body>
    		<section name="Building and Installing Log4j">
    
          <p class="text-info">
            <i>The information below is for developers who want to modify Log4j or
            contribute to Log4j. If your goal is to add logging to your application
            you don't need to build from the source code,
            you can <a href="download.html">download</a> the pre-built binaries instead.
            </i>
          </p>
          <p>
            Log4j 2 is hosted in the Apache Software Foundation's Git repository. Details on obtaining the
            most current source code can be found at
            <a href="./source-repository.html">Log4j Source Repository</a>. The source from the latest release may be
            obtained by downloading it using the instructions at <a href="./download.html">Log4j Downloads</a>.
          </p>
          <p>
            Log4j 2.x uses Maven 3 as its build tool. To build and install Log4j in your local Maven cache, from
            the root directory run: <kbd>mvn install</kbd>
          </p>
          <p class="bg-warning">Note that in order to build the website, you need to use
              <a href="http://maven.apache.org/download.cgi#Maven_3.0.5">Maven 3.0.5</a> due to plugin compatibility
              issues as documented in
              <a href="http://jira.codehaus.org/browse/MSITE-695">MSITE-695</a>.
          </p>
          <p>
            Then to build the full site, you must use a local staging directory:
          </p>
          <pre>mvn site
    [Windows] mvn site:stage-deploy -DstagingSiteURL=file:///%HOME%/log4j
    [Unix] mvn site:stage-deploy -DstagingSiteURL=file:///${dollar}HOME/log4j</pre>
          <p>
              To rebuild only what's changed and execute the tests, run: <kbd>mvn test</kbd>
          </p>
          <p>
              To rebuild from scratch, add "clean", for example: <kbd>mvn clean test</kbd>
          </p>
    
        </section>
    	<section name="Releasing Log4j">
          <p>
    	    Please see the wiki <a href="https://wiki.apache.org/logging/Log4j2ReleaseGuide">Log4j2ReleaseGuide</a>.
          </p>
        </section>
    	</body>
    </document>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/changelog.xml������������������������������������������������0000664�0000000�0000000�00000003701�12577562624�0022303�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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>Releases</title>
    	</properties>
    
    	<body>
    		<section name="Release Change Logs">
    
    				<p><a href="jira-report.html#a1.0-alpha1">JIRA change log</a></p>
            <p><a href="changes-report.html#a1.0-alpha1">Manual change log</a></p>
    
    				<p>Apache Log4j 2 is not compatible with the previous versions. Please have the following in mind
    				when upgrading to Log4j 2 in your project:</p>
    
    				<ul>
    					<li>Log4j 2.4 and greater requires Java 7, versions 2.0-alpha1 to 2.3 required Java 6.</li>
              <li>The XML configuration has been simplified and is not compatible with Log4j 1.x</li>
              <li>Configuration via property files is not supported.</li>
              <li>Configuration via JSON or YAML is supported.</li>
              <li>Although Log4j 2 is not directly compatible with Log4j 1.x a compatibility bridge
                has been provided to reduce the need to make coding changes.</li>
    				</ul>
    
    		</section>
    	</body>
    </document>
    ���������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/faq.xml������������������������������������������������������0000664�0000000�0000000�00000030232�12577562624�0021122�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>
        <properties>
            <title>Frequently Asked Questions</title>
    		<author email="remkop@yahoo.com">Remko Popma</author>
        </properties>
    
        <body>
          <section name="Frequently Asked Questions">
          <ul>
          <li><a href="#which_jars">Which JAR files do I need?</a></li>
          <li><a href="#config_location">How do I specify the configuration file location?</a></li>
          <li><a href="#config_from_code">How do I configure log4j2 in code without a configuration file?</a></li>
          <li><a href="#reconfig_from_code">How do I reconfigure log4j2 in code with a specific configuration file?</a></li>
          <li><a href="#set_logger_level_from_code">How do I change a logger's level in code?</a></li>
          <li><a href="#shutdown">How do I shut down log4j2 in code?</a></li>
          <li><a href="#config_sep_appender_level">How do I send log messages with different levels to different appenders?</a></li>
          <li><a href="#troubleshooting">How do I debug my configuration?</a></li>
          <li><a href="#separate_log_files">How do I dynamically write to separate log files?</a></li>
          <li><a href="#reconfig_level_from_code">How do I set a logger's level programmatically?</a></li>      
          <!--
          <li><a href="#custom_plugin">How do I get log4j2 to recognize my custom plugin?</a></li>
          -->
          </ul>
          <subsection>
    		<a name="which_jars" />
            <h4>Which JAR files do I need?</h4>
            <p>You need at least the log4j-api-2.1 and the log4j-core-2.1 jar files.</p>
            <p>The other jars are necessary if your application calls the API
            of another logging framework and you want to route logging calls to the Log4j 2 implementation.</p>
            <p><img src="images/whichjar-2.1.png" alt="Diagram showing which JARs correspond to which systems" /></p>
            <p>You can use the log4j-to-slf4j adapter jar when your application calls the Log4j 2 API and you
            want to route logging calls to a SLF4J implementation.</p>
            <p><img src="images/whichjar-slf4j-2.1.png" alt="Diagram showing the dependency flow to use Log4j 2 API with SLF4J" /></p>
            <p>Some of the Log4j components have features with optional dependencies.
              The component page will have more detail.
              For example, the <a href="log4j-core/index.html">log4j-core component page</a>
              has an outline of which log4j-core features have external dependencies.</p>
            
    		<a name="config_location" />
            <h4>How do I specify the configuration file location?</h4>
            <p>By default, Log4j looks for a configuration file named <b>log4j2.xml</b> (not log4j.xml) in the classpath.
            </p><p>
            You can also specify the full path of the configuration file with this system property:<br />
            <code>-Dlog4j.configurationFile=path/to/log4j2.xml</code></p>
    
    		<a name="config_from_code" />
            <h4>How do I configure log4j2 in code without a configuration file?</h4>
            <p>You could use the static method <code>#initialize(String contextName, ClassLoader loader, String configLocation)</code>
             (see
             <a href="log4j-core/xref/org/apache/logging/log4j/core/config/Configurator.html">source code</a>)
              in <code>org.apache.logging.log4j.core.config.Configurator</code>.
             (You can pass null for the class loader.)
             Be aware that this class is not part of the public API so your code may break with any minor release.</p>
    
            <a name="reconfig_from_code" />
            <h4>How do I reconfigure log4j2 in code with a specific configuration file?</h4>
            <p>See the below example.
             Be aware that this LoggerContext class is not part of the public API so your code may break with any minor release.</p>
            <pre class="prettyprint linenums">// import org.apache.logging.log4j.core.LoggerContext;
    
    LoggerContext context = (org.apache.logging.log4j.core.LoggerContext) LogManager.getContext(false);
    File file = new File("path/to/a/different/log4j2.xml");
    
    // this will force a reconfiguration
    context.setConfigLocation(file.toURI());
    </pre>
    
            <a name="set_logger_level_from_code" />
            <h4>How do I change a logger's level in code?</h4>
            <p>See the below example.
             Be aware that these classes are not part of the public API so your code may break with any minor release.</p>
            <pre class="prettyprint linenums">// import org.apache.logging.log4j.core.LoggerContext;
    // import org.apache.logging.log4j.core.config.Configuration;
    // import org.apache.logging.log4j.core.config.LoggerConfig;
    
    LoggerContext context = (LoggerContext) LogManager.getContext(false);
    Configuration config = context.getConfiguration();
    LoggerConfig rootConfig = config.getLoggerConfig(LogManager.ROOT_LOGGER_NAME);
    rootConfig.setLevel(Level.DEBUG);
    
    // You could also specify the actual logger name as below
    // and it will return the LoggerConfig used by the Logger.
    LoggerConfig loggerConfig = config.getLoggerConfig("com.apache.test");
    loggerConfig.setLevel(Level.TRACE);
    
    // This causes all Loggers to refetch information from their LoggerConfig.
    context.updateLoggers();
    </pre>
    
            <a name="shutdown" />
            <h4>How do I shut down log4j2 in code?</h4>
            <p>Normally there is no need to do this manually.
             Each LoggerContext registers a shutdown hook that takes care of releasing resources
             when the JVM exits (unless system property <code>log4j.shutdownHookEnabled</code>
             is set to <code>false</code>).        
             Web applications should include the log4j-web
             module in their classpath which disables the shutdown hook but instead
             cleans up log4j resources when the web application is stopped.</p>
            <p>However, if you need to manually shut down log4j, you can do so
            as in the below example.
             Be aware that these classes are not part of the public API so your code may break with any minor release.</p>
            <pre class="prettyprint linenums">// import org.apache.logging.log4j.core.LoggerContext;
    // import org.apache.logging.log4j.core.config.Configurator;
    
    // get the current context
    LoggerContext context = (LoggerContext) LogManager.getContext();
    Configurator.shutdown(context);</pre>
    
    		<a name="config_sep_appender_level" />
            <h4>How do I send log messages with different levels to different appenders?</h4>
    		You don't need to declare separate loggers to achieve this.
    		You can set the logging level on the <code>AppenderRef</code> element.
            <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
      <Appenders>
        <File name="file" fileName="app.log">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
          </PatternLayout>
        </File>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="trace">
          <AppenderRef ref="file" level="DEBUG"/>
          <AppenderRef ref="STDOUT" level="INFO"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
    		<a name="troubleshooting" />
            <h4>How do I debug my configuration?</h4>
            <p>First, make sure you have <a href="#which_jars">the right jar files</a> on your classpath. 
            You need at least log4j-api and log4j-core.</p>
            <p>Next, check the name of your configuration file. By default, log4j2 will look
            for a configuration file named <code>log4j2.xml</code> on the classpath. Note the "2" in the file name!
            (See the <a href="manual/configuration.html#AutomaticConfiguration">configuration manual page</a>
            for more details.)</p>
            <p>If the configuration file is found correctly, log4j2 internal status logging can be controlled by
            setting <code>&lt;Configuration status="trace"&gt;</code> in the configuration file.
            This will display detailed log4j2-internal
            log statements on the console about what happens during the configuration process.
            This may be useful to trouble-shoot configuration issues.
            By default the status logger level is WARN, so you only see notifications when there is a problem.
            </p>
            <p>If the configuration file is not found correctly, you can still enable 
            log4j2 internal status logging by setting system property 
              <code>-Dorg.apache.logging.log4j.simplelog.StatusLogger.level=TRACE</code>.</p>
    
    		<a name="separate_log_files" />
            <h4>How do I dynamically write to separate log files?</h4>
    		<p>
    		Look at the
    		<a href="http://logging.apache.org/log4j/2.x/manual/appenders.html#RoutingAppender">RoutingAppender</a>.
    		You can define multiple routes in the configuration,
    		and put values in the <code>ThreadContext</code> map that determine
    		which log file subsequent events in this thread get logged to.</p>
    		<p>
    		You can use the <code>ThreadContext</code> map value to determine the log file name.
    		</p>
            <pre class="prettyprint linenums"><![CDATA[<Routing name="Routing">
      <Routes pattern="$${ctx:ROUTINGKEY}">
    
        <!-- This route is chosen if ThreadContext has value 'special' for key ROUTINGKEY. -->
        <Route key="special">
          <RollingFile name="Rolling-${ctx:ROUTINGKEY}" fileName="logs/special-${ctx:ROUTINGKEY}.log"
    	filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-special-%d{yyyy-MM-dd}-%i.log.gz">
    	<PatternLayout>
    	  <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
    	</PatternLayout>
    	<Policies>
    	  <TimeBasedTriggeringPolicy interval="6" modulate="true" />
              <SizeBasedTriggeringPolicy size="10 MB" />
    	</Policies>
          </RollingFile>
        </Route>
    
        <!-- This route is chosen if ThreadContext has no value for key ROUTINGKEY. -->
        <Route key="$${ctx:ROUTINGKEY}">
          <RollingFile name="Rolling-default" fileName="logs/default.log"
    	filePattern="./logs/${date:yyyy-MM}/default-%d{yyyy-MM-dd}-%i.log.gz">
            <PatternLayout>
    	  <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
            </PatternLayout>
            <Policies>
              <TimeBasedTriggeringPolicy interval="6" modulate="true" />
              <SizeBasedTriggeringPolicy size="10 MB" />
            </Policies>
          </RollingFile>
        </Route>
    
        <!-- This route is chosen if ThreadContext has a value for ROUTINGKEY
             (other than the value 'special' which had its own route above).
             The value dynamically determines the name of the log file. -->
        <Route>
          <RollingFile name="Rolling-${ctx:ROUTINGKEY}" fileName="logs/other-${ctx:ROUTINGKEY}.log"
    	filePattern="./logs/${date:yyyy-MM}/${ctx:ROUTINGKEY}-other-%d{yyyy-MM-dd}-%i.log.gz">
    	<PatternLayout>
    	  <pattern>%d{ISO8601} [%t] %p %c{3} - %m%n</pattern>
    	</PatternLayout>
    	<Policies>
    	  <TimeBasedTriggeringPolicy interval="6" modulate="true" />
    	  <SizeBasedTriggeringPolicy size="10 MB" />
    	</Policies>
          </RollingFile>
        </Route>
      </Routes>
    </Routing>]]></pre>
    
            <a name="reconfig_level_from_code" />
            <h4>How do I set a logger's level programmatically?</h4>
            <p>You can set a logger's level with the class Configurator from Core module.
             Be aware that the Configuration class is not part of the public API.</p>
            <pre class="prettyprint linenums">// org.apache.logging.log4j.core.config.Configurator;
    
    Configurator.setLevel("com.example.Foo", Level.DEBUG);
    
    // You can also set the root logger:
    Configurator.setRootLevel(Level.DEBUG);
    </pre>
    
            <!--
    		<a name="custom_plugin" />
            <h4>How do I get log4j2 to recognize my custom plugin?</h4>
            -->
            </subsection>
          </section>
    
        </body>
    </document>
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/guidelines.xml�����������������������������������������������0000664�0000000�0000000�00000055317�12577562624�0022516�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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>Project Guidelines</title>
      </properties>
    
      <body>
        <section name="Apache Log4j Project Guidelines">
    
          <p>This document defines the guidelines for the <a href="http://logging.apache.org/log4j/2.x">Apache Log4j
            Project</a>. It includes definitions of how conflict
            is resolved by voting, who is able to vote, the procedures to follow
            for proposing and making changes as well as guidelines for changing code.</p>
          <p>The objective here is to avoid unnecessary conflict over changes and
            continue to produce a quality system in a timely manner. Not all conflict
            can be avoided, but at least we can agree on the procedures for conflict to
            be resolved.</p>
          <a name="people-places-and-things"/>
          <subsection name="People, Places, and Things">
          <dl>
            <dt><strong>Apache Logging Project Management Committee</strong></dt>
            <dd>The group of volunteers who are responsible for managing the Apache
              Logging Projects, including Log4j. This includes deciding what is distributed as
              products of the Apache Logging Project, maintaining the Project's
              shared resources, speaking on behalf of the Project, resolving license
              disputes regarding Apache products, nominating new PMC members or
              committers, and establishing these guidelines.</dd>
          </dl>
          <p>Membership in the Apache Logging PMC is by invitation only and must be approved by
            consensus of the active Logging PMC members. A PMC member is considered
            inactive by their own declaration or by not contributing in any form to the
            project for over six months. An inactive member can become active again by
            reversing whichever condition made them inactive ( <em>i.e.</em> , by reversing
            their earlier declaration or by once again contributing toward the
            project's work). Membership can be revoked by a unanimous vote of all the
            active PMC members other than the member in question.</p>
          <dl>
            <dt><strong>Apache Logging Committers</strong></dt>
            <dd>The group of volunteers who are responsible for the technical aspects
              of the Apache Logging Projects. This group has write access to the
              appropriate source repositories and these volunteers may cast binding
              votes on any technical discussion. Although a committer usually joins due to
              their activity on one of the Logging projects, they will have commit access to
              all Logging projects.</dd>
          </dl>
          <p>Membership as a Committer is by invitation only and must be approved by
            consensus of the active Logging PMC members. A Committer is considered
            inactive by their own declaration or by not contributing in any form to the
            project for over six months. An inactive member can become active again by
            reversing whichever condition made them inactive ( <em>i.e.</em> , by reversing
            their earlier declaration or by once again contributing toward the
            project's work). Membership can be revoked by a unanimous vote of all the
            active PMC members (except the member in question if they are a PMC
            member).</p>
          <dl>
            <dt><strong>Log4j Developers</strong></dt>
            <dd>All of the volunteers who are contributing time, code, documentation,
              or resources to the Log4j Project. A developer that makes sustained,
              welcome contributions to the project for over six months is usually
              invited to become a Committer, though the exact timing of such
              invitations depends on many factors.</dd>
            <dt><strong>mailing list</strong></dt>
            <dd>The Log4j developers' primary mailing list for discussion of issues
              and changes related to the project ( <em>log4j-dev@logging.apache.org</em> ).
              Subscription to the list is open, but only subscribers can post
              directly to the list.</dd>
            <dt><strong>private list</strong></dt>
            <dd>The Logging PMC's private mailing list for discussion of issues that
              are inappropriate for public discussion, such as legal, personal, or
              security issues prior to a published fix. Subscription to the list is
              only open (actually: mandatory) to Apache Logging's Project Management
              Committee.</dd>
            <dt><strong>Git</strong></dt>
            <dd>All of the Apache products are maintained in information
              repositories using either Subversion or Git; Log4j uses <a href="source-repository.html">Git</a>. Only some of the
              Apache developers have write access to the Apache Logging repositories; everyone
              has <a href="https://git-wip-us.apache.org/repos/asf?p=logging-log4j2.git;a=summary">read access</a>.</dd>
          </dl>
          </subsection>
          <a name="issues"/>
          <subsection name="Issue Management">
          <p>The Log4j project uses the <a href="https://issues.apache.org/jira/browse/LOG4J2">Jira</a> bug tracking
            system hosted and maintained by the Apache Software Foundation for tracking bugs and enhancements. The
            project roadmap may be maintained in JIRA through its RoadMap feature and through the use of
            Story or Epic issues.</p>
          <p>Many issues will be encountered by the project, each resulting in zero or
            more proposed action items. Issues should be raised on the mailing list as
            soon as they are identified. Action items <strong>must</strong> be raised on the mailing
            list and added to JIRA using the appropriate issue type. All action items may be voted
            on, but not all of them will require a formal vote.</p>
          </subsection>
          <a name="voting"/>
          <subsection name="Voting">
          <p>Any of the Log4j Developers may vote on any issue or action item. However,
            the only binding votes are those cast by active members of the Apache Logging
            PMC; if the vote is about a change to source code or documentation, the
            primary author of what is being changed may also cast a binding vote on
            that issue. All other votes are non-binding. All developers are encouraged
            to participate in decisions, but the decision itself is made by those who
            have been long-time contributors to the project. In other words, the Apache
            Log4j Project is a minimum-threshold meritocracy.</p>
          <p>The act of voting carries certain obligations -- voting members are not
            only stating their opinion, they are agreeing to help do the work of the
            Log4j Project. Since we are all volunteers, members often become inactive
            for periods of time in order to take care of their "real jobs" or devote
            more time to other projects. It is therefore unlikely that the entire group
            membership will vote on every issue. To account for this, all voting
            decisions are based on a minimum quorum.</p>
          <p>Each vote can be made in one of three flavors:</p>
          <dl>
            <dt><strong>+1</strong></dt>
            <dd>Yes, agree, or the action should be performed. On some issues, this
              vote is only binding if the voter has tested the action on their own
              system(s).</dd>
            <dt><strong>±0</strong></dt>
            <dd>Abstain, no opinion, or I am happy to let the other group members
              decide this issue. An abstention may have detrimental effects if too
              many people abstain.</dd>
            <dt><strong>-1</strong></dt>
            <dd>No. On issues where consensus is required, this vote counts as a
              <strong>veto</strong>. All vetoes must include an explanation of why the veto is
              appropriate. A veto with no explanation is void. No veto can be
              overruled. If you disagree with the veto, you should lobby the person
              who cast the veto. Voters intending to veto an action item should make
              their opinions known to the group immediately, so that the problem can
              be remedied as early as possible.</dd>
          </dl>
          <p>An action item requiring <em>consensus approval</em> must receive at least <strong>3
            binding +1</strong> votes and <strong>no vetoes</strong>. An action item requiring <em>majority
            approval</em> must receive at least <strong>3 binding +1</strong> votes and more <strong>+1</strong>
            votes than <strong>-1</strong> votes ( <em>i.e.</em> , a majority with a minimum quorum of
            three positive votes). All other action items are considered to have <em>lazy
              approval</em> until someone votes <strong>-1</strong> , after which point they are decided
            by either consensus or a majority vote, depending upon the type of action
            item.</p>
          <p>When appropriate, votes should be tallied in the JIRA issue. All votes must be either sent to
            the mailing list or added directly to the JIRA issue.</p>
          </subsection>
          <a name="types-of-action-items"/>
          <subsection name="Types of Action Items">
          <dl>
            <dt><strong>Long Term Plans</strong></dt>
            <dd>Long term plans are simply announcements that group members are
              working on particular issues related to the Log4j software. These are
              not voted on, but group members who do not agree with a particular
              plan, or think an alternate plan would be better, are obligated to
              inform the group of their feelings. In general, it is always better to
              hear about alternate plans <strong>prior</strong> to spending time on less adequate
              solutions.</dd>
            <dt><strong>Short Term Plans</strong></dt>
            <dd>Short term plans are announcements that a developer is working on a
              particular set of documentation or code files, with the implication
              that other developers should avoid them or try to coordinate their
              changes. This is a good way to proactively avoid conflict and possible
              duplication of work.</dd>
            <dt><strong>Release Plan</strong></dt>
            <dd>A release plan is used to keep all the developers aware of when a
              release is desired, who will be the release manager, when the
              repository will be frozen in order to create the release, and assorted
              other trivia to keep us from tripping over ourselves during the final
              moments. Lazy majority (at least 3 x +1 and more +1 than -1) decides
              each issue in the release plan.</dd>
            <dt><strong>Release Testing</strong></dt>
            <dd>After a new release is built it must be tested before being released to the public.
              Majority approval is required before the distribution can be publicly released.</dd>
            <dt><strong>Showstoppers/Blockers</strong></dt>
            <dd>Showstoppers are issues that require a fix be in place before the next
              public release. They are listed in Jira in order to focus
              special attention on the problem. An issue becomes a showstopper when
              it is listed as such in Jira and remains so by lazy consensus.</dd>
          </dl>
          <p>All product changes to the currently active repository are subject to lazy
            consensus. All product changes to a prior-branch (old version) repository
            require consensus before the change is committed.</p>
          </subsection>
          <a name="when-to-commit-a-change"/>
          <subsection name="When to Commit a Change">
          <p>Ideas must be review-then-commit; patches can be commit-then-review. With a
            commit-then-review process, we trust that the developer doing the commit
            has a high degree of confidence in the change. Doubtful changes, new
            features, and large-scale overhauls need to be discussed before being
            committed to a repository. Any change that affects the semantics of
            arguments to configurable directives, significantly adds to the runtime
            size of the program, or changes the semantics of an existing API function
            must receive consensus approval on the mailing list before being committed.</p>
          <p>Each developer is responsible for notifying the mailing list and adding an
            action item to Jira when they have an idea for a new feature or major
            change to propose for the product. The distributed nature of the Log4j
            project requires an advance notice of 48 hours in order to properly review
            a major change -- consensus approval of either the concept or a specific
            patch is required before the change can be committed. Note that a member
            might veto the concept (with an adequate explanation), but later rescind
            that veto if a specific patch satisfies their objections. No advance notice
            is required to commit singular bug fixes.</p>
          <p>Related changes should be committed as a group, or very closely together.
            Half-completed projects should not be committed unless doing so is
            necessary to pass the baton to another developer who has agreed to complete
            the project in short order. All code changes must be successfully compiled
            and unit tests pass on the developer's platform before being committed.</p>
          <p>The current source code tree should be capable of complete compilation at
            all times. However, it is sometimes impossible for a developer on one
            platform to avoid breaking some other platform when a change is committed,
            particularly when completing the change requires access to a special
            development tool on that other platform. If it is anticipated that a given
            change will break some other platform, the committer must indicate that in
            the commit log.</p>
          <p>The committer is responsible for the quality of any third-party code or
            documentation they commit to the repository. All software committed to the
            repository must be covered by the Apache LICENSE or contain a copyright and
            license that allows redistribution under the same conditions as the Apache
            LICENSE.</p>
          <p>A committed change must be reversed if it is vetoed by one of the voting
            members and the veto conditions cannot be immediately satisfied by the
            equivalent of a "bug fix" commit. The veto must be rescinded before the
            change can be included in any public release.</p>
          </subsection>
          <a name="changelogs"/>
          <subsection name="changes.xml and Git logs">
          <p>Many code changes should be noted in the changes.xml file, and all should be
            documented in Git commit messages. Often the text of the Git
            log and the changes.xml entry are the same, but the distinct requirements
            sometimes result in different information.</p>
          <h3 id="subversion-log">Git log</h3>
          <p>The Git commit log message contains any information needed by</p>
          <ul>
            <li>
              <p>fellow developers or other people researching source code changes/fixes</p>
            </li>
            <li>
              <p>end users (at least point out what the implications are for end users; it
                doesn't have to be in the most user friendly wording)</p>
            </li>
          </ul>
          <p>If the code change was provided by a non-committer, attribute it using
            Submitted-by. If the change was committed verbatim, identify the
            committer(s) who reviewed it with Reviewed-by. If the change was committed
            with modifications, use the appropriate wording to document that, perhaps
            "committed with changes" if the person making the commit made the changes,
            or "committed with contributions from xxxx" if others made contributions to
            the code committed.</p>
          <p>Example log message:</p>
            <pre><![CDATA[
    LOG4J2-9999
    Check the return code from parsing the content length, to avoid a
    crash if requests contain an invalid content length.
    Submitted by: Jane Doe <janedoe example.com>
    Reviewed by: susiecommitter
            ]]></pre>
          <h3 id="changes">changes.xml</h3>
          <p>changes.xml is the subset of the information that end users need to see when
            they upgrade from one release to the next:</p>
          <ul>
            <li>
              <p>what can I now do that I couldn't do before</p>
            </li>
            <li>
              <p>what problems that we anticipate a user could have suffered from are now
                fixed</p>
            </li>
            <li>
              <p>all security fixes included, with CVE number. (If not available at the
                time of the commit, add later.)</p>
            </li>
          </ul>
          <p>All entries in changes.xml should include the appropriate Jira issue number and should
            credit contributions made by non-committers by referencing them in the due-to attribute
            even if modifications needed to be made to the contribution.</p>
          <p>The attribution for the change is anyone responsible for the code changes.</p>
          </subsection>
          <a name="committing-security-fixes"/>
          <subsection name="Committing Security Fixes">
          <p>Open source projects, ASF or otherwise, have varying procedures for
            commits of vulnerability fixes.  One important aspect of these procedures
            is whether or not fixes to vulnerabilities can be committed to a
            repository with commit logs and possibly CHANGES entries which
            purposefully obscure the vulnerability and omit any available
            vulnerability tracking information.  The Apache HTTP Server project has
            decided that it is in the best interest of our users that the initial
            commit of such code changes to any branch will provide the best
            description available at that time as well as any available tracking
            information such as CVE number.  Committing of the fix will be delayed
            until the project determines that all of the information about the issue
            can be shared.</p>
          <p>In some cases there are very real benefits to sharing code early even if
            full information about the issue cannot, including the potential for
            broader review, testing, and distribution of the fix. This is outweighed
            by the concern that sharing only the code changes allows skilled analysts
            to determine the impact and exploit mechanisms but does not allow the
            general user community to determine if preventative measures should be
            taken.</p>
          <p>If a vulnerability is partially disclosed by committing a fix before the
            bug is determined to be exploitable, the httpd security team will decide
            on a case by case basis when to document the security implications and
            tracking number.</p>
          </subsection>
          <a name="patch"/>
          <subsection name="Patch Format">
          <p>When a specific change to the software is proposed for discussion or voting
            on the mailing list, it should be presented in the form of input to the
            patch command. When sent to the mailing list, the message should contain a
            Subject beginning with <code>[PATCH]</code> and a distinctive one-line summary
            corresponding to the action item for that patch. Afterwords, the patch
            summary in the STATUS file should be updated to point to the Message-ID of
            that message.</p>
          <p>The patch should be created by using the <kbd>diff -u</kbd> command from
            the original software file(s) to the modified software file(s). E.g.,
            <code>diff -u http_main.c.orig http_main.c &gt;&gt; patchfile.txt</code>
            or
            <code>svn diff http_main.c &gt;&gt; patchfile.txt</code>
            All patches necessary to address an action item should be concatenated
            within a single patch message. If later modification of the patch proves
            necessary, the entire new patch should be posted and not just the
            difference between two patches. The STATUS file entry should then be
            updated to point to the new patch message.</p>
          <p>The completed patchfile should produce no errors or prompts when the
            command,
            <code>patch -s &lt; patchfile</code>
            is issued in the target repository.</p>
          </subsection>
          <a name="teamwork"/>
          <subsection name="Teamwork">
            <p>Open source projects function best when everyone is aware of the "rules of the road" and abide by them.</p>
            <ol>
              <li>Error on the side of caution. If you don’t understand it, don’t touch it and ask on the list. If you think you
                understand it read it again or ask until you are sure you do. Nobody will blame you for asking questions.</li>
              <li>Don’t break the build - if there is the slightest chance the change you are making could cause unit test
                failures, run all unit tests.  Better yet, get in the habit of always running the unit tests before doing the commit.</li>
              <li>If the build breaks and you have made recent changes then assume you broke it and try to fix it. Although it
                might not have been something you did it will make others feel a lot better than having to fix the mistake for
                you. Everyone makes mistakes. Taking responsibility for them is a good thing.</li>
              <li>Don’t change things to match your personal preference - the project has <a href="javastyle.html">style guidelines</a>
                that are validated with checkstyle, PMD, and other tools. If you aren’t fixing a bug,
                fixing a problem identified by the tools, or fixing something specifically called out in these guidelines then
                start a discussion to see if the change is something the project wants before starting to work on it. We try to
                discuss things first and then implement the consensus reached in the discussion.</li>
              <li>Along the same lines, do not commit automatic changes made by your IDE without reviewing them. There
                are a few places in the code that cannot conform to style guidelines without causing errors in some environments.
                These are clearly marked and must be left as is.</li>
            </ol>
          </subsection>
        </section>
      </body>
    </document>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/index.xml����������������������������������������������������0000664�0000000�0000000�00000014575�12577562624�0021476�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Guide</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="ggregory@apache.org">Gary Gregory</author>
            <author email="sdeboy@apache.org">Scott Deboy</author>
        </properties>
    
        <body>
            <section name="Apache Log4j 2">
    
              <p>
                Apache Log4j 2 is an upgrade to Log4j that provides significant improvements over its predecessor, Log4j
                1.x, and provides many of the improvements available in Logback while fixing some inherent problems in
                Logback's architecture.
              </p>
    
              <p>Some of the features and improvements in Log4j 2 are:</p>
    
              <dl>
                <dt>API Separation</dt>
                <dd>
                  The API for Log4j is separate from the implementation making it clear for application developers
                  which classes and methods they can use while ensuring forward compatibility. This allows the
                  Log4j team to improve the implementation safely and in a compatible manner.
                </dd>
                <dt>Improved Performance</dt>
                <dd>
                  Log4j 2 contains next-generation Asynchronous Loggers based
                  on the LMAX Disruptor library. In multi-threaded scenarios
                  Asynchronous Loggers have 18 times higher throughput and
                  orders of magnitude lower latency than Log4j 1.x and Logback.
                  See <a href="manual/async.html#Performance">Asynchronous Logging Performance</a>
                  for details.
                  Otherwise, Log4j 2 performs faster than Log4j 1.x in critical areas
                  and similarly to Logback under most circumstances.
                  See <a href="performance.html">Performance</a> for more information.
                </dd>
                <dt>Support for multiple APIs</dt>
                <dd>
                  While the Log4j 2 API will provide the best performance, Log4j 2 provides support for the SLF4J and
                  Commons Logging APIs.
                </dd>
                <dt>Automatic Reloading of Configurations</dt>
                <dd>
                  Like Logback, Log4j 2 can automatically reload its configuration upon modification. Unlike Logback,
                  it will do so without losing log events while reconfiguration is taking place.
                </dd>
                <dt>Advanced Filtering</dt>
                <dd>
                  Like Logback, Log4j 2 supports filtering based on context data, markers, regular expressions,
                  and other components in the Log event. Filtering can be specified to apply to all events
                  before being passed to Loggers or as they pass through Appenders. In addition, filters can also
                  be associated with Loggers. Unlike Logback, you can use a common Filter class in any of these
                  circumstances.
                </dd>
                <dt>Plugin Architecture</dt>
                <dd>
                  Log4j uses the plugin pattern to configure components. As such, you do not need to write code
                  to create and configure an Appender, Layout, Pattern Converter, and so on. Log4j automatically
                  recognizes plugins and uses them when a configuration references them.
                </dd>
                <dt>Property Support</dt>
                <dd>
                  You can reference properties in a configuration, Log4j will directly replace them, or Log4j will
                  pass them to an underlying component that will dynamically resolve them. Properties come from values
                  defined in the configuration file, system properties, environment variables, the ThreadContext
                  Map, and data present in the event. Users can further customize the property providers by
                  adding their own <a href="manual/lookups.html">Lookup</a> Plugin.
                </dd>
                <dt>Java 8 Lambda Support</dt>
                <dd>
                  Previously, if a log message was expensive to construct, you would often explicitly check if the
                  requested log level is enabled before constructing the message.
                  Client code running on Java 8 can benefit from Log4j's <a href="manual/api.html#LambdaSupport">lambda
                  support</a>. Since Log4j will not evaluate a lambda
                  expression if the requested log level is not enabled, the same effect can be achieved with less code.
                </dd>
              </dl>
    
              <subsection name="Documentation">
                <p>
                  The Log4j 2 User's Guide is available on this <a href="manual/index.html">site</a> or as a downloadable
                  <a href="log4j-users-guide.pdf">PDF</a>.
                </p>
              </subsection>
    
              <subsection name="Requirements">
                 <p>
                   Log4j 2.4 and greater requires Java 7, versions 2.0-alpha1 to 2.3 required Java 6.
                   Some features require optional dependencies; the documentation for these features specifies the
                   dependencies.
                </p>
              </subsection>
    
              <subsection name="News">
                <p>
                  Log4j 2 is now available for production. The API for Log4j 2 is not compatible with Log4j 1.x, however an adapter
                  is available to allow applications to continue to use the Log4j 1.x API. Adapters are also available for
                  Apache Commons Logging and SLF4J.
                </p>
              </subsection>
            </section>
        </body>
    </document>
    
    �����������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/javadoc.xml��������������������������������������������������0000664�0000000�0000000�00000012017�12577562624�0021763�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
        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 Javadoc API Documentation and TLD Documentation</title>
        <author email="nickwilliams@apache.org">Nick Williams</author>
      </properties>
    
      <body>
        <section name="Javadoc API Documentation">
          <p>
            The table below contains links to the Javadoc API Documentation for the components you are most likely to use
            directly in code. You can also use the menu links on the left.
          </p>
          <table>
            <tr>
              <th>Component</th>
              <th>Description</th>
            </tr>
            <tr>
              <td><a href="log4j-api/apidocs/index.html">Log4j 2 API</a></td>
              <td>The interface that applications should use and code against.</td>
            </tr>
            <tr>
              <td><a href="log4j-core/apidocs/index.html">Implementation</a></td>
              <td>The standard implementation, also called the Log4j 2 Core, that contains Appenders, Filters, and more.</td>
            </tr>
            <tr>
              <td><a href="log4j-iostreams/apidocs/index.html">Log4j IO Streams</a></td>
              <td>Extra classes for dealing with older APIs that expect classes from <code>java.io</code> for logging.</td>
            </tr>
            <tr>
              <td><a href="log4j-taglib/apidocs/index.html">JSP Tag Library</a></td>
              <td>The tag library that enables Java-free logging in JavaServer Pages™ using Log4j 2.</td>
            </tr>
            <tr>
              <td><a href="log4j-taglib/tlddoc/index.html">JSP Tag Library (TLD Doc)</a></td>
              <td>The special Javadoc-like Tag Library Documentation for the Log4j 2 JSP Tag Library.</td>
            </tr>
          </table>
    
          <p>
            The table below contains links to the Javadoc API Documentation for all the other Log4j 2 components, which you
            likely will not use directly in code but instead will only configure or include in your dependencies.
          </p>
          <table>
            <tr>
              <th>Component</th>
              <th>Description</th>
            </tr>
            <tr>
              <td><a href="log4j-jcl/apidocs/index.html">Commons Logging Bridge</a></td>
              <td>A bridge that permits applications written against the Apache Commons Logging API to log using Log4j 2.</td>
            </tr>
            <tr>
              <td><a href="log4j-slf4j-impl/apidocs/index.html">SLF4J Binding</a></td>
              <td>A bridge that permits applications written against the SLF4J API to log using Log4j 2.</td>
            </tr>
            <tr>
              <td><a href="log4j-jul/apidocs/index.html">Java Util Logging Adapter</a></td>
              <td>A bridge that permits applications written against the <code>java.util.logging</code> API to log using
              Log4j 2.</td>
            </tr>
            <tr>
              <td><a href="log4j-1.2-api/apidocs/index.html">Log4j 1.2 API Bridge</a></td>
              <td>A bridge that permits applications written against the Log4j 1.2.x API to log using Log4j 2.</td>
            </tr>
            <tr>
              <td><a href="log4j-to-slf4j/apidocs/index.html">Log4j 2 to SLF4J Adapter</a></td>
              <td>An adapter that permits applications written against the Log4j 2 API to log using SLF4J.</td>
            </tr>
            <tr>
              <td><a href="log4j-flume-ng/apidocs/index.html">Apache Flume Appender</a></td>
              <td>An Appender that allows applications to send logging events to Apache Flume Agents.</td>
            </tr>
            <tr>
              <td><a href="log4j-jmx-gui/apidocs/index.html">Log4j JMX GUI</a></td>
              <td>A Java Swing-based client for remotely viewing the status logger and editing the Log4j configuration.</td>
            </tr>
            <tr>
              <td><a href="log4j-web/apidocs/index.html">Log4j Web Application Support</a></td>
              <td>Additional classes that enable multiple configurations within a Servlet Container.</td>
            </tr>
            <tr>
              <td><a href="log4j-nosql/apidocs/index.html">Log4j NoSQL Support</a></td>
              <td>Additional Appenders for NoSQL databases such as MongoDB and CouchDB.</td>
            </tr>
          </table>
        </section>
      </body>
    </document>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/javastyle.xml������������������������������������������������0000664�0000000�0000000�00000127733�12577562624�0022372�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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>Java Style Guidelines</title>
      </properties>
    
      <body>
        <section name="Apache Log4j Code Style Guidelines">
          <a name="intro"/>
          <subsection name="Introduction">
            <p>This document serves as the <strong>complete</strong> definition of the Log4j project's coding standards for
              source code in the Java™ Programming Language. It originated from the Google coding standards but incorporates
              modifications that reflect the desires of the Log4j community.</p>
            <p>Like other programming style guides, the issues covered span not only aesthetic issues of
            formatting, but other types of conventions or coding standards as well. However, this document
            focuses primarily on the <strong>hard-and-fast rules</strong> that we follow universally, and
            avoids giving <em>advice</em> that isn't clearly enforceable (whether by human or tool).</p>
          <a name="terminology"/>
          <h3>Terminology notes</h3>
            <p>In this document, unless otherwise clarified:</p>
            <ol>
              <li>The term <em>class</em> is used inclusively to mean an "ordinary" class, enum class, interface or
                 annotation type (<code>@interface</code>).</li>
              <li>The term <em>comment</em> always refers to <em>implementation</em> comments. We do not
                use the phrase "documentation comments", instead using the common term "Javadoc."</li>
            </ol>
            <p>Other "terminology notes" will appear occasionally throughout the document.</p>
          <a name="guide-notes"/>
          <h3>Guide notes</h3>
          <p>Example code in this document is <strong>non-normative</strong>. That is, while the examples
            are in Log4j Style, they may not illustrate the <em>only</em> stylish way to represent the
            code. Optional formatting choices made in examples should not be enforced as rules.</p>
          </subsection>
          <a name="source-file-basics"/>
          <subsection name="Source File Basics">
          <a name="file-name"/>
          <h3>File name</h3>
          <p>The source file name consists of the case-sensitive name of the top-level class it contains,
            plus the <code>.java</code> extension.</p>
          <a name="file-encoding"/>
          <h3>2.2 File encoding: UTF-8</h3>
          <p>Source files are encoded in <strong>UTF-8</strong>.</p>
          <a name="special-characters"/>
          <h3>Special characters</h3>
          <a name="whitespace-characters"/>
          <h4>Whitespace characters</h4>
          <p>Aside from the line terminator sequence, the <strong>ASCII horizontal space
            character</strong> (<strong>0x20</strong>) is the only whitespace character that appears
            anywhere in a source file. This implies that:</p>
            <ol>
              <li>All other whitespace characters in string and character literals are escaped.</li>
              <li>Tab characters are <strong>not</strong> used for indentation.</li>
            </ol>
          <a name="special-escape-sequences"/>
          <h4>Special escape sequences</h4>
          <p>For any character that has a special escape sequence
            (<code>\b</code>,
            <code>\t</code>,
            <code>\n</code>,
            <code>\f</code>,
            <code>\r</code>,
            <code>\"</code>,
            <code>\'</code> and
            <code>\\</code>), that sequence is used rather than the corresponding octal
            (e.g. <code>\012</code>) or Unicode (e.g. <code>\u000a</code>) escape.</p>
          <a name="non-ascii-characters"/>
          <h4>Non-ASCII characters</h4>
            <p>For the remaining non-ASCII characters, either the actual Unicode character
              (e.g. <code>∞</code>) or the equivalent Unicode escape (e.g. <code>\u221e</code>) is used, depending only on which
              makes the code <strong>easier to read and understand</strong>.</p>
            <p><strong>Tip:</strong> In the Unicode escape case, and occasionally even when actual
              Unicode characters are used, an explanatory comment can be very helpful.</p>
            <p>Examples:</p>
              <table>
                <tr><th>Example</th><th>Discussion</th></tr>
                <tr><td><code>String unitAbbrev = "μs";</code></td><td>Best: perfectly clear even without a comment.</td></tr>
                <tr><td><code>String unitAbbrev = "\u03bcs"; // "μs"</code></td><td>Allowed, but there's no reason to do this.</td></tr>
                <tr><td><code>String unitAbbrev = "\u03bcs"; // Greek letter mu, "s"</code></td><td>Allowed, but awkward and prone to mistakes.</td></tr>
                <tr><td><code>String unitAbbrev = "\u03bcs";</code></td><td>Poor: the reader has no idea what this is.</td></tr>
                <tr><td><code>return '\ufeff' + content; // byte order mark</code></td><td>Good: use escapes for non-printable characters, and comment if necessary.</td></tr>
              </table>
            <p><strong>Tip:</strong> Never make your code less readable simply out of fear that
              some programs might not handle non-ASCII characters properly. If that should happen, those
              programs are <strong>broken</strong> and they must be <strong>fixed</strong>.</p>
          </subsection>
          <a name="filestructure"/>
          <a name="source-file-structure"/>
          <subsection name="Source file structure">
            <p>A source file consists of, <strong>in order</strong>:</p>
              <ol>
                <li>Apache license</li>
                <li>Package statement</li>
                <li>Import statements</li>
                <li>Exactly one top-level class</li>
              </ol>
            <p><strong>Exactly one blank line</strong> separates each section that is present.</p>
            <a name="license"/>
          <h3>Apache License</h3>
            <p>The Apache license belongs here. No other license should appear. Other licenses that apply should be referenced in
              a NOTICE file</p>
          <a name="package-statement"/>
          <h3>Package statement</h3>
          <p>The package statement is <strong>not line-wrapped</strong>. The column limit
            (<a href="#column-limit">Column limit: 120</a>) does not apply to package statements.</p>
          <a name="imports"/>
          <a name="import-statements"/>
          <h3>Import statements</h3>
          <a name="wildcard-imports"/>
          <h4>No wildcard imports in the main tree</h4>
            <p><strong>Wildcard imports</strong>, static or otherwise, <strong>are not used</strong>.</p>
          <h4>Static wildcard imports in the test tree</h4>
            <p><strong>Wildcard static imports</strong> are encouraged for test imports like JUnit, EasyMock, and Hamcrest.</p>
          <a name="import-line-wrapping"/>
          <h4>No line-wrapping</h4>
          <p>Import statements are <strong>not line-wrapped</strong>. The column limit
            (<a href="#column-limit">Column limit: 120</a>) does not apply to import statements.</p>
          <a name="import-ordering-and-spacing"/>
          <h4>Ordering and spacing</h4>
          <p>Import statements are divided into the following groups, in this order, with each group
            separated by a single blank line:</p>
            <ol>
              <li>java</li>
              <li>javax</li>
              <li>org</li>
              <li>com</li>
              <li>All static imports in a single group</li>
            </ol>
          <p>Within a group there are no blank lines, and the imported names appear in ASCII sort
          order. (<strong>Note:</strong> this is not the same as the import <em>statements</em> being in
          ASCII sort order; the presence of semicolons warps the result.)</p>
          <p>IDE settings for ordering imports automatically can be found in the source distributions under
          <code>src/ide</code>. For example:</p>
          <ul>
            <li>Eclipse: <code>src/ide/eclipse/4.3.2/organize-imports.importorder</code></li>
            <li>IntelliJ: <code>src/ide/Intellij/13/IntellijSettings.jar</code></li>
          </ul>
          <a name="class-declaration"/>
          <h3>Class declaration</h3>
          <a name="oneclassperfile"/>
          <a name="one-top-level-class"/>
          <h4>Exactly one top-level class declaration</h4>
            <p>Each top-level class resides in a source file of its own.</p>
          <a name="class-member-ordering"/>
          <h4>Class member ordering</h4>
          <p>Class members should be grouped in the following order>.</p>
          <ol>
            <li>static variables grouped in the order shown below. Within a group variables may appear in any order.</li>
            <li>
              <ol>
                <li>public</li>
                <li>protected</li>
                <li>package</li>
                <li>private</li>
              </ol>
            </li>
            <li>instance variables grouped in the order shown below. Within a group variables may appear in any order</li>
            <li>
              <ol>
                <li>public</li>
                <li>protected</li>
                <li>package</li>
                <li>private</li>
              </ol>
            </li>
            <li>constructors</li>
            <li>methods may be specified in the following order but may appear in another order if it improves the
              clarity of the program.</li>
            <li>
              <ol>
                <li>public</li>
                <li>protected</li>
                <li>package</li>
                <li>private</li>
              </ol>
            </li>
          </ol>
          <a name="overloads"/>
          <a name="never-split"/>
          <h5>Overloads: never split</h5>
          <p>When a class has multiple constructors, or multiple methods with the same name, these appear
            sequentially, with no intervening members.</p>
          </subsection>
          <a name="formatting"/>
          <subsection name="Formatting">
          <p><strong>Terminology Note:</strong> <em>block-like construct</em> refers to
            the body of a class, method or constructor. Note that, by
            <a href="array-initializers">array initializers</a>, any array initializer
            <em>may</em> optionally be treated as if it were a block-like construct.</p>
          <a name="braces"/>
          <h3>Braces</h3>
          <a name="braces-always-used"/>
          <h4>Braces are used where optional</h4>
          <p>Braces are used with
            <code>if</code>,
            <code>else</code>,
            <code>for</code>,
            <code>do</code> and
            <code>while</code> statements, even when the
            body is empty or contains only a single statement.</p>
          <a name="blocks-k-r-style"/>
          <h4>Nonempty blocks: K &amp; R style</h4>
          <p>Braces follow the Kernighan and Ritchie style
            ("<a href="http://www.codinghorror.com/blog/2012/07/new-programming-jargon.html">Egyptian brackets</a>")
            for <em>nonempty</em> blocks and block-like constructs:</p><ul><li>No line break before the opening brace.</li><li>Line break after the opening brace.</li><li>Line break before the closing brace.</li><li>Line break after the closing brace <em>if</em> that brace terminates a statement or the body
          of a method, constructor or <em>named</em> class. For example, there is <em>no</em> line break
          after the brace if it is followed by <code>else</code> or a
          comma.</li></ul><p>Example:</p><pre>
          return new MyClass() {
          @Override public void method() {
          if (condition()) {
          try {
          something();
          } catch (ProblemException e) {
          recover();
          }
          }
          }
          };
        </pre><p>A few exceptions for enum classes are given in Section 4.8.1,
          <a href="enum-classes">Enum classes</a>.</p>
          <a name="emptyblocks"/>
          <a name="braces-empty-blocks"/>
          <h4>Empty blocks: may be concise</h4>
          <p>An empty block or block-like construct <em>may</em> be closed immediately after it is
            opened, with no characters or line break in between
            (<code>{}</code>), <strong>unless</strong> it is part of a
            <em>multi-block statement</em> (one that directly contains multiple blocks:
            <code>if/else-if/else</code> or
            <code>try/catch/finally</code>).</p>
            <p>Example:</p><pre>
          void doNothing() {}
        </pre><a name="block-indentation"/>
          <h3>Block indentation: +4 spaces</h3>
          <p>Each time a new block or block-like construct is opened, the indent increases by four
            spaces. When the block ends, the indent returns to the previous indent level. The indent level
            applies to both code and comments throughout the block. (See the example in Section 4.1.2,
            <a href="#blocks-k-r-style">Nonempty blocks: K &amp; R Style</a>.)</p>
            <a name="one-statement-per-line"/>
          <h3>One statement per line</h3>
          <p>Each statement is followed by a line-break.</p>
            <a name="columnlimit"/>
            <a name="column-limit"/>
          <h3>Column limit: 120</h3>
          <p>
            The column limit for Log4j is 120 characters.
    
            Except as noted below, any line that would exceed this limit must be line-wrapped, as explained in
            <a href="#line-wrapping">Line-wrapping</a>.
          </p><p><strong>Exceptions:</strong></p>
            <ol>
              <li>Lines where obeying the column limit is not possible (for example, a long URL in Javadoc,
          or a long JSNI method reference).</li>
              <li><code>package</code> and <code>import</code> statements (see <a href="#package-statement">Package statement</a> and
          <a href="#import-statements">Import statements</a>).</li>
              <li>Command lines in a comment that may be cut-and-pasted into a shell.</li>
            </ol><a name="line-wrapping"/>
          <h3>Line-wrapping</h3>
          <p class="terminology"><strong>Terminology Note:</strong> When code that might otherwise legally
            occupy a single line is divided into multiple lines, typically to avoid overflowing the column
            limit, this activity is called
            <em>line-wrapping</em>.</p>
            <p>There is no comprehensive, deterministic formula showing <em>exactly</em> how to line-wrap in
          every situation. Very often there are several valid ways to line-wrap the same piece of code.</p>
            <p class="tip"><strong>Tip:</strong> Extracting a method or local variable may solve the problem
          without the need to line-wrap.</p>
          <a name="line-wrapping-where-to-break"/>
          <h4>Where to break</h4>
          <p>The prime directive of line-wrapping is: prefer to break at a
            <strong>higher syntactic level</strong>. Also:</p>
            <ol>
              <li>When a line is broken at a <em>non-assignment</em> operator the break comes <em>before</em>
          the symbol. (Note that this is not the same practice used in Google style for other languages,
          such as C++ and JavaScript.)
                <ul>
                  <li>This also applies to the following "operator-like" symbols: the dot separator
            (<code>.</code>), the ampersand in type bounds
            (<code>&lt;T extends Foo &amp; Bar&gt;</code>), and the pipe in
            catch blocks
            (<code>catch (FooException | BarException e)</code>).</li>
                </ul>
              </li>
              <li>When a line is broken at an <em>assignment</em> operator the break typically comes
          <em>after</em> the symbol, but either way is acceptable.
                <ul>
                  <li>This also applies to the "assignment-operator-like" colon in an enhanced
            <code>for</code> ("foreach") statement.</li>
                </ul>
              </li>
              <li>A method or constructor name stays attached to the open parenthesis
          (<code>(</code>) that follows it.</li>
              <li>A comma (<code>,</code>) stays attached to the token that
          precedes it.</li>
            </ol>
            <a name="indentation"/>
            <a name="line-wrapping-indent"/>
          <h4>Indent continuation lines at least +8 spaces</h4>
            <p>When line-wrapping, each line after the first (each <em>continuation line</em>) is indented
              at least +8 from the original line.</p>
            <p>When there are multiple continuation lines, indentation may be varied beyond +8 as
          desired. In general, two continuation lines use the same indentation level if and only if they
          begin with syntactically parallel elements.</p>
            <p>The section on <a href="#horizontal-alignment">Horizontal alignment</a> addresses
          the discouraged practice of using a variable number of spaces to align certain tokens with
          previous lines.</p>
            <a name="whitespace"/>
          <h3>Whitespace</h3>
          <a name="vertical-whitespace"/>
          <h4>Vertical Whitespace</h4>
          <p>A single blank line appears:</p>
            <ol>
              <li><em>Between</em> consecutive members (or initializers) of a class: fields, constructors,
          methods, nested classes, static initializers, instance initializers.
                <ul>
                  <li><span class="exception"><strong>Exception:</strong> A blank line between two consecutive
            fields (having no other code between them) is optional. Such blank lines are used as needed to
            create <em>logical groupings</em> of fields.</span></li>
                </ul>
              </li>
              <li>Within method bodies, as needed to create <em>logical groupings</em> of statements.</li><li><em>Optionally</em> before the first member or after the last member of the class (neither
          encouraged nor discouraged).</li>
              <li>As required by other sections of this document (such as
          <a href="#import-statements">Import statements</a>).</li>
            </ol>
            <p><em>Multiple</em> consecutive blank lines are permitted, but never required (or encouraged).</p>
            <a name="horizontal-whitespace"/>
          <h4>Horizontal whitespace</h4>
          <p>Beyond where required by the language or other style rules, and apart from literals, comments and
            Javadoc, a single ASCII space also appears in the following places <strong>only</strong>.</p>
            <ol>
              <li>Separating any reserved word, such as
          <code>if</code>,
          <code>for</code> or
          <code>catch</code>, from an open parenthesis
          (<code>(</code>)
          that follows it on that line</li>
              <li>Separating any reserved word, such as
          <code>else</code> or
          <code>catch</code>, from a closing curly brace
          (<code>}</code>) that precedes it on that line</li>
              <li>Before any open curly brace
          (<code>{</code>), with two exceptions:
                <ul>
                  <li><code>String[][] x = {{"foo"}};</code> (no space is required
            between <code>{{</code>, by item 8 below)</li>
                </ul>
              </li>
              <li>On both sides of any binary or ternary operator. This also applies to the following
          "operator-like" symbols:
                <ul>
                  <li>the ampersand in a conjunctive type bound:
            <code>&lt;T extends Foo &amp; Bar&gt;</code></li>
                  <li>the pipe for a catch block that handles multiple exceptions:
            <code>catch (FooException | BarException e)</code></li>
                  <li>the colon (<code>:</code>) in an enhanced
            <code>for</code> ("foreach") statement</li>
                </ul>
              </li>
              <li>After <code>,:;</code> or the closing parenthesis
          (<code>)</code>) of a cast</li>
              <li>On both sides of the double slash (<code>//</code>) that
          begins an end-of-line comment. Here, multiple spaces are allowed, but not required.</li>
              <li>Between the type and variable of a declaration:
          <code>List&lt;String&gt; list</code></li>
              <li><em>Optional</em> just inside both braces of an array initializer
                <ul>
                  <li><code>new int[] {5, 6}</code> and
            <code>new int[] { 5, 6 }</code> are both valid</li>
                </ul>
              </li>
            </ol>
            <p class="note"><strong>Note:</strong> This rule never requires or forbids additional space at the
          start or end of a line, only <em>interior</em> space.</p>
            <a name="horizontal-alignment"/>
          <h4>Horizontal alignment: never required</h4>
            <p class="terminology"><strong>Terminology Note:</strong> <em>Horizontal alignment</em> is the
            practice of adding a variable number of additional spaces in your code with the goal of making
            certain tokens appear directly below certain other tokens on previous lines.</p>
            <p>This practice is permitted, but is <strong>never required</strong> by Google Style. It is not
          even required to <em>maintain</em> horizontal alignment in places where it was already used.</p>
            <p>Here is an example without alignment, then using alignment:</p>
            <pre>
          private int x; // this is fine
          private Color color; // this too
    
          private int   x;      // permitted, but future edits
          private Color color;  // may leave it unaligned
        </pre>
            <p class="tip"><strong>Tip:</strong> Alignment can aid readability, but it creates problems for
          future maintenance.  Consider a future change that needs to touch just one line. This change may
          leave the formerly-pleasing formatting mangled, and that is <strong>allowed</strong>. More often
          it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly
          triggering a cascading series of reformattings. That one-line change now has a "blast radius."
          This can at worst result in pointless busywork, but at best it still corrupts version history
          information, slows down reviewers and exacerbates merge conflicts.</p>
            <a name="parentheses"/>
            <a name="grouping-parentheses"/>
          <h3>Grouping parentheses: recommended</h3>
          <p>Optional grouping parentheses are omitted only when author and reviewer agree that there is no
            reasonable chance the code will be misinterpreted without them, nor would they have made the code
            easier to read. It is <em>not</em> reasonable to assume that every reader has the entire Java
            operator precedence table memorized.</p>
            <a name="specific-constructs"/>
          <h3>Specific constructs</h3>
          <a name="enum-classes"/>
          <h4>Enum classes</h4>
          <p>After each comma that follows an enum constant, a line-break is optional.</p><p>An enum class with no methods
            and no documentation on its constants may optionally be formatted
          as if it were an array initializer (see
          <a href="array-initializers">array initializers</a>).</p><pre>
          private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
        </pre>
            <p>Since enum classes <em>are classes</em>, all other rules for formatting classes apply.</p>
            <a name="localvariables"/>
            <a name="variable-declarations"/>
          <h4>Variable declarations</h4>
          <a name="variables-per-declaration"/>
          <h5>One variable per declaration</h5>
          <p>Every variable declaration (field or local) declares only one variable: declarations such as
            <code>int a, b;</code> are not used.</p>
            <a name="variables-limited-scope"/>
          <h5>Declared when needed, initialized as soon as possible</h5>
          <p>Local variables are <strong>not</strong> habitually declared at the start of their containing
            block or block-like construct. Instead, local variables are declared close to the point they are
            first used (within reason), to minimize their scope. Local variable declarations typically have
            initializers, or are initialized immediately after declaration.</p><a name="s4.8.3-arrays"/>
          <h4>Arrays</h4>
          <a name="array-initializers"/>
          <h5>Array initializers: can be "block-like"</h5>
          <p>Any array initializer may <em>optionally</em> be formatted as if it were a "block-like
            construct." For example, the following are all valid (<strong>not</strong> an exhaustive
            list):</p><pre>
          new int[] {           new int[] {
          0, 1, 2, 3            0,
          }                       1,
          2,
          new int[] {             3,
          0, 1,               }
          2, 3
          }                     new int[]
          {0, 1, 2, 3}
        </pre><a name="array-declarations"/>
          <h5>No C-style array declarations</h5>
          <p>The square brackets form a part of the <em>type</em>, not the variable:
            <code>String[] args</code>, not
            <code>String args[]</code>.</p>
            <a name="switch"/>
          <h4>Switch statements</h4>
          <p class="terminology"><strong>Terminology Note:</strong> Inside the braces of a
            <em>switch block</em> are one or more <em>statement groups</em>. Each statement group consists of
            one or more <em>switch labels</em> (either <code>case FOO:</code> or
            <code>default:</code>), followed by one or more statements.</p>
            <a name="switch-indentation"/>
          <h5>Indentation</h5>
          <p>As with any other block, the contents of a switch block are indented +2.</p>
            <p>After a switch label, a newline appears, and the indentation level is increased +2, exactly as
          if a block were being opened. The following switch label returns to the previous indentation
          level, as if a block had been closed.</p>
            <a name="fallthrough"/>
            <a name="switch-fall-through"/>
          <h5>Fall-through: commented</h5>
          <p>Within a switch block, each statement group either terminates abruptly (with a
            <code>break</code>,
            <code>continue</code>,
            <code>return</code> or thrown exception), or is marked with a comment
            to indicate that execution will or <em>might</em> continue into the next statement group. Any
            comment that communicates the idea of fall-through is sufficient (typically
            <code>// fall through</code>). This special comment is not required in
            the last statement group of the switch block. Example:</p><pre>
          switch (input) {
          case 1:
          case 2:
          prepareOneOrTwo();
          // fall through
          case 3:
          handleOneTwoOrThree();
          break;
          default:
          handleLargeNumber(input);
          }
        </pre><a name="switch-default"/>
          <h5>The default case is present</h5>
          <p>Each switch statement includes a <code>default</code> statement
            group, even if it contains no code.</p>
            <a name="annotations"/>
          <h4>Annotations</h4>
          <p>Annotations applying to a class, method or constructor appear immediately after the
            documentation block, and each annotation is listed on a line of its own (that is, one annotation
            per line). These line breaks do not constitute line-wrapping (Section
            4.5, <a href="#line-wrapping">Line-wrapping</a>), so the indentation level is not
            increased. Example:</p><pre>
          @Override
          @Nullable
          public String getNameIfPresent() { ... }
        </pre><p class="exception"><strong>Exception:</strong> A <em>single</em> parameterless annotation
          <em>may</em> instead appear together with the first line of the signature, for example:</p><pre>
          @Override public int hashCode() { ... }
        </pre><p>Annotations applying to a field also appear immediately after the documentation block, but in
          this case, <em>multiple</em> annotations (possibly parameterized) may be listed on the same line;
          for example:</p><pre>
          @Partial @Mock DataLoader loader;
        </pre><p>There are no specific rules for formatting parameter and local variable annotations.</p>
            <a name="comments"/>
          <h4>Comments</h4>
          <a name="block-comment-style"/>
          <h5>Block comment style</h5>
          <p>Block comments are indented at the same level as the surrounding code. They may be in
            <code>/* ... */</code> style or
            <code>// ...</code> style. For multi-line
            <code>/* ... */</code> comments, subsequent lines must start with
            <code>*</code> aligned with the <code>*</code> on the previous line.</p><pre>
          /*
          * This is          // And so           /* Or you can
          * okay.            // is this.          * even do this. */
          */
        </pre>
            <p>Comments are not enclosed in boxes drawn with asterisks or other characters.</p>
            <p><strong>Tip:</strong> When writing multi-line comments, use the
          <code>/* ... */</code> style if you want automatic code formatters to
          re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in
          <code>// ...</code> style comment blocks.</p>
            <a name="modifiers"/>
          <h4>Modifiers</h4>
          <p>Class and member modifiers, when present, appear in the order
            recommended by the Java Language Specification:
          </p><pre>
          public protected private abstract static final transient volatile synchronized native strictfp
        </pre>
            <a name="numeric-literals"/>
          <h4>Numeric Literals</h4>
          <p><code>long</code>-valued integer literals use an uppercase <code>L</code> suffix, never
            lowercase (to avoid confusion with the digit <code>1</code>). For example, <code>3000000000L</code>
            rather than <code>3000000000l</code>.</p>
          </subsection>
          <a name="naming"/>
          <subsection name="Naming">
          <a name="identifier-names"/>
          <h3>Rules common to all identifiers</h3>
          <p>Identifiers use only ASCII letters and digits, and in two cases noted below, underscores. Thus
            each valid identifier name is matched by the regular expression <code>\w+</code> .</p>
            <p> In Google Style special prefixes or
          suffixes, like those seen in the examples <code>name_</code>,
          <code>mName</code>, <code>s_name</code> and
          <code>kName</code>, are <strong>not</strong> used.</p>
            <a name="specific-identifier-names"/>
          <h3>Rules by identifier type</h3>
          <a name="package-names"/>
          <h4>Package names</h4>
          <p>Package names are all lowercase, with consecutive words simply concatenated together (no
            underscores). For example, <code>com.example.deepspace</code>, not
            <code>com.example.deepSpace</code> or
            <code>com.example.deep_space</code>.</p>
            <a name="class-names"/>
          <h4>Class names</h4>
          <p>Class names are written in <a href="#camel-case">UpperCamelCase</a>.</p>
            <p>Class names are typically nouns or noun phrases. For example,
          <code>Character</code> or
          <code>ImmutableList</code>. Interface names may also be nouns or
          noun phrases (for example, <code>List</code>), but may sometimes be
          adjectives or adjective phrases instead (for example,
          <code>Readable</code>).</p><p>There are no specific rules or even well-established conventions for naming annotation types.</p><p><em>Test</em> classes are named starting with the name of the class they are testing, and ending
          with <code>Test</code>. For example,
          <code>HashTest</code> or
          <code>HashIntegrationTest</code>.</p>
            <a name="method-names"/>
          <h4>Method names</h4>
          <p>Method names are written in <a href="#s5.3-camel-case">lowerCamelCase</a>.</p>
            <p>Method names are typically verbs or verb phrases. For example,
          <code>sendMessage</code> or
          <code>stop</code>.</p><p>Underscores may appear in JUnit <em>test</em> method names to separate logical components of the
          name. One typical pattern is <code>test<i>&lt;MethodUnderTest&gt;</i>_<i>&lt;state&gt;</i></code>,
          for example <code>testPop_emptyStack</code>. There is no One Correct
          Way to name test methods.</p>
            <a name="constants"/>
            <a name="constant-names"/>
          <h4>Constant names</h4>
          <p>Constant names use <code>CONSTANT_CASE</code>: all uppercase
            letters, with words separated by underscores. But what <em>is</em> a constant, exactly?</p>
            <p>Every constant is a static final field, but not all static final fields are constants. Before
          choosing constant case, consider whether the field really <em>feels like</em> a constant. For
          example, if any of that instance's observable state can change, it is almost certainly not a
          constant. Merely <em>intending</em> to never mutate the object is generally not
          enough. Examples:</p><pre>
          // Constants
          static final int NUMBER = 5;
          static final ImmutableList&lt;String&gt; NAMES = ImmutableList.of("Ed", "Ann");
          static final Joiner COMMA_JOINER = Joiner.on(',');  // because Joiner is immutable
          static final SomeMutableType[] EMPTY_ARRAY = {};
          enum SomeEnum { ENUM_CONSTANT }
    
          // Not constants
          static String nonFinal = "non-final";
          final String nonStatic = "non-static";
          static final Set&lt;String&gt; mutableCollection = new HashSet&lt;String&gt;();
          static final ImmutableSet&lt;SomeMutableType&gt; mutableElements = ImmutableSet.of(mutable);
          static final Logger logger = Logger.getLogger(MyClass.getName());
          static final String[] nonEmptyArray = {"these", "can", "change"};
        </pre>
            <p>These names are typically nouns or noun phrases.</p>
            <a name="non-constant-field-names"/>
          <h4>Non-constant field names</h4>
          <p>Non-constant field names (static or otherwise) are written
            in <a href="#camel-case">lowerCamelCase</a>.</p>
            <p>These names are typically nouns or noun phrases.  For example,
          <code>computedValues</code> or
          <code>index</code>.</p>
            <a name="parameter-names"/>
          <h4>Parameter names</h4>
          <p>Parameter names are written in <a href="#camel-case">lowerCamelCase</a>.</p>
            <p>One-character parameter names should be avoided.</p>
            <a name="local-variable-names"/>
          <h4>Local variable names</h4>
          <p>Local variable names are written in <a href="#camel-case">lowerCamelCase</a>, and can be
            abbreviated more liberally than other types of names.</p><p>However, one-character names should be avoided, except for temporary and looping variables.</p><p>Even when final and immutable, local variables are not considered to be constants, and should not
          be styled as constants.</p>
            <a name="type-variable-names"/>
          <h4>Type variable names</h4>
          <p>Each type variable is named in one of two styles:</p><ul><li>A single capital letter, optionally followed by a single numeral (such as
          <code>E</code>, <code>T</code>,
          <code>X</code>, <code>T2</code>)
        </li><li>A name in the form used for classes (see
          <a href="#class-names">Class names</a>), followed by the capital letter
          <code>T</code> (examples:
          <code>RequestT</code>,
          <code>FooBarT</code>).</li></ul><a name="acronyms"/>
            <a name="camelcase"/>
            <a name="camel-case"/>
          <h3>Camel case: defined</h3>
          <p>Sometimes there is more than one reasonable way to convert an English phrase into camel case,
            such as when acronyms or unusual constructs like "IPv6" or "iOS" are present. To improve
            predictability, Google Style specifies the following (nearly) deterministic scheme.</p>
            <p>Beginning with the prose form of the name:</p>
            <ol>
              <li>Convert the phrase to plain ASCII and remove any apostrophes. For example, "Müller's
          algorithm" might become "Muellers algorithm".</li>
              <li>Divide this result into words, splitting on spaces and any remaining punctuation (typically
          hyphens).
    
                <ul>
                  <li><em>Recommended:</em> if any word already has a conventional camel-case appearance in common
            usage, split this into its constituent parts (e.g., "AdWords" becomes "ad words"). Note
            that a word such as "iOS" is not really in camel case <em>per se</em>; it defies <em>any</em>
            convention, so this recommendation does not apply.</li>
                </ul>
              </li>
              <li>Now lowercase <em>everything</em> (including acronyms), then uppercase only the first
          character of:
                <ul><li>... each word, to yield <em>upper camel case</em>, or</li>
                  <li>... each word except the first, to yield <em>lower camel case</em></li>
                </ul>
              </li>
              <li>Finally, join all the words into a single identifier.</li>
            </ol>
            <p>Note that the casing of the original words is almost entirely disregarded. Examples:</p>
            <table>
              <tr><th>Prose form</th><th>Correct</th><th>Incorrect</th></tr>
              <tr><td>"XML HTTP request"</td><td><code>XmlHttpRequest</code></td><td><code>XMLHTTPRequest</code></td></tr>
              <tr><td>"new customer ID"</td><td><code>newCustomerId</code></td><td><code>newCustomerID</code></td></tr>
              <tr><td>"inner stopwatch"</td><td><code>innerStopwatch</code></td><td><code>innerStopWatch</code></td></tr>
              <tr><td>"supports IPv6 on iOS?"</td><td><code>supportsIpv6OnIos</code></td><td><code>supportsIPv6OnIOS</code></td></tr>
              <tr><td>"YouTube importer"</td><td><code>YouTubeImporter</code><br/><code>YoutubeImporter</code>*</td><td/></tr>
            </table>
            <p>*Acceptable, but not recommended.</p>
            <p><strong>Note:</strong> Some words are ambiguously hyphenated in the English
          language: for example "nonempty" and "non-empty" are both correct, so the method names
          <code>checkNonempty</code> and
          <code>checkNonEmpty</code> are likewise both correct.</p>
          </subsection>
          <subsection name="Programming Practices">
          <a name="programming-practices"/>
          <a name="override-annotation"/>
          <h3>@Override: always used</h3>
          <p>A method is marked with the <code>@Override</code> annotation
            whenever it is legal.  This includes a class method overriding a superclass method, a class method
            implementing an interface method, and an interface method respecifying a superinterface
            method.</p>
          <p class="exception"><strong>Exception:</strong><code>@Override</code> may be omitted when the parent method is
          <code>@Deprecated</code>.</p>
          <a name="caughtexceptions"/>
          <a name="caught-exceptions"/>
          <h3>Caught exceptions: not ignored</h3>
          <p>Except as noted below, it is very rarely correct to do nothing in response to a caught
            exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an
            <code>AssertionError</code>.)</p>
            <p>When it truly is appropriate to take no action whatsoever in a catch block, the reason this is
          justified is explained in a comment.</p><pre>
          try {
          int i = Integer.parseInt(response);
          return handleNumericResponse(i);
          } catch (NumberFormatException ok) {
          // it's not numeric; that's fine, just continue
          }
          return handleTextResponse(response);
        </pre><p><strong>Exception:</strong> In tests, a caught exception may be ignored
          without comment <em>if</em> it is named <code>expected</code>. The
          following is a very common idiom for ensuring that the method under test <em>does</em> throw an
          exception of the expected type, so a comment is unnecessary here.</p><pre>
          try {
          emptyStack.pop();
          fail();
          } catch (NoSuchElementException expected) {
          }
        </pre><a name="static-members"/>
          <h3>Static members: qualified using class</h3>
          <p>When a reference to a static class member must be qualified, it is qualified with that class's
            name, not with a reference or expression of that class's type.</p><pre>
          Foo aFoo = ...;
          Foo.aStaticMethod(); // good
          <span>aFoo.aStaticMethod();</span> // bad
          <span>somethingThatYieldsAFoo().aStaticMethod();</span> // very bad
        </pre>
            <a name="finalizers"/>
          <h3>Finalizers: not used</h3>
          <p>It is <strong>extremely rare</strong> to override <code>Object.finalize</code>.</p>
          <p><strong>Tip:</strong> Don't do it. If you absolutely must, first read and understand
          <a href="http://books.google.com/books?isbn=8131726592"><em>Effective Java</em></a>
          Item 7, "Avoid Finalizers," very carefully, and <em>then</em> don't do it.</p>
          </subsection>
          <a name="javadoc"/>
          <subsection name="Javadoc">
          <a name="javadoc-formatting"/>
          <h3>Formatting</h3>
          <a name="javadoc-multi-line"/>
          <h4>General form</h4>
          <p>The <em>basic</em> formatting of Javadoc blocks is as seen in this example:</p><pre>
          /**
          * Multiple lines of Javadoc text are written here,
          * wrapped normally...
          */
          public int method(String p1) { ... }
        </pre><p>... or in this single-line example:</p><pre>
          /** An especially short bit of Javadoc. */
        </pre><p>The basic form is always acceptable. The single-line form may be substituted when there are no
          at-clauses present, and the entirety of the Javadoc block (including comment markers) can fit on a
          single line.</p>
          <a name="javadoc-paragraphs"/>
          <h4>Paragraphs</h4>
          <p>One blank line—that is, a line containing only the aligned leading asterisk
            (<code>*</code>)—appears between paragraphs, and before the group of "at-clauses" if
            present. Each paragraph but the first has <code>&lt;p&gt;</code> immediately before the first word,
            with no space after.</p>
          <a name="javadoc-at-clauses"/>
          <h4>At-clauses</h4>
          <p>Any of the standard "at-clauses" that are used appear in the order <code>@param</code>,
            <code>@return</code>, <code>@throws</code>, <code>@deprecated</code>, and these four types never
            appear with an empty description. When an at-clause doesn't fit on a single line, continuation lines
            are indented four (or more) spaces from the position of the <code>@</code>.
          </p>
            <a name="summary-fragment"/>
          <h3>The summary fragment</h3>
          <p>The Javadoc for each class and member begins with a brief <strong>summary fragment</strong>. This
            fragment is very important: it is the only part of the text that appears in certain contexts such as
            class and method indexes.</p><p>This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does
          <strong>not</strong> begin with <code>A {@code Foo} is a...</code>, or
          <code>This method returns...</code>, nor does it form a complete imperative sentence
          like <code>Save the record.</code>. However, the fragment is capitalized and
          punctuated as if it were a complete sentence.</p><p class="tip"><strong>Tip:</strong> A common mistake is to write simple Javadoc in the form
          <code>/** @return the customer ID */</code>. This is incorrect, and should be
          changed to <code>/** Returns the customer ID. */</code>.</p>
          <a name="javadoc-optional"/>
          <a name="javadoc-where-required"/>
          <h3>Where Javadoc is used</h3>
          <p>At the <em>minimum</em>, Javadoc is present for every
            <code>public</code> class, and every
            <code>public</code> or
            <code>protected</code> member of such a class, with a few exceptions
            noted below.</p><p>Other classes and members still have Javadoc <em>as needed</em>.  Whenever an implementation
          comment would be used to define the overall purpose or behavior of a class, method or field, that
          comment is written as Javadoc instead. (It's more uniform, and more tool-friendly.)</p>
          <a name="javadoc-exception-self-explanatory"/>
          <h4>Exception: self-explanatory methods</h4>
          <p>Javadoc is optional for "simple, obvious" methods like
            <code>getFoo</code>, in cases where there <em>really and truly</em> is
            nothing else worthwhile to say but "Returns the foo".</p>
            <p class="note"><strong>Important:</strong> it is not appropriate to cite this exception to justify
          omitting relevant information that a typical reader might need to know. For example, for a method
          named <code>getCanonicalName</code>, don't omit its documentation
          (with the rationale that it would say only
          <code>/** Returns the canonical name. */</code>) if a typical reader may have no idea
          what the term "canonical name" means!</p>
            <a name="javadoc-exception-overrides"/>
          <h4>Exception: overrides</h4>
          <p>Javadoc is not always present on a method that overrides a supertype method.
          </p>
          </subsection>
        </section>
      </body>
    </document>�������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/������������������������������������������������������0000775�0000000�0000000�00000000000�12577562624�0021106�5����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/api.xml�����������������������������������������������0000664�0000000�0000000�00000023472�12577562624�0022411�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 API</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="ggregory@apache.org">Gary Gregory</author>
        </properties>
    
        <body>
            <section name="Log4j 2 API">
              <a name="Overview"/>
              <subsection name="Overview">
                <p>
                  The Log4j 2 API provides the interface that applications should code to and provides the
                  adapter components required for implementers to create a logging implementation. Although Log4j 2
                  is broken up between an API and an implementation, the primary purpose of doing so was not to
                  allow multiple implementations, although that is certainly possible, but to clearly define
                  what classes and methods are safe to use in "normal" application code.
                </p>
                <h4>Hello World!</h4>
                <p>
                  No introduction would be complete without the customary Hello, World example. Here is ours. First,
                  a Logger with the name "HelloWorld" is obtained from the
                  <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html">LogManager</a>.
                  Next, the logger is used to write the "Hello, World!" message, however the message will be written
                  only if the Logger is configured to allow informational messages.
                </p>
                <pre class="prettyprint linenums">import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class HelloWorld {
        private static final Logger logger = LogManager.getLogger("HelloWorld");
        public static void main(String[] args) {
            logger.info("Hello, World!");
        }
    }</pre>
                <p>
                  The output from the call to logger.info() will vary significantly depending on the configuration
                  used. See the <a href="./configuration.html">Configuration</a> section for more details.
                </p>
                <h4>Substituting Parameters</h4>
                <p>
                  Frequently the purpose of logging is to provide information about what is happening in the system,
                  which requires including information about the objects being manipulated. In Log4j 1.x this could
                  be accomplished by doing:
                </p>
                <pre class="prettyprint linenums">if (logger.isDebugEnabled()) {
        logger.debug("Logging in user " + user.getName() + " with birthday " + user.getBirthdayCalendar());
    }</pre>
                <p>
                  Doing this repeatedly has the effect of making the code feel like it is more about logging than the
                  actual task at hand. In addition, it results in the logging level being checked twice; once on the
                  call to isDebugEnabled and once on the debug method. A better alternative would be:
                </p>
                <pre class="prettyprint">logger.debug("Logging in user {} with birthday {}", user.getName(), user.getBirthdayCalendar());</pre>
                <p>
                  With the code above the logging level will only be checked once and the String construction will
                  only occur when debug logging is enabled.
                </p>
                <h4>Formatting Parameters</h4>
                <p>
                  Substituting parameters leaves formatting up to you if <code>toString()</code> is not what you want.
                  To facilitate formatting, you can use the same format strings as Java's
                  <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax">Formatter</a>.
                  For example:
                </p>
                <pre class="prettyprint linenums">public static Logger logger = LogManager.getFormatterLogger("Foo");
    
    logger.debug("Logging in user %s with birthday %s", user.getName(), user.getBirthdayCalendar());
    logger.debug("Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
    logger.debug("Integer.MAX_VALUE = %,d", Integer.MAX_VALUE);
    logger.debug("Long.MAX_VALUE = %,d", Long.MAX_VALUE);
    </pre>
                <p>
                  To use a formatter Logger, you must call one of the LogManager
                  <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getFormatterLogger(java.lang.Class)">getFormatterLogger</a>
                  method. The output for this example shows that Calendar toString() is verbose compared to custom formatting:
                </p>
                <pre class="prettyprint linenums">2012-12-12 11:56:19,633 [main] DEBUG: User John Smith with birthday java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=sun.util.calendar.ZoneInfo[id="America/New_York",offset=-18000000,dstSavings=3600000,useDaylight=true,transitions=235,lastRule=java.util.SimpleTimeZone[id=America/New_York,offset=-18000000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=3,startMonth=2,startDay=8,startDayOfWeek=1,startTime=7200000,startTimeMode=0,endMode=3,endMonth=10,endDay=1,endDayOfWeek=1,endTime=7200000,endTimeMode=0]],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=?,YEAR=1995,MONTH=4,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=23,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
    2012-12-12 11:56:19,643 [main] DEBUG: User John Smith with birthday 05 23, 1995
    2012-12-12 11:56:19,643 [main] DEBUG: Integer.MAX_VALUE = 2,147,483,647
    2012-12-12 11:56:19,643 [main] DEBUG: Long.MAX_VALUE = 9,223,372,036,854,775,807
    </pre>
              <h4>Mixing Loggers with Formatter Loggers</h4>
              <p>
              Formatter loggers give fine-grained control over the output format, but have the drawback
              that the correct type must be specified (for example, passing anything other than a decimal integer
              for a %d format parameter gives an exception).
              </p>
              <p>
              If your main usage is to use {}-style parameters, but occasionally you need fine-grained
              control over the output format, you can use the <code>printf</code> method:</p>
                <pre class="prettyprint linenums">public static Logger logger = LogManager.getLogger("Foo");
    
    logger.debug("Opening connection to {}...", someDataSource);
    logger.printf(Level.INFO, "Logging in user %1$s with birthday %2$tm %2$te,%2$tY", user.getName(), user.getBirthdayCalendar());
    </pre>
    
              <a name="LambdaSupport"/>
                <h4>Java 8 lambda support for lazy logging</h4>
                <p>
                  In release 2.4, the <code>Logger</code> interface adds support for lambda expressions.
                  This allows client code to lazily log messages without explicitly checking if the requested log
                  level is enabled. For example, previously you would write:
                </p>
                <pre class="prettyprint linenums">// pre-Java 8 style optimization: explicitly check the log level
    // to make sure the expensiveOperation() method is only called if necessary
    if (logger.isTraceEnabled()) {
        logger.trace(&quot;Some long-running operation returned {}&quot;, expensiveOperation());
    }</pre>
                <p>
                  With Java 8 you can achieve the same effect with a lambda expression.
                  You no longer need to explicitly check the log level:
                </p>
                <pre class="prettyprint linenums">// Java-8 style optimization: no need to explicitly check the log level:
    // the lambda expression is not evaluated if the TRACE level is not enabled
    logger.trace(&quot;Some long-running operation returned {}&quot;, () -> expensiveOperation());</pre>
    
              <h4>Logger Names</h4>
                <p>
                  Most logging implementations use a hierarchical scheme for matching logger names with logging
                  configuration. In this scheme the logger name hierarchy is represented by '.' characters in the
                  logger name, in a fashion very similar to the hierarchy used for Java package names. For example,
                  org.apache.logging.appender and org.apache.logging.filter both have org.apache.logging as their parent.
                  In most cases, applications name their loggers by passing the current class's name to
                  LogManager.getLogger.  Because this usage is so common, Log4j 2 provides that as the default when
                  the logger name parameter is either omitted or is null. For example, in both examples below the Logger will
                  have a name of "org.apache.test.MyTest".
                </p>
                <pre class="prettyprint linenums">package org.apache.test;
    
    public class MyTest {
        private static final Logger logger = LogManager.getLogger(MyTest.class.getName());
    }
                </pre>
                <pre class="prettyprint linenums">package org.apache.test;
    
    public class MyTest {
        private static final Logger logger = LogManager.getLogger();
    }
                </pre>
              </subsection>
            </section>
        </body>
    </document>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/appenders.xml�����������������������������������������0000664�0000000�0000000�00000464643�12577562624�0023632�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0"?>
    <!--
        Licensed to the Apache Software Foundation (ASF) under one or more
        contributor license agreements.  See the NOTICE file distributed with
        this work for additional information regarding copyright ownership.
        The ASF licenses this file to You under the Apache License, Version 2.0
        (the "License"); you may not use this file except in compliance with
        the License.  You may obtain a copy of the License at
    
             http://www.apache.org/licenses/LICENSE-2.0
    
        Unless required by applicable law or agreed to in writing, software
        distributed under the License is distributed on an "AS IS" BASIS,
        WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
        See the License for the specific language governing permissions and
        limitations under the License.
    -->
    
    <document xmlns="http://maven.apache.org/XDOC/2.0"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
              xsi:schemaLocation="http://maven.apache.org/XDOC/2.0 http://maven.apache.org/xsd/xdoc-2.0.xsd">
        <properties>
            <title>Log4j 2 Appenders</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="ggrgeory@apache.org">Gary Gregory</author>
            <author email="nickwilliams@apache.org">Nick Williams</author>
        </properties>
    
        <body>
          <section name="Appenders">
            <p>
              Appenders are responsible for delivering LogEvents to their destination. Every Appender must
              implement the <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html">Appender</a>
              interface. Most Appenders will extend
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/appender/AbstractAppender.html">AbstractAppender</a>
              which adds <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/LifeCycle.html">Lifecycle</a>
              and <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/filter/Filterable.html">Filterable</a>
              support. Lifecycle allows components to finish initialization after configuration has completed and to
              perform cleanup during shutdown. Filterable allows the component to have Filters attached to it which are
              evaluated during event processing.
            </p>
            <p>
              Appenders usually are only responsible for writing the event data to the target destination. In most cases
              they delegate responsibility for formatting the event to a <a href="layouts.html">layout</a>. Some
              appenders wrap other appenders so that they can modify the LogEvent, handle a failure in an Appender,
              route the event to a subordinate Appender based on advanced Filter criteria or provide similar functionality
              that does not directly format the event for viewing.
            </p>
            <p>
              Appenders always have a name so that they can be referenced from Loggers.
            </p>
            <a name="AsyncAppender"/>
            <subsection name="AsyncAppender">
              <p>The AsyncAppender accepts references to other Appenders and causes LogEvents to be written to them
                on a separate Thread. Note that exceptions while writing to those Appenders will be hidden from
                the application. The AsyncAppender should be configured after the appenders it references to allow it
                to shut down properly.</p>
              <table>
                <caption align="top">AsyncAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>AppenderRef</td>
                  <td>String</td>
                  <td>The name of the Appenders to invoke asynchronously. Multiple AppenderRef
                    elements can be configured.</td>
                </tr>
                <tr>
                  <td>blocking</td>
                  <td>boolean</td>
                  <td>If true, the appender will wait until there are free slots in the queue. If false, the event
                    will be written to the error appender if the queue is full. The default is true.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>integer</td>
                  <td>Specifies the maximum number of events that can be queued. The default is 128.</td>
                </tr>
                <tr>
                  <td>errorRef</td>
                  <td>String</td>
                  <td>The name of the Appender to invoke if none of the appenders can be called, either due to errors
                    in the appenders or because the queue is full. If not specified then errors will be ignored.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                    may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>includeLocation</td>
                  <td>boolean</td>
                  <td>Extracting location is an expensive operation (it can make
                  logging 5 - 20 times slower). To improve performance, location is
                  not included by default when adding a log event to the queue.
                  You can change this by setting includeLocation="true".</td>
                </tr>
              </table>
              <p>
                A typical AsyncAppender configuration might look like:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <File name="MyFile" fileName="logs/app.log">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
        </File>
        <Async name="Async">
          <AppenderRef ref="MyFile"/>
        </Async>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Async"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="ConsoleAppender"/>
            <subsection name="ConsoleAppender">
              <p>
                As one might expect, the ConsoleAppender writes its output to either System.err or System.out with System.err
                being the default target. A Layout must be provided to format the LogEvent.
              </p>
              <table>
                <caption align="top">ConsoleAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent. If no layout is supplied the default pattern layout
                  of "%m%n" will be used.</td>
                </tr>
                <tr>
                  <td>follow</td>
                  <td>boolean</td>
                  <td>Identifies whether the appender honors reassignments of System.out or System.err
                    via System.setOut or System.setErr made after configuration. Note that the follow
                    attribute cannot be used with Jansi on Windows.</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>target</td>
                  <td>String</td>
                  <td>Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is "SYSTEM_ERR".</td>
                </tr>
              </table>
              <p>
                A typical Console configuration might look like:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="FailoverAppender"/>
            <subsection name="FailoverAppender">
              <p>The FailoverAppender wraps a set of appenders. If the primary Appender fails the secondary appenders will be
              tried in order until one succeeds or there are no more secondaries to try.</p>
              <table>
                <caption align="top">FailoverAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>primary</td>
                  <td>String</td>
                  <td>The name of the primary Appender to use.</td>
                </tr>
                <tr>
                  <td>failovers</td>
                  <td>String[]</td>
                  <td>The names of the secondary Appenders to use.</td>
                </tr>
    
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>retryIntervalSeconds</td>
                  <td>integer</td>
                  <td>The number of seconds that should pass before retrying the primary Appender. The default is 60.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead.</td>
                </tr>
                <tr>
                  <td>target</td>
                  <td>String</td>
                  <td>Either "SYSTEM_OUT" or "SYSTEM_ERR". The default is "SYSTEM_ERR".</td>
                </tr>
              </table>
              <p>
                A Failover configuration might look like:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{MM-dd-yyyy}.log.gz"
                     ignoreExceptions="false">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <TimeBasedTriggeringPolicy />
        </RollingFile>
        <Console name="STDOUT" target="SYSTEM_OUT" ignoreExceptions="false">
          <PatternLayout pattern="%m%n"/>
        </Console>
        <Failover name="Failover" primary="RollingFile">
          <Failovers>
            <AppenderRef ref="Console"/>
          </Failovers>
        </Failover>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Failover"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="FileAppender"/>
            <subsection name="FileAppender">
              <p>The FileAppender is an OutputStreamAppender that writes to the File named in the fileName parameter. The
                FileAppender uses a FileManager (which extends OutputStreamManager) to actually perform the file I/O. While
                FileAppenders from different Configurations cannot be shared, the FileManagers can be if the Manager is
                accessible. For example, two web applications in a servlet container can have their own configuration and
                safely write to the same file if Log4j is in a ClassLoader that is common to both of them.</p>
              <table>
                <caption align="top">FileAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>append</td>
                  <td>boolean</td>
                  <td>When true - the default, records will be appended to the end of the file. When set to false,
                    the file will be cleared before new records are written.</td>
                </tr>
                <tr>
                  <td>bufferedIO</td>
                  <td>boolean</td>
                  <td>When true - the default, records will be written to a buffer and the data will be written to
                    disk when the buffer is full or, if immediateFlush is set, when the record is written.
                    File locking cannot be used with bufferedIO. Performance tests have shown that using buffered I/O
                    significantly improves performance, even if immediateFlush is enabled.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>int</td>
                  <td>When bufferedIO is true, this is the buffer size, the default is 8192 bytes.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>fileName</td>
                  <td>String</td>
                  <td>The name of the file to write to. If the file, or any of its parent directories, do not exist,
                    they will be created.</td>
                </tr>
                <tr>
                  <td>immediateFlush</td>
                  <td>boolean</td>
                  <td><p>When set to true - the default, each write will be followed by a flush.
                    This will guarantee the data is written
                    to disk but could impact performance.</p>
                    <p>Flushing after every write is only useful when using this
    				appender with synchronous loggers. Asynchronous loggers and
    				appenders will automatically flush at the end of a batch of events,
    				even if immediateFlush is set to false. This also guarantees
    				the data is written to disk but is more efficient.</p>
                  </td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent</td>
                </tr>
                <tr>
                  <td>locking</td>
                  <td>boolean</td>
                  <td>When set to true, I/O operations will occur only while the file lock is held allowing FileAppenders
                    in multiple JVMs and potentially multiple hosts to write to the same file simultaneously. This
                    will significantly impact performance so should be used carefully. Furthermore, on many systems
                    the file lock is "advisory" meaning that other applications can perform operations on the file
                    without acquiring a lock. The default value is false.</td>
                </tr>
    
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
              </table>
              <p>
                Here is a sample File configuration:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <File name="MyFile" fileName="logs/app.log">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
        </File>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="MyFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="FlumeAppender"/>
            <subsection name="FlumeAppender">
              <p><i>This is an optional component supplied in a separate jar.</i></p>
              <p><a href="http://flume.apache.org/index.html">Apache Flume</a> is a distributed, reliable,
                and available system for efficiently collecting, aggregating, and moving large amounts of log data
                from many different sources to a centralized data store. The FlumeAppender takes LogEvents and sends
                them to a Flume agent as serialized Avro events for consumption.</p>
              <p>
                The Flume Appender supports three modes of operation.
              </p>
                <ol>
                  <li>It can act as a remote Flume client which sends Flume events via Avro to a Flume Agent configured
                  with an Avro Source.</li>
                  <li>It can act as an embedded Flume Agent where Flume events pass directly into Flume for processing.</li>
                  <li>It can persist events to a local BerkeleyDB data store and then asynchronously send the events to
                  Flume, similar to the embedded Flume Agent but without most of the Flume dependencies.</li>
                </ol>
              <p>
                Usage as an embedded agent will cause the messages to be directly passed to the Flume Channel and then
                control will be immediately returned to the application. All interaction with remote agents will occur
                asynchronously. Setting the "type" attribute to "Embedded" will force the use of the embedded agent. In
                addition, configuring agent properties in the appender configuration will also cause the embedded agent
                to be used.
              </p>
              <table>
                <caption align="top">FlumeAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>agents</td>
                  <td>Agent[]</td>
                  <td>An array of Agents to which the logging events should be sent. If more than one agent is specified
                    the first Agent will be the primary and subsequent Agents will be used in the order specified as
                    secondaries should the primary Agent fail. Each Agent definition supplies the Agents host and port.
                    The specification of agents and properties are mutually exclusive. If both are configured an
                    error will result.</td>
                </tr>
                <tr>
                  <td>agentRetries</td>
                  <td>integer</td>
                  <td>The number of times the agent should be retried before failing to a secondary. This parameter is
                    ignored when type="persistent" is specified (agents are tried once before failing to the next).</td>
                </tr>
                <tr>
                  <td>batchSize</td>
                  <td>integer</td>
                  <td>Specifies the number of events that should be sent as a batch. The default is 1. <i>This
                    parameter only applies to the Flume Appender.</i></td>
                </tr>
                <tr>
                  <td>compress</td>
                  <td>boolean</td>
                  <td>When set to true the message body will be compressed using gzip</td>
                </tr>
                <tr>
                  <td>connectTimeoutMillis</td>
                  <td>integer</td>
                  <td>The number of milliseconds Flume will wait before timing out the connection.</td>
                </tr>
                <tr>
                  <td>dataDir</td>
                  <td>String</td>
                  <td>Directory where the Flume write ahead log should be written. Valid only when embedded is set
                    to true and Agent elements are used instead of Property elements.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>eventPrefix</td>
                  <td>String</td>
                  <td>The character string to prepend to each event attribute in order to distinguish it from MDC attributes.
                    The default is an empty string.</td>
                </tr>
                <tr>
                  <td>flumeEventFactory</td>
                  <td>FlumeEventFactory</td>
                  <td>Factory that generates the Flume events from Log4j events. The default factory is the
                    FlumeAvroAppender itself.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent. If no layout is specified RFC5424Layout will be used.</td>
                </tr>
                <tr>
                  <td>lockTimeoutRetries</td>
                  <td>integer</td>
                  <td>The number of times to retry if a LockConflictException occurs while writing to Berkeley DB. The
                    default is 5.</td>
                </tr>
                <tr>
                  <td>maxDelayMillis</td>
                  <td>integer</td>
                  <td>The maximum number of milliseconds to wait for batchSize events before publishing the batch.</td>
                </tr>
                <tr>
                  <td>mdcExcludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be excluded from the FlumeEvent. This is mutually
                    exclusive with the mdcIncludes attribute.</td>
                </tr>
                <tr>
                  <td>mdcIncludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC
                    not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes
                    attribute.</td>
                </tr>
                <tr>
                  <td>mdcRequired</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that must be present in the MDC. If a key is not present a
                    LoggingException will be thrown.</td>
                </tr>
                <tr>
                  <td>mdcPrefix</td>
                  <td>String</td>
                  <td>A string that should be prepended to each MDC key in order to distinguish it from event attributes.
                    The default string is "mdc:".</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>properties</td>
                  <td>Property[]</td>
                  <td><p>One or more Property elements that are used to configure the Flume Agent. The properties must be
                    configured without the agent name (the appender name is used for this) and no sources can be
                    configured. Interceptors can be specified for the source using "sources.log4j-source.interceptors".
                    All other Flume configuration properties are allowed. Specifying both Agent and Property
                    elements will result in an error.</p>
                    <p>When used to configure in Persistent mode the valid properties are:</p>
                    <ol>
                      <li>"keyProvider" to specify the name of the plugin to provide the secret key for encryption.</li>
                    </ol>
                  </td>
                </tr>
                <tr>
                  <td>requestTimeoutMillis</td>
                  <td>integer</td>
                  <td>The number of milliseconds Flume will wait before timing out the request.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>type</td>
                  <td>enumeration</td>
                  <td>One of "Avro", "Embedded", or "Persistent" to indicate which variation of the Appender is desired.</td>
                </tr>
              </table>
                <p>
                  A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
                  compresses the body, and formats the body using the RFC5424Layout:
                </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Flume name="eventLogger" compress="true">
          <Agent host="192.168.10.101" port="8800"/>
          <Agent host="192.168.10.102" port="8800"/>
          <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
        </Flume>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="eventLogger"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
                compresses the body, formats the body using the RFC5424Layout, and persists encrypted events to disk:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Flume name="eventLogger" compress="true" type="persistent" dataDir="./logData">
          <Agent host="192.168.10.101" port="8800"/>
          <Agent host="192.168.10.102" port="8800"/>
          <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
          <Property name="keyProvider">MySecretProvider</Property>
        </Flume>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="eventLogger"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                A sample FlumeAppender configuration that is configured with a primary and a secondary agent,
                compresses the body, formats the body using RFC5424Layout and passes the events to an embedded Flume
                Agent.
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Flume name="eventLogger" compress="true" type="Embedded">
          <Agent host="192.168.10.101" port="8800"/>
          <Agent host="192.168.10.102" port="8800"/>
          <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
        </Flume>
        <Console name="STDOUT">
          <PatternLayout pattern="%d [%p] %c %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="EventLogger" level="info">
          <AppenderRef ref="eventLogger"/>
        </Logger>
        <Root level="warn">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                A sample FlumeAppender configuration that is configured with a primary and a secondary agent using
                Flume configuration properties, compresses the body, formats the body using RFC5424Layout and passes the
                events to an embedded Flume Agent.
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error" name="MyApp" packages="">
      <Appenders>
        <Flume name="eventLogger" compress="true" type="Embedded">
          <Property name="channels">file</Property>
          <Property name="channels.file.type">file</Property>
          <Property name="channels.file.checkpointDir">target/file-channel/checkpoint</Property>
          <Property name="channels.file.dataDirs">target/file-channel/data</Property>
          <Property name="sinks">agent1 agent2</Property>
          <Property name="sinks.agent1.channel">file</Property>
          <Property name="sinks.agent1.type">avro</Property>
          <Property name="sinks.agent1.hostname">192.168.10.101</Property>
          <Property name="sinks.agent1.port">8800</Property>
          <Property name="sinks.agent1.batch-size">100</Property>
          <Property name="sinks.agent2.channel">file</Property>
          <Property name="sinks.agent2.type">avro</Property>
          <Property name="sinks.agent2.hostname">192.168.10.102</Property>
          <Property name="sinks.agent2.port">8800</Property>
          <Property name="sinks.agent2.batch-size">100</Property>
          <Property name="sinkgroups">group1</Property>
          <Property name="sinkgroups.group1.sinks">agent1 agent2</Property>
          <Property name="sinkgroups.group1.processor.type">failover</Property>
          <Property name="sinkgroups.group1.processor.priority.agent1">10</Property>
          <Property name="sinkgroups.group1.processor.priority.agent2">5</Property>
          <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
        </Flume>
        <Console name="STDOUT">
          <PatternLayout pattern="%d [%p] %c %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="EventLogger" level="info">
          <AppenderRef ref="eventLogger"/>
        </Logger>
        <Root level="warn">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="JDBCAppender"/>
            <subsection name="JDBCAppender">
              <p>The JDBCAppender writes log events to a relational database table using standard JDBC. It can be configured
                to obtain JDBC connections using a JNDI <code>DataSource</code> or a custom factory method. Whichever
                approach you take, it <strong><em>must</em></strong> be backed by a connection pool. Otherwise, logging
                performance will suffer greatly.</p>
              <table>
                <caption align="top">JDBCAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be
                    used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>int</td>
                  <td>If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
                    buffer reaches this size.</td>
                </tr>
                <tr>
                  <td>connectionSource</td>
                  <td>ConnectionSource</td>
                  <td><em>Required.</em> The connections source from which database connections should be retrieved.</td>
                </tr>
                <tr>
                  <td>tableName</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the database table to insert log events into.</td>
                </tr>
                <tr>
                  <td>columnConfigs</td>
                  <td>ColumnConfig[]</td>
                  <td><em>Required.</em> Information about the columns that log event data should be inserted into and how
                    to insert that data. This is represented with multiple <code>&lt;Column&gt;</code> elements.</td>
                </tr>
              </table>
              <p>When configuring the JDBCAppender, you must specify a <code>ConnectionSource</code> implementation from
                which the Appender gets JDBC connections. You must use exactly one of the <code>&lt;DataSource&gt;</code>
                or <code>&lt;ConnectionFactory&gt;</code> nested elements.</p>
              <table>
                <caption align="top">DataSource Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>jndiName</td>
                  <td>String</td>
                  <td><em>Required.</em> The full, prefixed JNDI name that the <code>javax.sql.DataSource</code> is bound
                    to, such as <code>java:/comp/env/jdbc/LoggingDatabase</code>. The <code>DataSource</code> must be backed
                    by a connection pool; otherwise, logging will be very slow.</td>
                </tr>
              </table>
              <table>
                <caption align="top">ConnectionFactory Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>class</td>
                  <td>Class</td>
                  <td><em>Required.</em> The fully qualified name of a class containing a static factory method for
                    obtaining JDBC connections.</td>
                </tr>
                <tr>
                  <td>method</td>
                  <td>Method</td>
                  <td><em>Required.</em> The name of a static factory method for obtaining JDBC connections. This method
                    must have no parameters and its return type must be either <code>java.sql.Connection</code> or
                    <code>DataSource</code>. If the method returns <code>Connection</code>s, it must obtain them from a
                    connection pool (and they will be returned to the pool when Log4j is done with them); otherwise, logging
                    will be very slow. If the method returns a <code>DataSource</code>, the <code>DataSource</code> will
                    only be retrieved once, and it must be backed by a connection pool for the same reasons.</td>
                </tr>
              </table>
              <p>When configuring the JDBCAppender, use the nested <code>&lt;Column&gt;</code> elements to specify which
                columns in the table should be written to and how to write to them. The JDBCAppender uses this information
                to formulate a <code>PreparedStatement</code> to insert records without SQL injection vulnerability.</p>
              <table>
                <caption align="top">Column Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the database column.</td>
                </tr>
                <tr>
                  <td>pattern</td>
                  <td>String</td>
                  <td>Use this attribute to insert a value or values from the log event in this column using a
                    <code>PatternLayout</code> pattern. Simply specify any legal pattern in this attribute. Either this
                    attribute, <code>literal</code>, or <code>isEventTimestamp="true"</code> must be specified, but not more
                    than one of these.</td>
                </tr>
                <tr>
                  <td>literal</td>
                  <td>String</td>
                  <td>Use this attribute to insert a literal value in this column. The value will be included directly in
                    the insert SQL, without any quoting (which means that if you want this to be a string, your value should
                    contain single quotes around it like this: <code>literal="'Literal String'"</code>). This is especially
                    useful for databases that don't support identity columns. For example, if you are using Oracle you could
                    specify <code>literal="NAME_OF_YOUR_SEQUENCE.NEXTVAL"</code> to insert a unique ID in an ID column.
                    Either this attribute, <code>pattern</code>, or <code>isEventTimestamp="true"</code> must be specified,
                    but not more than one of these.</td>
                </tr>
                <tr>
                  <td>isEventTimestamp</td>
                  <td>boolean</td>
                  <td>Use this attribute to insert the event timestamp in this column, which should be a SQL datetime. The
                    value will be inserted as a <code>java.sql.Types.TIMESTAMP</code>. Either this attribute (equal to
                    <code>true</code>), <code>pattern</code>, or <code>isEventTimestamp</code> must be specified, but not
                    more than one of these.</td>
                </tr>
                <tr>
                  <td>isUnicode</td>
                  <td>boolean</td>
                  <td>This attribute is ignored unless <code>pattern</code> is specified. If <code>true</code> or omitted
                    (default), the value will be inserted as unicode (<code>setNString</code> or <code>setNClob</code>).
                    Otherwise, the value will be inserted non-unicode (<code>setString</code> or <code>setClob</code>).</td>
                </tr>
                <tr>
                  <td>isClob</td>
                  <td>boolean</td>
                  <td>This attribute is ignored unless <code>pattern</code> is specified. Use this attribute to indicate
                    that the column stores Character Large Objects (CLOBs). If <code>true</code>, the value will be inserted
                    as a CLOB (<code>setClob</code> or <code>setNClob</code>). If <code>false</code> or omitted (default),
                    the value will be inserted as a VARCHAR or NVARCHAR (<code>setString</code> or <code>setNString</code>).
                  </td>
                </tr>
              </table>
              <p>
                Here are a couple sample configurations for the JDBCAppender, as well as a sample factory implementation
                that uses Commons Pooling and Commons DBCP to pool database connections:
              </p>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <JDBC name="databaseAppender" tableName="dbo.application_log">
          <DataSource jndiName="java:/comp/env/jdbc/LoggingDataSource" />
          <Column name="eventDate" isEventTimestamp="true" />
          <Column name="level" pattern="%level" />
          <Column name="logger" pattern="%logger" />
          <Column name="message" pattern="%message" />
          <Column name="exception" pattern="%ex{full}" />
        </JDBC>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <JDBC name="databaseAppender" tableName="LOGGING.APPLICATION_LOG">
          <ConnectionFactory class="net.example.db.ConnectionFactory" method="getDatabaseConnection" />
          <Column name="EVENT_ID" literal="LOGGING.APPLICATION_LOG_SEQUENCE.NEXTVAL" />
          <Column name="EVENT_DATE" isEventTimestamp="true" />
          <Column name="LEVEL" pattern="%level" />
          <Column name="LOGGER" pattern="%logger" />
          <Column name="MESSAGE" pattern="%message" />
          <Column name="THROWABLE" pattern="%ex{full}" />
        </JDBC>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
                <pre class="prettyprint linenums lang-java"><![CDATA[package net.example.db;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.Properties;
    
    import javax.sql.DataSource;
    
    import org.apache.commons.dbcp.DriverManagerConnectionFactory;
    import org.apache.commons.dbcp.PoolableConnection;
    import org.apache.commons.dbcp.PoolableConnectionFactory;
    import org.apache.commons.dbcp.PoolingDataSource;
    import org.apache.commons.pool.impl.GenericObjectPool;
    
    public class ConnectionFactory {
        private static interface Singleton {
            final ConnectionFactory INSTANCE = new ConnectionFactory();
        }
    
        private final DataSource dataSource;
    
        private ConnectionFactory() {
            Properties properties = new Properties();
            properties.setProperty("user", "logging");
            properties.setProperty("password", "abc123"); // or get properties from some configuration file
    
            GenericObjectPool<PoolableConnection> pool = new GenericObjectPool<PoolableConnection>();
            DriverManagerConnectionFactory connectionFactory = new DriverManagerConnectionFactory(
                    "jdbc:mysql://example.org:3306/exampleDb", properties
            );
            new PoolableConnectionFactory(
                    connectionFactory, pool, null, "SELECT 1", 3, false, false, Connection.TRANSACTION_READ_COMMITTED
            );
    
            this.dataSource = new PoolingDataSource(pool);
        }
    
        public static Connection getDatabaseConnection() throws SQLException {
            return Singleton.INSTANCE.dataSource.getConnection();
        }
    }]]></pre>
            </subsection>
            <a name="JMSAppender"/>
            <!-- cool URLs don't change, so here are some old anchors -->
            <a name="JMSQueueAppender"/>
            <a name="JMSTopicAppender"/>
            <subsection name="JMSAppender">
              <p>The JMSAppender sends the formatted log event to a JMS Destination.</p>
              <p>
                Note that in Log4j 2.0, this appender was split into a JMSQueueAppender and a JMSTopicAppender. Starting
                in Log4j 2.1, these appenders were combined into the JMSAppender which makes no distinction between queues
                and topics. However, configurations written for 2.0 which use the <code>&lt;JMSQueue/&gt;</code> or
                <code>&lt;JMSTopic/&gt;</code> elements will continue to work with the new <code>&lt;JMS/&gt;</code>
                configuration element.
              </p>
              <table>
                <caption align="top">JMSAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>factoryBindingName</td>
                  <td>String</td>
                  <td>The name to locate in the Context that provides the
                    <a class="javadoc" href="http://download.oracle.com/javaee/5/api/javax/jms/ConnectionFactory.html">ConnectionFactory</a>.
                    This can be any subinterface of <code>ConnectionFactory</code> as well. This attribute is required.
                  </td>
                </tr>
                <tr>
                  <td>factoryName</td>
                  <td>String</td>
                  <td>The fully qualified class name that should be used to define the Initial Context Factory as defined in
                    <a class="javadoc" href="http://download.oracle.com/javase/6/docs/api/javax/naming/Context.html#INITIAL_CONTEXT_FACTORY">INITIAL_CONTEXT_FACTORY</a>.
                    If no value is provided the
                    default InitialContextFactory will be used. If a factoryName is specified without a providerURL
                    a warning message will be logged as this is likely to cause problems.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>
                    The Layout to use to format the LogEvent. If you do not specify a layout,
                    this appender will use a <a href="layouts.html#SerializedLayout">SerializedLayout</a>.
                  </td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender. Required.</td>
                </tr>
                <tr>
                  <td>password</td>
                  <td>String</td>
                  <td>The password to use to create the JMS connection.</td>
                </tr>
                <tr>
                  <td>providerURL</td>
                  <td>String</td>
                  <td>The URL of the provider to use as defined by
                    <a class="javadoc" href="http://download.oracle.com/javase/6/docs/api/javax/naming/Context.html#PROVIDER_URL">PROVIDER_URL</a>.
                    If this value is null the default system provider will be used.</td>
                </tr>
                <tr>
                  <td>destinationBindingName</td>
                  <td>String</td>
                  <td>
                    The name to use to locate the
                    <a class="javadoc" href="http://download.oracle.com/javaee/5/api/javax/jms/Destination.html">Destination</a>.
                    This can be a <code>Queue</code> or <code>Topic</code>, and as such, the attribute names
                    <code>queueBindingName</code> and <code>topicBindingName</code> are aliases to maintain compatibility
                    with the Log4j 2.0 JMS appenders.
                  </td>
                </tr>
                <tr>
                  <td>securityPrincipalName</td>
                  <td>String</td>
                  <td>The name of the identity of the Principal as specified by
                    <a class="javadoc" href="http://download.oracle.com/javase/6/docs/api/javax/naming/Context.html#SECURITY_PRINCIPAL">SECURITY_PRINCIPAL</a>.
                    If a securityPrincipalName is specified without securityCredentials a warning message will be
                    logged as this is likely to cause problems.</td>
                </tr>
                <tr>
                  <td>securityCredentials</td>
                  <td>String</td>
                  <td>The security credentials for the principal as specified by
                    <a class="javadoc" href="http://download.oracle.com/javase/6/docs/api/javax/naming/Context.html#SECURITY_CREDENTIALS">SECURITY_CREDENTIALS</a>.
                  </td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>urlPkgPrefixes</td>
                  <td>String</td>
                  <td>A colon-separated list of package prefixes for the class name of the factory class that will create
                    a URL context factory as defined by
                    <a class="javadoc" href="http://download.oracle.com/javase/6/docs/api/javax/naming/Context.html#URL_PKG_PREFIXES">URL_PKG_PREFIXES</a>.
                  </td>
                </tr>
                <tr>
                  <td>userName</td>
                  <td>String</td>
                  <td>The user id used to create the JMS connection.</td>
                </tr>
              </table>
              <p>
                Here is a sample JMSAppender configuration:
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp">
      <Appenders>
        <JMS name="jmsQueue" destinationBindingName="MyQueue"
             factoryBindingName="MyQueueConnectionFactory"/>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="jmsQueue"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="JPAAppender"/>
            <subsection name="JPAAppender">
              <p>The JPAAppender writes log events to a relational database table using the Java Persistence API 2.1.
                It requires the API and a provider implementation be on the classpath. It also requires a decorated entity
                configured to persist to the table desired. The entity should either extend
                <code>org.apache.logging.log4j.core.appender.db.jpa.BasicLogEventEntity</code> (if you mostly want to
                use the default mappings) and provide at least an <code>@Id</code> property, or
                <code>org.apache.logging.log4j.core.appender.db.jpa.AbstractLogEventWrapperEntity</code> (if you want
                to significantly customize the mappings). See the Javadoc for these two classes for more information. You
                can also consult the source code of these two classes as an example of how to implement the entity.</p>
              <table>
                <caption align="top">JPAAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be
                    used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>int</td>
                  <td>If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
                    buffer reaches this size.</td>
                </tr>
                <tr>
                  <td>entityClassName</td>
                  <td>String</td>
                  <td><em>Required.</em> The fully qualified name of the concrete LogEventWrapperEntity implementation that
                    has JPA annotations mapping it to a database table.</td>
                </tr>
                <tr>
                  <td>persistenceUnitName</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the JPA persistence unit that should be used for persisting log
                    events.</td>
                </tr>
              </table>
              <p>
                Here is a sample configuration for the JPAAppender. The first XML sample is the Log4j configuration file,
                the second is the <code>persistence.xml</code> file. EclipseLink is assumed here, but any JPA 2.1 or higher
                provider will do. You should <em>always</em> create a <em>separate</em> persistence unit for logging, for
                two reasons. First, <code>&lt;shared-cache-mode&gt;</code> <em>must</em> be set to "NONE," which is usually
                not desired in normal JPA usage. Also, for performance reasons the logging entity should be isolated in its
                own persistence unit away from all other entities and you should use a non-JTA data source. Note that your
                persistence unit <em>must</em> also contain <code>&lt;class&gt;</code> elements for all of the
                <code>org.apache.logging.log4j.core.appender.db.jpa.converter</code> converter classes.
              </p>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <JPA name="databaseAppender" persistenceUnitName="loggingPersistenceUnit"
             entityClassName="com.example.logging.JpaLogEntity" />
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence
                                     http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"
                 version="2.1">
    
      <persistence-unit name="loggingPersistenceUnit" transaction-type="RESOURCE_LOCAL">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextMapJsonAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ContextStackJsonAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.MarkerAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.MessageAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.StackTraceElementAttributeConverter</class>
        <class>org.apache.logging.log4j.core.appender.db.jpa.converter.ThrowableAttributeConverter</class>
        <class>com.example.logging.JpaLogEntity</class>
        <non-jta-data-source>jdbc/LoggingDataSource</non-jta-data-source>
        <shared-cache-mode>NONE</shared-cache-mode>
      </persistence-unit>
    
    </persistence>]]></pre>
    
                <pre class="prettyprint linenums lang-java"><![CDATA[package com.example.logging;
    ...
    @Entity
    @Table(name="application_log", schema="dbo")
    public class JpaLogEntity extends BasicLogEventEntity {
        private static final long serialVersionUID = 1L;
        private long id = 0L;
    
        public TestEntity() {
            super(null);
        }
        public TestEntity(LogEvent wrappedEvent) {
            super(wrappedEvent);
        }
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "id")
        public long getId() {
            return this.id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        // If you want to override the mapping of any properties mapped in BasicLogEventEntity,
        // just override the getters and re-specify the annotations.
    }]]></pre>
    
                <pre class="prettyprint linenums lang-java"><![CDATA[package com.example.logging;
    ...
    @Entity
    @Table(name="application_log", schema="dbo")
    public class JpaLogEntity extends AbstractLogEventWrapperEntity {
        private static final long serialVersionUID = 1L;
        private long id = 0L;
    
        public TestEntity() {
            super(null);
        }
        public TestEntity(LogEvent wrappedEvent) {
            super(wrappedEvent);
        }
    
        @Id
        @GeneratedValue(strategy = GenerationType.IDENTITY)
        @Column(name = "logEventId")
        public long getId() {
            return this.id;
        }
    
        public void setId(long id) {
            this.id = id;
        }
    
        @Override
        @Enumerated(EnumType.STRING)
        @Column(name = "level")
        public Level getLevel() {
            return this.getWrappedEvent().getLevel();
        }
    
        @Override
        @Column(name = "logger")
        public String getLoggerName() {
            return this.getWrappedEvent().getLoggerName();
        }
    
        @Override
        @Column(name = "message")
        @Convert(converter = MyMessageConverter.class)
        public Message getMessage() {
            return this.getWrappedEvent().getMessage();
        }
        ...
    }]]></pre>
            </subsection>
            <a name="KafkaAppender"/>
            <subsection name="KafkaAppender">
              <p>The KafkaAppender log events to an Apache Kafka topic.</p>
              <table>
                <caption align="top">KafkaAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>topic</td>
                  <td>String</td>
                  <td>The Kafka topic to use. Required.</td>
                </tr>
                <tr>
                  <td>lilter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                    may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>
                    The Layout to use to format the LogEvent. If you do not specify a layout,
                    if not specified the <a class="javadoc" href="http://logging.apache.org/log4j/2.x/log4j-api/apidocs/org/apache/logging/log4j/message/Message.html#getFormattedMessage())">formatted message</a>
                    as an UTF-8 encoded string will be sent to Kafka.
                  </td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender. Required.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>properties</td>
                  <td>Property</td>
                  <td>
                    You can set any properties in <a href="http://kafka.apache.org/documentation.html#newproducerconfigs">Kafka new producer properties</a>.
                    You need to set the <code>bootstrap.servers</code> property, there are sensible default values for the others.
                  </td>
                </tr>
              </table>
              <p>
                Here is a sample KafkaAppender configuration snippet:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
      ...
      <Appenders>
        <Kafka name="Kafka" topic="log-test">
          <PatternLayout pattern="%date %message"/>
            <Property name="bootstrap.servers">localhost:9092</Property>
        </Kafka>
      </Appenders>]]></pre>
              <p>
                This appender is synchronous and will block until the record has been acknowledged by the Kafka server, timeout for this
                can be set with the <code>timeout.ms</code> property (defaults to 30 seconds). Wrap with
                <a href="http://logging.apache.org/log4j/2.x/manual/appenders.html#AsyncAppender">Async appender</a> to log asynchronously.
              </p>
              <p>
                This appender requires <a href="http://search.maven.org/#artifactdetails|org.apache.kafka|kafka-clients|0.8.2.1|jar">Kafka client library</a>
              </p>
              <p>
                <em>Note:</em>Make sure to not let <code>org.apache.kafka</code> log to a Kafka appender on DEBUG level,
                since that will cause recursive logging:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
      ...
      <Loggers>
        <Root level="DEBUG">
          <AppenderRef ref="Kafka"/>
        </Root>
        <Logger name="org.apache.kafka" level="INFO" /> <!-- avoid recursive logging -->
      </Loggers>]]></pre>
            </subsection>
          <a name="MemoryMappedFileAppender" />
          <subsection name="MemoryMappedFileAppender">
            <p><i>New since 2.1. Be aware that this is a new addition, and although it has been
              tested on several platforms, it does not have as much track record as the other file appenders.</i></p>
            <p>
              The MemoryMappedFileAppender maps a part of the specified file into memory
              and writes log events to this memory, relying on the operating system's
              virtual memory manager to synchronize the changes to the storage device.
              The main benefit of using memory mapped files is I/O performance. Instead of making system
              calls to write to disk, this appender can simply change the program's local memory,
              which is orders of magnitude faster. Also, in most operating systems the memory
              region mapped actually is the kernel's <a href="http://en.wikipedia.org/wiki/Page_cache">page
              cache</a> (file cache), meaning that no copies need to be created in user space.
              (TODO: performance tests that compare performance of this appender to
              RandomAccessFileAppender and FileAppender.)
            </p>
            <p>
              There is some overhead with mapping a file region into memory,
              especially very large regions (half a gigabyte or more).
              The default region size is 32 MB, which should strike a reasonable balance
              between the frequency and the duration of remap operations.
              (TODO: performance test remapping various sizes.)
            </p>
            <p>
              Similar to the FileAppender and the RandomAccessFileAppender,
              MemoryMappedFileAppender uses a MemoryMappedFileManager to actually perform the
              file I/O. While MemoryMappedFileAppender from different Configurations
              cannot be shared, the MemoryMappedFileManagers can be if the Manager is
              accessible. For example, two web applications in a servlet container can have
              their own configuration and safely write to the same file if Log4j
              is in a ClassLoader that is common to both of them.
            </p>
            <table>
              <caption align="top">MemoryMappedFileAppender Parameters</caption>
              <tr>
                <th>Parameter Name</th>
                <th>Type</th>
                <th>Description</th>
              </tr>
              <tr>
                <td>append</td>
                <td>boolean</td>
                <td>When true - the default, records will be appended to the end
                  of the file. When set to false, the file will be cleared before
                  new records are written.
                </td>
              </tr>
              <tr>
                <td>fileName</td>
                <td>String</td>
                <td>The name of the file to write to. If the file, or any of its
                  parent directories, do not exist, they will be created.
                </td>
              </tr>
              <tr>
                <td>filters</td>
                <td>Filter</td>
                <td>A Filter to determine if the event should be handled by this
                  Appender. More than one Filter may be used by using a CompositeFilter.
                </td>
              </tr>
              <tr>
                <td>immediateFlush</td>
                <td>boolean</td>
                <td>
                  <p>When set to true, each write will be followed by a
                    call to <a href="http://docs.oracle.com/javase/7/docs/api/java/nio/MappedByteBuffer.html#force()">MappedByteBuffer.force()</a>.
                This will guarantee the data is written to the storage device.
                  </p>
                  <p>The default for this parameter is <code>false</code>.
                    This means that the data is written to the storage device even
                    if the Java process crashes, but there may be data loss if the
                    operating system crashes.</p>
                  <p>Note that manually forcing a sync on every log event loses most
                    of the performance benefits of using a memory mapped file.</p>
                  <p>Flushing after every write is only useful when using this
                  appender with synchronous loggers. Asynchronous loggers and
                  appenders will automatically flush at the end of a batch of events,
                  even if immediateFlush is set to false. This also guarantees
                  the data is written to disk but is more efficient.
                  </p>
                </td>
              </tr>
              <tr>
                <td>regionLength</td>
                <td>int</td>
                <td>The length of the mapped region, defaults to 32 MB
                  (32 * 1024 * 1024 bytes). This parameter must be a value
                  between 256 and 1,073,741,824 (1 GB or 2^30);
                  values outside this range will be adjusted to the closest valid
                  value.
                  Log4j will round the specified value up to the nearest power of two.</td>
              </tr>
              <tr>
                <td>layout</td>
                <td>Layout</td>
                <td>The Layout to use to format the LogEvent</td>
              </tr>
              <tr>
                <td>name</td>
                <td>String</td>
                <td>The name of the Appender.</td>
              </tr>
              <tr>
                <td>ignoreExceptions</td>
                <td>boolean</td>
                <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                  internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                  caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                  <a href="#FailoverAppender">FailoverAppender</a>.</td>
              </tr>
            </table>
            <p>
              Here is a sample MemoryMappedFile configuration:
            </p>
    
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <MemoryMappedFile name="MyFile" fileName="logs/app.log">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
        </MemoryMappedFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="MyFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
          </subsection>
            <a name="NoSQLAppender"/>
            <subsection name="NoSQLAppender">
              <p>The NoSQLAppender writes log events to a NoSQL database using an internal lightweight provider interface.
                Provider implementations currently exist for MongoDB and Apache CouchDB, and writing a custom provider is
                quite simple.</p>
              <table>
                <caption align="top">NoSQLAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the Appender.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter may be
                    used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>int</td>
                  <td>If an integer greater than 0, this causes the appender to buffer log events and flush whenever the
                    buffer reaches this size.</td>
                </tr>
                <tr>
                  <td>NoSqlProvider</td>
                  <td>NoSQLProvider&lt;C extends NoSQLConnection&lt;W, T extends NoSQLObject&lt;W&gt;&gt;&gt;</td>
                  <td><em>Required.</em> The NoSQL provider that provides connections to the chosen NoSQL database.</td>
                </tr>
              </table>
              <p>You specify which NoSQL provider to use by specifying the appropriate configuration element within the
                <code>&lt;NoSql&gt;</code> element. The types currently supported are <code>&lt;MongoDb&gt;</code> and
                <code>&lt;CouchDb&gt;</code>. To create your own custom provider, read the JavaDoc for the
                <code>NoSQLProvider</code>, <code>NoSQLConnection</code>, and <code>NoSQLObject</code> classes and the
                documentation about creating Log4j plugins. We recommend you review the source code for the MongoDB and
                CouchDB providers as a guide for creating your own provider.</p>
              <table>
                <caption align="top">MongoDB Provider Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>collectionName</td>
                  <td>String</td>
                  <td><em>Required.</em> The name of the MongoDB collection to insert the events into.</td>
                </tr>
                <tr>
                  <td>writeConcernConstant</td>
                  <td>Field</td>
                  <td>By default, the MongoDB provider inserts records with the instructions
                    <code>com.mongodb.WriteConcern.ACKNOWLEDGED</code>. Use this optional attribute to specify the name of
                    a constant other than <code>ACKNOWLEDGED</code>.</td>
                </tr>
                <tr>
                  <td>writeConcernConstantClass</td>
                  <td>Class</td>
                  <td>If you specify <code>writeConcernConstant</code>, you can use this attribute to specify a class other
                    than <code>com.mongodb.WriteConcern</code> to find the constant on (to create your own custom
                    instructions).</td>
                </tr>
                <tr>
                  <td>factoryClassName</td>
                  <td>Class</td>
                  <td>To provide a connection to the MongoDB database, you can use this attribute and
                    <code>factoryMethodName</code> to specify a class and static method to get the connection from. The
                    method must return a <code>com.mongodb.DB</code> or a <code>com.mongodb.MongoClient</code>. If the
                    <code>DB</code> is not authenticated, you must also specify a <code>username</code> and
                    <code>password</code>. If you use the factory method for providing a connection, you must not specify
                    the <code>databaseName</code>, <code>server</code>, or <code>port</code> attributes.</td>
                </tr>
                <tr>
                  <td>factoryMethodName</td>
                  <td>Method</td>
                  <td>See the documentation for attribute <code>factoryClassName</code>.</td>
                </tr>
                <tr>
                  <td>databaseName</td>
                  <td>String</td>
                  <td>If you do not specify a <code>factoryClassName</code> and <code>factoryMethodName</code> for providing
                    a MongoDB connection, you must specify a MongoDB database name using this attribute. You must also
                    specify a <code>username</code> and <code>password</code>. You can optionally also specify a
                    <code>server</code> (defaults to localhost), and a <code>port</code> (defaults to the default MongoDB
                    port).</td>
                </tr>
                <tr>
                  <td>server</td>
                  <td>String</td>
                  <td>See the documentation for attribute <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>port</td>
                  <td>int</td>
                  <td>See the documentation for attribute <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>username</td>
                  <td>String</td>
                  <td>See the documentation for attributes <code>databaseName</code> and <code>factoryClassName</code>.</td>
                </tr>
                <tr>
                  <td>password</td>
                  <td>String</td>
                  <td>See the documentation for attributes <code>databaseName</code> and <code>factoryClassName</code>.</td>
                </tr>
              </table>
              <table>
                <caption align="top">CouchDB Provider Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>factoryClassName</td>
                  <td>Class</td>
                  <td>To provide a connection to the CouchDB database, you can use this attribute and
                    <code>factoryMethodName</code> to specify a class and static method to get the connection from. The
                    method must return a <code>org.lightcouch.CouchDbClient</code> or a
                    <code>org.lightcouch.CouchDbProperties</code>. If you use the factory method for providing a connection,
                    you must not specify the <code>databaseName</code>, <code>protocol</code>, <code>server</code>,
                    <code>port</code>, <code>username</code>, or <code>password</code> attributes.</td>
                </tr>
                <tr>
                  <td>factoryMethodName</td>
                  <td>Method</td>
                  <td>See the documentation for attribute <code>factoryClassName</code>.</td>
                </tr>
                <tr>
                  <td>databaseName</td>
                  <td>String</td>
                  <td>If you do not specify a <code>factoryClassName</code> and <code>factoryMethodName</code> for providing
                    a CouchDB connection, you must specify a CouchDB database name using this attribute. You must also
                    specify a <code>username</code> and <code>password</code>. You can optionally also specify a
                    <code>protocol</code> (defaults to http), <code>server</code> (defaults to localhost), and a
                    <code>port</code> (defaults to 80 for http and 443 for https).</td>
                </tr>
                <tr>
                  <td>protocol</td>
                  <td>String</td>
                  <td>Must either be "http" or "https." See the documentation for attribute <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>server</td>
                  <td>String</td>
                  <td>See the documentation for attribute <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>port</td>
                  <td>int</td>
                  <td>See the documentation for attribute <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>username</td>
                  <td>String</td>
                  <td>See the documentation for attributes <code>databaseName</code>.</td>
                </tr>
                <tr>
                  <td>password</td>
                  <td>String</td>
                  <td>See the documentation for attributes <code>databaseName</code>.</td>
                </tr>
              </table>
              <p>
                Here are a few sample configurations for the NoSQLAppender:
              </p>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <NoSql name="databaseAppender">
          <MongoDb databaseName="applicationDb" collectionName="applicationLog" server="mongo.example.org"
                   username="loggingUser" password="abc123" />
        </NoSql>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <NoSql name="databaseAppender">
          <MongoDb collectionName="applicationLog" factoryClassName="org.example.db.ConnectionFactory"
                   factoryMethodName="getNewMongoClient" />
        </NoSql>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <pre class="prettyprint linenums lang-xml"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <NoSql name="databaseAppender">
          <CouchDb databaseName="applicationDb" protocol="https" server="couch.example.org"
                   username="loggingUser" password="abc123" />
        </NoSql>
      </Appenders>
      <Loggers>
        <Root level="warn">
          <AppenderRef ref="databaseAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                The following example demonstrates how log events are persisted in NoSQL databases if represented in a JSON
                format:
              </p>
                <pre class="prettyprint lang-javascript"><![CDATA[{
        "level": "WARN",
        "loggerName": "com.example.application.MyClass",
        "message": "Something happened that you might want to know about.",
        "source": {
            "className": "com.example.application.MyClass",
            "methodName": "exampleMethod",
            "fileName": "MyClass.java",
            "lineNumber": 81
        },
        "marker": {
            "name": "SomeMarker",
            "parent" {
                "name": "SomeParentMarker"
            }
        },
        "threadName": "Thread-1",
        "millis": 1368844166761,
        "date": "2013-05-18T02:29:26.761Z",
        "thrown": {
            "type": "java.sql.SQLException",
            "message": "Could not insert record. Connection lost.",
            "stackTrace": [
                    { "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "fileName": "PreparedStatement.java", "lineNumber": 1049 },
                    { "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
                    { "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
                    { "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
            ],
            "cause": {
                "type": "java.io.IOException",
                "message": "Connection lost.",
                "stackTrace": [
                    { "className": "java.nio.channels.SocketChannel", "methodName": "write", "fileName": null, "lineNumber": -1 },
                    { "className": "org.example.sql.driver.PreparedStatement$1", "methodName": "responder", "fileName": "PreparedStatement.java", "lineNumber": 1032 },
                    { "className": "org.example.sql.driver.PreparedStatement", "methodName": "executeUpdate", "fileName": "PreparedStatement.java", "lineNumber": 738 },
                    { "className": "com.example.application.MyClass", "methodName": "exampleMethod", "fileName": "MyClass.java", "lineNumber": 81 },
                    { "className": "com.example.application.MainClass", "methodName": "main", "fileName": "MainClass.java", "lineNumber": 52 }
                ]
            }
        },
        "contextMap": {
            "ID": "86c3a497-4e67-4eed-9d6a-2e5797324d7b",
            "username": "JohnDoe"
        },
        "contextStack": [
            "topItem",
            "anotherItem",
            "bottomItem"
        ]
    }]]></pre>
            </subsection>
            <a name="OutputStreamAppender"/>
            <subsection name="OutputStreamAppender">
              <p>
              The OutputStreamAppender provides the base for many of the other Appenders such as the File and Socket
              appenders that write the event to an Output Stream. It cannot be directly configured. Support for
              immediateFlush and buffering is provided by the OutputStreamAppender. The OutputStreamAppender uses an
              OutputStreamManager to handle the actual I/O, allowing the stream to be shared by Appenders in multiple
              configurations.
              </p>
            </subsection>
    			<a name="RandomAccessFileAppender" />
    			<subsection name="RandomAccessFileAppender">
    			<p><i>As of beta-9, the name of this appender has been changed from FastFile to
    			  RandomAccessFile. Configurations using the <code>FastFile</code> element
    			  no longer work and should be modified to use the <code>RandomAccessFile</code> element.</i></p>
    				<p>
    					The RandomAccessFileAppender is similar to the standard
    					<a href="#FileAppender">FileAppender</a>
    					except it is always buffered (this cannot be switched off)
    					and internally it uses a
    					<tt>ByteBuffer + RandomAccessFile</tt>
    					instead of a
    					<tt>BufferedOutputStream</tt>.
    					We saw a 20-200% performance improvement compared to
    					FileAppender with "bufferedIO=true" in our
    					<a href="async.html#RandomAccessFileAppenderPerformance">measurements</a>.
    					Similar to the FileAppender,
    					RandomAccessFileAppender uses a RandomAccessFileManager to actually perform the
    					file I/O. While RandomAccessFileAppender
    					from different Configurations
    					cannot be shared, the RandomAccessFileManagers can be if the Manager is
    					accessible. For example, two web applications in a
    					servlet container can have
    					their own configuration and safely
    					write to the same file if Log4j
    					is in a ClassLoader that is common to
    					both of them.
    				</p>
    				<table>
              <caption align="top">RandomAccessFileAppender Parameters</caption>
              <tr>
    						<th>Parameter Name</th>
    						<th>Type</th>
    						<th>Description</th>
    					</tr>
              <tr>
    						<td>append</td>
    						<td>boolean</td>
    						<td>When true - the default, records will be appended to the end
    							of the file. When set to false,
    							the file will be cleared before
    							new records are written.
    						</td>
    					</tr>
              <tr>
    						<td>fileName</td>
    						<td>String</td>
    						<td>The name of the file to write to. If the file, or any of its
    							parent directories, do not exist,
    							they will be created.
    						</td>
    					</tr>
              <tr>
    						<td>filters</td>
    						<td>Filter</td>
    						<td>A Filter to determine if the event should be handled by this
    							Appender. More than one Filter
    							may be used by using a CompositeFilter.
    						</td>
    					</tr>
              <tr>
    						<td>immediateFlush</td>
    						<td>boolean</td>
    		                <td>
                              <p>
                                When set to true - the default, each write will be followed by a flush.
    		                    This will guarantee the data is written
    		                    to disk but could impact performance.
                              </p>
    		                  <p>
                                Flushing after every write is only useful when using this
    						    appender with synchronous loggers. Asynchronous loggers and
    						    appenders will automatically flush at the end of a batch of events,
    						    even if immediateFlush is set to false. This also guarantees
    						    the data is written to disk but is more efficient.
                              </p>
    		                </td>
    					</tr>
              <tr>
                          <td>bufferSize</td>
                          <td>int</td>
                          <td>The buffer size, defaults to 262,144 bytes (256 * 1024).</td>
                        </tr>
              <tr>
    						<td>layout</td>
    						<td>Layout</td>
    						<td>The Layout to use to format the LogEvent</td>
    					</tr>
              <tr>
    						<td>name</td>
    						<td>String</td>
    						<td>The name of the Appender.</td>
    					</tr>
              <tr>
                          <td>ignoreExceptions</td>
                          <td>boolean</td>
                          <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                            internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                            caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                            <a href="#FailoverAppender">FailoverAppender</a>.</td>
                        </tr>
    				</table>
    				<p>
    					Here is a sample RandomAccessFile configuration:
            </p>
    
    					<pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RandomAccessFile name="MyFile" fileName="logs/app.log">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
        </RandomAccessFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="MyFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    			</subsection>
            <a name="RewriteAppender"/>
            <subsection name="RewriteAppender">
              <p>
                The RewriteAppender allows the LogEvent to manipulated before it is processed by another Appender. This
                can be used to mask sensitive information such as passwords or to inject information into each event.
                The RewriteAppender must be configured with a <a href="RewritePolicy">RewritePolicy</a>. The
                RewriteAppender should be configured after any Appenders it references to allow it to shut down properly.
              </p>
              <table>
                <caption align="top">RewriteAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>AppenderRef</td>
                  <td>String</td>
                  <td>The name of the Appenders to call after the LogEvent has been manipulated. Multiple AppenderRef
                    elements can be configured.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>rewritePolicy</td>
                  <td>RewritePolicy</td>
                  <td>The RewritePolicy that will manipulate the LogEvent.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
              </table>
              <h4>RewritePolicy</h4>
                <p>
                  RewritePolicy is an interface that allows implementations to inspect and possibly modify LogEvents
                  before they are passed to Appender. RewritePolicy declares a single method named rewrite that must
                  be implemented. The method is passed the LogEvent and can return the same event or create a new one.
                </p>
                <h5>MapRewritePolicy</h5>
                  <p>
                    MapRewritePolicy will evaluate LogEvents that contain a MapMessage and will add or update
                    elements of the Map.
                  </p>
                  <table>
                    <tr>
                      <th>Parameter Name</th>
                      <th>Type</th>
                      <th>Description</th>
                    </tr>
                    <tr>
                      <td>mode</td>
                      <td>String</td>
                      <td>"Add" or "Update"</td>
                    </tr>
                    <tr>
                      <td>keyValuePair</td>
                      <td>KeyValuePair[]</td>
                      <td>An array of keys and their values.</td>
                    </tr>
                  </table>
                <p>
                 The following configuration shows a RewriteAppender configured to add a product key and its value
                 to the MapMessage.:
                </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%m%n"/>
        </Console>
        <Rewrite name="rewrite">
          <AppenderRef ref="STDOUT"/>
          <MapRewritePolicy mode="Add">
            <KeyValuePair key="product" value="TestProduct"/>
          </MapRewritePolicy>
        </Rewrite>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Rewrite"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <h5>PropertiesRewritePolicy</h5>
              <p>
                PropertiesRewritePolicy will add properties configured on the policy to the ThreadContext Map
                being logged. The properties will not be added to the actual ThreadContext Map. The property
                values may contain variables that will be evaluated when the configuration is processed as
                well as when the event is logged.
              </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>properties</td>
                  <td>Property[]</td>
                  <td>One of more Property elements to define the keys and values to be added to the ThreadContext Map.</td>
                </tr>
              </table>
              <p>
                The following configuration shows a RewriteAppender configured to add a product key and its value
                to the MapMessage:
              </p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%m%n"/>
        </Console>
        <Rewrite name="rewrite">
          <AppenderRef ref="STDOUT"/>
          <PropertiesRewritePolicy>
            <Property name="user">${sys:user.name}</Property>
            <Property name="env">${sys:environment}</Property>
          </PropertiesRewritePolicy>
        </Rewrite>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Rewrite"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            <h5>LoggerNameLevelRewritePolicy</h5>
            <p>
              You can use this policy to make loggers in third party code less chatty by changing event levels.
              The LoggerNameLevelRewritePolicy will rewrite log event levels for a given logger name prefix.
              You configure a LoggerNameLevelRewritePolicy with a logger name prefix and a pairs of levels, 
              where a pair defines a source level and a target level.
            </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>loggerName</td>
                  <td>String</td>
                  <td>A logger name used as a prefix to test each event's logger name.</td>
                </tr>
                <tr>
                  <td>LevelPair</td>
                  <td>KeyValuePair[]</td>
                  <td>An array of keys and their values, each key is a source level, each value a target level.</td>
                </tr>
              </table>
              <p>
                The following configuration shows a RewriteAppender configured to map level INFO to DEBUG and level 
                WARN to INFO for all loggers that start with <code>com.foo.bar</code>. 
              </p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp">
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%m%n"/>
        </Console>
        <Rewrite name="rewrite">
          <AppenderRef ref="STDOUT"/>
          <LoggerNameLevelRewritePolicy loggerName="com.foo.bar">
            <LevelPair key="INFO" value="DEBUG"/>
            <LevelPair key="WARN" value="INFO"/>
          </LoggerNameLevelRewritePolicy>
        </Rewrite>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Rewrite"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="RollingFileAppender"/>
            <subsection name="RollingFileAppender">
              <p>The RollingFileAppender is an OutputStreamAppender that writes to the File named in the fileName parameter
                and rolls the file over according the TriggeringPolicy and the RolloverPolicy. The
                RollingFileAppender uses a RollingFileManager (which extends OutputStreamManager) to actually perform the
                file I/O and perform the rollover. While RolloverFileAppenders from different Configurations cannot be
                shared, the RollingFileManagers can be if the Manager is accessible. For example, two web applications in a
                servlet container can have their own configuration and safely
                write to the same file if Log4j is in a ClassLoader that is common to both of them.</p>
              <p>
                A RollingFileAppender requires a <a href="#TriggeringPolicies">TriggeringPolicy</a> and a
                <a href="#RolloverStrategies">RolloverStrategy</a>. The triggering policy determines if a rollover should
                be performed while the RolloverStrategy defines how the rollover should be done. If no RolloverStrategy
                is configured, RollingFileAppender will use the <a href="#DefaultRolloverStrategy">DefaultRolloverStrategy</a>.
              </p>
              <p>
                File locking is not supported by the RollingFileAppender.
              </p>
              <table>
                <caption align="top">RollingFileAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>append</td>
                  <td>boolean</td>
                  <td>When true - the default, records will be appended to the end of the file. When set to false,
                    the file will be cleared before new records are written.</td>
                </tr>
                <tr>
                  <td>bufferedIO</td>
                  <td>boolean</td>
                  <td>When true - the default, records will be written to a buffer and the data will be written to
                    disk when the buffer is full or, if immediateFlush is set, when the record is written.
                    File locking cannot be used with bufferedIO. Performance tests have shown that using buffered I/O
                    significantly improves performance, even if immediateFlush is enabled.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>int</td>
                  <td>When bufferedIO is true, this is the buffer size, the default is 8192 bytes.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>fileName</td>
                  <td>String</td>
                  <td>The name of the file to write to. If the file, or any of its parent directories, do not exist,
                    they will be created.</td>
                </tr>
                <tr>
                  <td>filePattern</td>
                  <td>String</td>
                  <td>The pattern of the file name of the archived log file. The format of the pattern should is
                    dependent on the RolloverPolicy that is used. The DefaultRolloverPolicy will accept both
                    a date/time pattern compatible with
                    <a href="http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html">SimpleDateFormat</a>
                    and and/or a %i which represents an integer counter. The pattern also supports interpolation at
                    runtime so any of the Lookups (such as the <a href="./lookups.html#DateLookup">DateLookup</a> can
                    be included in the pattern.</td>
                </tr>
                <tr>
                  <td>immediateFlush</td>
                  <td>boolean</td>
                  <td><p>When set to true - the default, each write will be followed by a flush.
                    This will guarantee the data is written
                    to disk but could impact performance.</p>
                    <p>Flushing after every write is only useful when using this
    				appender with synchronous loggers. Asynchronous loggers and
    				appenders will automatically flush at the end of a batch of events,
    				even if immediateFlush is set to false. This also guarantees
    				the data is written to disk but is more efficient.</p>
                  </td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent</td>
                </tr>
    
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>policy</td>
                  <td>TriggeringPolicy</td>
                  <td>The policy to use to determine if a rollover should occur.</td>
                </tr>
                <tr>
                  <td>strategy</td>
                  <td>RolloverStrategy</td>
                  <td>The strategy to use to determine the name and location of the archive file.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
              </table>
              <a name="TriggeringPolicies"/>
              <h4>Triggering Policies</h4>
                <h5>Composite Triggering Policy</h5>
                  <p>
                    The <code>CompositeTriggeringPolicy</code> combines multiple triggering policies and returns true if
                    any of the configured policies return true. The <code>CompositeTriggeringPolicy</code> is configured
                    simply by wrapping other policies in a <code>Policies</code> element.
                  </p>
                  <p>
                    For example, the following XML fragment defines policies that rollover the log when the JVM starts,
                    when the log size reaches twenty megabytes, and when the current date no longer matches the log’s
                    start date.
                  </p>
                <pre class="prettyprint linenums"><![CDATA[<Policies>
      <OnStartupTriggeringPolicy />
      <SizeBasedTriggeringPolicy size="20 MB" />
      <TimeBasedTriggeringPolicy />
    </Policies>]]></pre>
                <h5>OnStartup Triggering Policy</h5>
                  <p>
                    The <code>OnStartupTriggeringPolicy</code> policy takes no parameters and causes a rollover if the log
                    file is older than the current JVM's start time.
                  </p>
                  <p>
                    <em>Google App Engine note:</em><br />
                    When running in Google App Engine, the OnStartup policy causes a rollover if the log file is older
                    than <em>the time when Log4J initialized</em>.
                    (Google App Engine restricts access to certain classes so Log4J cannot determine JVM start time with
                    <code>java.lang.management.ManagementFactory.getRuntimeMXBean().getStartTime()</code>
                    and falls back to Log4J initialization time instead.)
                  </p>
                <h5>SizeBased Triggering Policy</h5>
                  <p>
                    The <code>SizeBasedTriggeringPolicy</code> causes a rollover once the file has reached the specified
                    size. The size can be specified in bytes, with the suffix KB, MB or GB, for example <code>20MB</code>.
                  </p>
                <h5>TimeBased Triggering Policy</h5>
                  <p>
                    The <code>TimeBasedTriggeringPolicy</code> causes a rollover once the date/time pattern no longer
                    applies to the active file. This policy accepts an <code>increment</code> attribute which indicates how
                    frequently the rollover should occur based on the time pattern and a <code>modulate</code> boolean
                    attribute.
                  </p>
                    <table>
                      <caption align="top">TimeBasedTriggeringPolicy Parameters</caption>
                      <tr>
                        <th>Parameter Name</th>
                        <th>Type</th>
                        <th>Description</th>
                      </tr>
                      <tr>
                        <td>interval</td>
                        <td>integer</td>
                        <td>How often a rollover should occur based on the most specific time unit in the date pattern.
                          For example, with a date pattern with hours as the most specific item and and increment of 4 rollovers
                          would occur every 4 hours.
                          The default value is 1.</td>
                      </tr>
                      <tr>
                        <td>modulate</td>
                        <td>boolean</td>
                        <td>Indicates whether the interval should be adjusted to cause the next rollover to occur on
                          the interval boundary. For example, if the item is hours, the current hour is 3 am and the
                          interval is 4 then then the first rollover will occur at 4 am and then next ones will occur at
                          8 am, noon, 4pm, etc.</td>
                      </tr>
                    </table>
              <a name="RolloverStrategies"/>
              <h4>Rollover Strategies</h4>
                <a name="DefaultRolloverStrategy"/>
                <h5>Default Rollover Strategy</h5>
                  <p>
                    The default rollover strategy accepts both a date/time pattern and an integer from the filePattern
                    attribute specified on the RollingFileAppender itself. If the date/time pattern
                    is present it will be replaced with the current date and time values. If the pattern contains an integer
                    it will be incremented on each rollover. If the pattern contains both a date/time and integer
                    in the pattern the integer will be incremented until the result of the date/time pattern changes. If
                    the file pattern ends with ".gz", ".zip", ".bz2", ".deflate", ".pack200", or ".xz" the resulting archive 
                    will be compressed using the compression scheme that matches the suffix. The formats bzip2, Deflate, 
                    Pack200 and XZ require <a href="http://commons.apache.org/proper/commons-compress/">Apache Commons Compress</a>.
                    In addition, XZ requires <a href="http://tukaani.org/xz/java.html">XZ for Java</a>. 
                    The pattern may also contain lookup references that can be resolved at runtime such as is shown in the example 
                    below.
                  </p>
                  <p>The default rollover strategy supports two variations for incrementing the counter. The first is
                    the "fixed window" strategy. To illustrate how it works, suppose that the min attribute is set to 1,
                    the max attribute is set to 3, the file name is "foo.log", and the file name pattern is "foo-%i.log".
                  </p>
    
                  <table>
                    <tr>
                      <th>Number of rollovers</th>
                      <th>Active output target</th>
                      <th>Archived log files</th>
                      <th>Description</th>
                    </tr>
                    <tr>
                      <td>0</td>
                      <td>foo.log</td>
                      <td>-</td>
                      <td>All logging is going to the initial file.</td>
                    </tr>
                    <tr>
                      <td>1</td>
                      <td>foo.log</td>
                      <td>foo-1.log</td>
                      <td>During the first rollover foo.log is renamed to foo-1.log. A new foo.log file is created and
                      starts being written to.</td>
                    </tr>
                    <tr>
                      <td>2</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log</td>
                      <td>During the second rollover foo-1.log is renamed to foo-2.log and foo.log is renamed to
                        foo-1.log. A new foo.log file is created and starts being written to.</td>
                    </tr>
                    <tr>
                      <td>3</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log, foo-3.log</td>
                      <td>During the third rollover foo-2.log is renamed to foo-3.log, foo-1.log is renamed to foo-2.log and
                        foo.log is renamed to foo-1.log. A new foo.log file is created and starts being written to.</td>
                    </tr>
                    <tr>
                      <td>4</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log, foo-3.log</td>
                      <td>In the fourth and subsequent rollovers, foo-3.log is deleted, foo-2.log is renamed to foo-3.log,
                        foo-1.log is renamed to foo-2.log and foo.log is renamed to foo-1.log. A new foo.log file is
                        created and starts being written to.</td>
                    </tr>
                  </table>
                  <p>By way of contrast, when the the fileIndex attribute is set to "max" but all the other settings
                    are the same the following actions will be performed.
                  </p>
                  <table>
                    <tr>
                      <th>Number of rollovers</th>
                      <th>Active output target</th>
                      <th>Archived log files</th>
                      <th>Description</th>
                    </tr>
                    <tr>
                      <td>0</td>
                      <td>foo.log</td>
                      <td>-</td>
                      <td>All logging is going to the initial file.</td>
                    </tr>
                    <tr>
                      <td>1</td>
                      <td>foo.log</td>
                      <td>foo-1.log</td>
                      <td>During the first rollover foo.log is renamed to foo-1.log. A new foo.log file is created and
                        starts being written to.</td>
                    </tr>
                    <tr>
                      <td>2</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log</td>
                      <td>During the second rollover foo.log is renamed to foo-2.log. A new foo.log file is created
                        and starts being written to.</td>
                    </tr>
                    <tr>
                      <td>3</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log, foo-3.log</td>
                      <td>During the third rollover foo.log is renamed to foo-3.log. A new foo.log file is created and
                        starts being written to.</td>
                    </tr>
                    <tr>
                      <td>4</td>
                      <td>foo.log</td>
                      <td>foo-1.log, foo-2.log, foo-3.log</td>
                      <td>In the fourth and subsequent rollovers, foo-1.log is deleted, foo-2.log is renamed to foo-1.log,
                        foo-3.log is renamed to foo-2.log and foo.log is renamed to foo-3.log. A new foo.log file is
                        created and starts being written to.</td>
                    </tr>
                  </table>
                  <table>
                    <caption align="top">DefaultRolloverStrategy Parameters</caption>
                    <tr>
                      <th>Parameter Name</th>
                      <th>Type</th>
                      <th>Description</th>
                    </tr>
                    <tr>
                      <td>fileIndex</td>
                      <td>String</td>
                      <td>If set to "max" (the default), files with a higher index will be newer than files with a
                        smaller index. If set to "min", file renaming and the counter will follow the Fixed Window strategy
                        described above.</td>
                    </tr>
                    <tr>
                      <td>min</td>
                      <td>integer</td>
                      <td>The minimum value of the counter. The default value is 1.</td>
                    </tr>
                    <tr>
                      <td>max</td>
                      <td>integer</td>
                      <td>The maximum value of the counter. Once this values is reached older archives will be
                        deleted on subsequent rollovers.</td>
                    </tr>
                    <tr>
                      <td>compressionLevel</td>
                      <td>integer</td>
                      <td>
                        Sets the compression level, 0-9, where 0 = none, 1 = best speed, through 9 = best compression.
                        Only implemented for ZIP files.
                      </td>
                    </tr>
                  </table>
    
              <p>
                Below is a sample configuration that uses a RollingFileAppender with both the time and size based
                triggering policies, will create up to 7 archives on the same day (1-7) that are stored in a directory
                based on the current year and month, and will compress each
                archive using gzip:
              </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/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                This second example shows a rollover strategy that will keep up to 20 files before removing them.
              </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/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
          <DefaultRolloverStrategy max="20"/>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              <p>
                Below is a sample configuration that uses a RollingFileAppender with both the time and size based
                triggering policies, will create up to 7 archives on the same day (1-7) that are stored in a directory
                based on the current year and month, and will compress each
                archive using gzip and will roll every 6 hours when the hour is divisible by 6:
              </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/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
    			<a name="RollingRandomAccessFileAppender" />
    			<subsection name="RollingRandomAccessFileAppender">
    			<p><i>As of beta-9, the name of this appender has been changed from FastRollingFile to
    			  RollingRandomAccessFile. Configurations using the <code>FastRollingFile</code> element
    			  no longer work and should be modified to use the <code>RollingRandomAccessFile</code> element.</i></p>
    				<p>
    					The RollingRandomAccessFileAppender is similar to the standard
    					<a href="#RollingFileAppender">RollingFileAppender</a>
    					except it is always buffered (this cannot be switched off)
    					and
    					internally it uses a
    					<tt>ByteBuffer + RandomAccessFile</tt>
    					instead of a
    					<tt>BufferedOutputStream</tt>.
    					We saw a 20-200% performance improvement compared to
    					RollingFileAppender with "bufferedIO=true"
    					in our
    					<a href="async.html#RandomAccessFileAppenderPerformance">measurements</a>.
    
    					The RollingRandomAccessFileAppender writes
    					to the File named in the
    					fileName parameter
    					and rolls the file over according the
    					TriggeringPolicy
    					and the RolloverPolicy.
    
    					Similar to the RollingFileAppender,
    					RollingRandomAccessFileAppender uses a RollingRandomAccessFileManager
    					to actually perform the
    					file I/O and perform the rollover. While RollingRandomAccessFileAppender
    					from different Configurations cannot be
    					shared, the RollingRandomAccessFileManagers can be
    					if the Manager is accessible.
    					For example, two web applications in a servlet
    					container can have their own configuration and safely write to the
    					same file if Log4j is in a ClassLoader that is common to both of them.
    				</p>
    				<p>
    					A RollingRandomAccessFileAppender requires a
    					<a href="#TriggeringPolicies">TriggeringPolicy</a>
    					and a
    					<a href="#RolloverStrategies">RolloverStrategy</a>.
    					The triggering policy determines if a rollover should
    					be performed
    					while the RolloverStrategy defines how the rollover
    					should be done.
    					If no RolloverStrategy
    					is configured, RollingRandomAccessFileAppender will
    					use the
    					<a href="#DefaultRolloverStrategy">DefaultRolloverStrategy</a>.
    				</p>
    				<p>
    					File locking is not supported by the RollingRandomAccessFileAppender.
    				</p>
    				<table>
              <caption align="top">RollingRandomAccessFileAppender Parameters</caption>
              <tr>
    						<th>Parameter Name</th>
    						<th>Type</th>
    						<th>Description</th>
    					</tr>
              <tr>
    						<td>append</td>
    						<td>boolean</td>
    						<td>When true - the default, records will be appended to the end
    							of the file. When set to false,
    							the file will be cleared before
    							new records are written.
    						</td>
    					</tr>
              <tr>
    						<td>filter</td>
    						<td>Filter</td>
    						<td>A Filter to determine if the event should be handled by this
    							Appender. More than one Filter
    							may be used by using a
    							CompositeFilter.
    						</td>
    					</tr>
              <tr>
    						<td>fileName</td>
    						<td>String</td>
    						<td>The name of the file to write to. If the file, or any of its
    							parent directories, do not exist,
    							they will be created.
    						</td>
    					</tr>
              <tr>
    						<td>filePattern</td>
    						<td>String</td>
    						<td>
    							The pattern of the file name of the archived log file. The format
    							of the pattern should is
    							dependent on the RolloverPolicy that is
    							used. The DefaultRolloverPolicy
    							will accept both
    							a date/time
    							pattern compatible with
    							<a
    								href="http://download.oracle.com/javase/6/docs/api/java/text/SimpleDateFormat.html">
    								SimpleDateFormat</a>
    
    							and/or a %i which represents an integer counter. The pattern
    							also supports interpolation at
    							runtime so any of the Lookups (such
    							as the
    							<a href="./lookups.html#DateLookup">DateLookup</a>
    							can
    							be included in the pattern.
    						</td>
    					</tr>
              <tr>
    						<td>immediateFlush</td>
    						<td>boolean</td>
    		              <td><p>When set to true - the default, each write will be followed by a flush.
    		                This will guarantee the data is written
    		                to disk but could impact performance.</p>
    		                <p>Flushing after every write is only useful when using this
    						appender with synchronous loggers. Asynchronous loggers and
    						appenders will automatically flush at the end of a batch of events,
    						even if immediateFlush is set to false. This also guarantees
    						the data is written to disk but is more efficient.</p>
    		              </td>
    					</tr>
              <tr>
                          <td>bufferSize</td>
                          <td>int</td>
                          <td>The buffer size, defaults to 262,144 bytes (256 * 1024).</td>
                        </tr>
              <tr>
    						<td>layout</td>
    						<td>Layout</td>
    						<td>The Layout to use to format the LogEvent</td>
    					</tr>
    
              <tr>
    						<td>name</td>
    						<td>String</td>
    						<td>The name of the Appender.</td>
    					</tr>
              <tr>
    						<td>policy</td>
    						<td>TriggeringPolicy</td>
    						<td>The policy to use to determine if a rollover should occur.
    						</td>
    					</tr>
              <tr>
    						<td>strategy</td>
    						<td>RolloverStrategy</td>
    						<td>The strategy to use to determine the name and location of the
    							archive file.
    						</td>
    					</tr>
              <tr>
                <td>ignoreExceptions</td>
                <td>boolean</td>
                <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                  internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                  caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                  <a href="#FailoverAppender">FailoverAppender</a>.</td>
              </tr>
    				</table>
    				<a name="FRFA_TriggeringPolicies" />
    				<h4>Triggering Policies</h4>
    				<p>
    					See
    					<a href="#TriggeringPolicies">RollingFileAppender Triggering Policies</a>.
    				</p>
    				<a name="FRFA_RolloverStrategies" />
    				<h4>Rollover Strategies</h4>
    				<p>
    					See
    					<a href="#RolloverStrategies">RollingFileAppender Rollover Strategies</a>.
    				</p>
    
    				<p>
    					Below is a sample configuration that uses a RollingRandomAccessFileAppender
    					with both the time and size based
    					triggering policies, will create
    					up to 7 archives on the same day (1-7) that
    					are stored in a
    					directory
    					based on the current year and month, and will compress
    					each
    					archive using gzip:
            </p>
    
    					<pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingRandomAccessFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingRandomAccessFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    				<p>
    					This second example shows a rollover strategy that will keep up to
    					20 files before removing them.
            </p>
    					<pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy />
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
          <DefaultRolloverStrategy max="20"/>
        </RollingRandomAccessFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingRandomAccessFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    				<p>
    					Below is a sample configuration that uses a RollingRandomAccessFileAppender
    					with both the time and size based
    					triggering policies, will create
    					up to 7 archives on the same day (1-7) that
    					are stored in a
    					directory
    					based on the current year and month, and will compress
    					each
    					archive using gzip and will roll every 6 hours when the hour is
    					divisible
    					by 6:
            </p>
    
    					<pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <RollingRandomAccessFile name="RollingRandomAccessFile" fileName="logs/app.log"
                     filePattern="logs/$${date:yyyy-MM}/app-%d{yyyy-MM-dd-HH}-%i.log.gz">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m%n</Pattern>
          </PatternLayout>
          <Policies>
            <TimeBasedTriggeringPolicy interval="6" modulate="true"/>
            <SizeBasedTriggeringPolicy size="250 MB"/>
          </Policies>
        </RollingRandomAccessFile>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="RollingRandomAccessFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    			</subsection>
            <a name="RoutingAppender"/>
            <subsection name="RoutingAppender">
               <p>
                 The RoutingAppender evaluates LogEvents and then routes them to a subordinate Appender. The target
                 Appender may be an appender previously configured and may be referenced by its name or the
                 Appender can be dynamically created as needed. The RoutingAppender should be configured after any
                 Appenders it references to allow it to shut down properly.
              </p>
              <table>
                <caption align="top">RoutingAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>rewritePolicy</td>
                  <td>RewritePolicy</td>
                  <td>The RewritePolicy that will manipulate the LogEvent.</td>
                </tr>
                <tr>
                  <td>routes</td>
                  <td>Routes</td>
                  <td>Contains one or more Route declarations to identify the criteria for choosing Appenders.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
              </table>
              <h4>Routes</h4>
                <p>
                  The Routes element accepts a single, required attribute named "pattern". The pattern is evaluated
                  against all the registered Lookups and the result is used to select a Route. Each Route may be
                  configured with a key. If the key matches the result of evaluating the pattern then that Route
                  will be selected. If no key is specified on a Route then that Route is the default. Only one Route
                  can be configured as the default.
                </p>
                <p>
                  Each Route must reference an Appender. If the Route contains a ref attribute then the
                  Route will reference an Appender that was defined in the configuration. If the Route contains an
                  Appender definition then an Appender will be created within the context of the RoutingAppender and
                  will be reused each time a matching Appender name is referenced through a Route.
                </p>
              <p>
                Below is a sample configuration that uses a RoutingAppender to route all Audit events to
                a FlumeAppender and all other events will be routed to a RollingFileAppender that captures only
                the specific event type. Note that the AuditAppender was predefined while the RollingFileAppenders
                are created as needed.
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Flume name="AuditLogger" compress="true">
          <Agent host="192.168.10.101" port="8800"/>
          <Agent host="192.168.10.102" port="8800"/>
          <RFC5424Layout enterpriseNumber="18060" includeMDC="true" appName="MyApp"/>
        </Flume>
        <Routing name="Routing">
          <Routes pattern="$${sd:type}">
            <Route>
              <RollingFile name="Rolling-${sd:type}" fileName="${sd:type}.log"
                           filePattern="${sd:type}.%i.log.gz">
                <PatternLayout>
                  <pattern>%d %p %c{1.} [%t] %m%n</pattern>
                </PatternLayout>
                <SizeBasedTriggeringPolicy size="500" />
              </RollingFile>
            </Route>
            <Route ref="AuditLogger" key="Audit"/>
          </Routes>
        </Routing>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Routing"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="SMTPAppender"/>
            <subsection name="SMTPAppender">
              <p>
                Sends an e-mail when a specific logging event occurs, typically on errors or fatal errors.
              </p>
              <p>
                The number of logging events delivered in this e-mail depend on the value of
                <b>BufferSize</b> option. The <code>SMTPAppender</code> keeps only the last
                <code>BufferSize</code> logging events in its cyclic buffer. This keeps
                memory requirements at a reasonable level while still delivering useful
                application context. All events in the buffer are included in the email.
                The buffer will contain the most recent events of level TRACE to WARN
                preceding the event that triggered the email.
              </p>
              <p>
                The default behavior is to trigger sending an email whenever an ERROR or higher
                severity event is logged and to format it as HTML. The circumstances on when the
                email is sent can be controlled by setting one or more filters on the Appender.
                As with other Appenders, the formatting can be controlled by specifying a Layout
                for the Appender.
              </p>
              <table>
                <caption align="top">SMTPAppender Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>bcc</td>
                  <td>String</td>
                  <td>The comma-separated list of BCC email addresses.</td>
                </tr>
                <tr>
                  <td>cc</td>
                  <td>String</td>
                  <td>The comma-separated list of CC email addresses.</td>
                </tr>
                <tr>
                  <td>bufferSize</td>
                  <td>integer</td>
                  <td>The maximum number of log events to be buffered for inclusion in the message. Defaults to 512.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                    may be used by using a CompositeFilter.
                  </td>
                </tr>
                <tr>
                  <td>from</td>
                  <td>String</td>
                  <td>The email address of the sender.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent. The default is SerializedLayout.</td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>replyTo</td>
                  <td>String</td>
                  <td>The comma-separated list of reply-to email addresses.</td>
                </tr>
                <tr>
                  <td>smtpDebug</td>
                  <td>boolean</td>
                  <td>When set to true enables session debugging on STDOUT. Defaults to false.</td>
                </tr>
                <tr>
                  <td>smtpHost</td>
                  <td>String</td>
                  <td>The SMTP hostname to send to. This parameter is required.</td>
                </tr>
                <tr>
                  <td>smtpPassword</td>
                  <td>String</td>
                  <td>The password required to authenticate against the SMTP server.</td>
                </tr>
                <tr>
                  <td>smtpPort</td>
                  <td>integer</td>
                  <td>The SMTP port to send to. </td>
                </tr>
                <tr>
                  <td>smtpProtocol</td>
                  <td>String</td>
                  <td>The SMTP transport protocol (such as "smtps", defaults to "smtp").</td>
                </tr>
                <tr>
                  <td>smtpUsername</td>
                  <td>String</td>
                  <td>The username required to authenticate against the SMTP server.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>to</td>
                  <td>String</td>
                  <td>The comma-separated list of recipient email addresses.</td>
                </tr>
              </table>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <SMTP name="Mail" subject="Error Log" to="errors@logging.apache.org" from="test@logging.apache.org"
              smtpHost="localhost" smtpPort="25" bufferSize="50">
        </SMTP>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="Mail"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
            <a name="SocketAppender"/>
            <subsection name="SocketAppender">
              <p>
                The <code>SocketAppender</code> is an OutputStreamAppender that writes its output to a remote destination
                specified by a host and port. The data can be sent over either TCP or UDP and can be sent in any format.
                The default format is to send a Serialized LogEvent. Log4j 2 contains a SocketServer which is capable
                of receiving serialized LogEvents and routing them through the logging system on the server. You can optionally
                secure communication with SSL.
              </p>
              <table>
                <caption align="top"><code>SocketAppender</code> 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 Appender.</td>
                </tr>
                <tr>
                  <td>host</td>
                  <td>String</td>
                  <td>The name or address of the system that is listening for log events. This parameter is required.</td>
                </tr>
                <tr>
                  <td>port</td>
                  <td>integer</td>
                  <td>The port on the host that is listening for log events. This parameter must be specified.</td>
                </tr>
                <tr>
                  <td>protocol</td>
                  <td>String</td>
                  <td>"TCP" (default), "SSL" or "UDP".</td>
                </tr>
                <tr>
                  <td>SSL</td>
                  <td>SslConfiguration</td>
                  <td>Contains the configuration for the KeyStore and TrustStore.</td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>immediateFail</td>
                  <td>boolean</td>
                  <td>When set to true, log events will not wait to try to reconnect and will fail immediately if the
                  socket is not available.</td>
                </tr>
                <tr>
                  <td>immediateFlush</td>
                  <td>boolean</td>
                  <td>When set to true - the default, each write will be followed by a flush.
                    This will guarantee the data is written
                    to disk but could impact performance.</td>
                </tr>
                <tr>
                  <td>layout</td>
                  <td>Layout</td>
                  <td>The Layout to use to format the LogEvent. The default is SerializedLayout.</td>
                </tr>
                <tr>
                  <td>reconnectionDelayMillis</td>
                  <td>integer</td>
                  <td>If set to a value greater than 0, after an error the SocketManager will attempt to reconnect to
                    the server after waiting the specified number of milliseconds. If the reconnect fails then
                    an exception will be thrown (which can be caught by the application if <code>ignoreExceptions</code> is
                    set to <code>false</code>).</td>
                </tr>
                <tr>
                  <td>connectTimeoutMillis</td>
                  <td>integer</td>
                  <td>The connect timeout in milliseconds. The default is 0 (infinite timeout, like Socket.connect()
                    methods).</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
              </table>
    
              <p>
                This is an unsecured TCP configuration:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Socket name="socket" host="localhost" port="9500">
          <SerializedLayout />
        </Socket>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="socket"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
              <p>
                This is a secured SSL configuration:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Socket name="socket" host="localhost" port="9500">
          <SerializedLayout />
          <SSL>
            <KeyStore location="log4j2-keystore.jks" password="changeme"/>
            <TrustStore location="truststore.jks" password="changeme"/>
          </SSL>
        </Socket>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="socket"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
            </subsection>
            <a name="SyslogAppender"/>
            <subsection name="SyslogAppender">
              <p>
                The <code>SyslogAppender</code> is a <code>SocketAppender</code> that writes its output to a remote destination
                specified by a host and port in a format that conforms with either the BSD Syslog format or the RFC 5424
                format. The data can be sent over either TCP or UDP.
              </p>
              <table>
                <caption align="top"><code>SyslogAppender</code> Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>advertise</td>
                  <td>boolean</td>
                  <td>Indicates whether the appender should be advertised.</td>
                </tr>
                <tr>
                  <td>appName</td>
                  <td>String</td>
                  <td>The value to use as the APP-NAME in the RFC 5424 syslog record.</td>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the syslog String to a byte array. The String must be
                    a valid <a href="http://download.oracle.com/javase/6/docs/api/java/nio/charset/Charset.html">Charset</a>.
                    If not specified, the default system Charset will be used.</td>
                </tr>
                <tr>
                  <td>connectTimeoutMillis</td>
                  <td>integer</td>
                  <td>The connect timeout in milliseconds. The default is 0 (infinite timeout, like Socket.connect()
                    methods).</td>
                </tr>
                <tr>
                  <td>enterpriseNumber</td>
                  <td>integer</td>
                  <td>The IANA enterprise number as described in
                    <a href="http://tools.ietf.org/html/rfc5424#section-7.2.2">RFC 5424</a></td>
                </tr>
                <tr>
                  <td>filter</td>
                  <td>Filter</td>
                  <td>A Filter to determine if the event should be handled by this Appender. More than one Filter
                  may be used by using a CompositeFilter.</td>
                </tr>
                <tr>
                  <td>facility</td>
                  <td>String</td>
                  <td>The facility is used to try to classify the message. The facility option must be set to one of
                    "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV",
                    "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5",
                    "LOCAL6", or "LOCAL7". These values may be specified as upper or lower case characters.</td>
                </tr>
                <tr>
                  <td>format</td>
                  <td>String</td>
                  <td>If set to "RFC5424" the data will be formatted in accordance with RFC 5424. Otherwise, it will
                    be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be
                    1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not
                    truncate records since the receiver must accept records of up to 2048 bytes and may accept records
                    that are longer.</td>
                </tr>
                <tr>
                  <td>host</td>
                  <td>String</td>
                  <td>The name or address of the system that is listening for log events. This parameter is required.</td>
                </tr>
                <tr>
                  <td>id</td>
                  <td>String</td>
                  <td>The default structured data id to use when formatting according to RFC 5424. If the LogEvent contains
                    a StructuredDataMessage the id from the Message will be used instead of this value.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>The default is <code>true</code>, causing exceptions encountered while appending events to be
                    internally logged and then ignored. When set to <code>false</code> exceptions will be propagated to the
                    caller, instead. You must set this to <code>false</code> when wrapping this Appender in a
                    <a href="#FailoverAppender">FailoverAppender</a>.</td>
                </tr>
                <tr>
                  <td>immediateFail</td>
                  <td>boolean</td>
                  <td>When set to true, log events will not wait to try to reconnect and will fail immediately if the
                    socket is not available.</td>
                </tr>
                <tr>
                  <td>immediateFlush</td>
                  <td>boolean</td>
                  <td>When set to true - the default, each write will be followed by a flush.
                    This will guarantee the data is written
                    to disk but could impact performance.</td>
                </tr>
                <tr>
                  <td>includeMDC</td>
                  <td>boolean</td>
                  <td>Indicates whether data from the ThreadContextMap will be included in the RFC 5424 Syslog record.
                    Defaults to true.</td>
                </tr>
                <tr>
                  <td>loggerFields</td>
                  <td>List of KeyValuePairs</td>
                  <td>Allows arbitrary PatternLayout patterns to be included as specified ThreadContext fields; no default
                    specified. To use, include a &gt;LoggerFields&lt; nested element, containing one or more
                    &gt;KeyValuePair&lt; elements. Each &gt;KeyValuePair&lt; must have a key attribute, which
                    specifies the key name which will be used to identify the field within the MDC Structured Data element,
                    and a value attribute, which specifies the PatternLayout pattern to use as the value.</td>
                </tr>
                <tr>
                  <td>mdcExcludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be excluded from the LogEvent. This is mutually
                    exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcIncludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC
                    not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes
                    attribute. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcRequired</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that must be present in the MDC. If a key is not present a
                    LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcPrefix</td>
                  <td>String</td>
                  <td>A string that should be prepended to each MDC key in order to distinguish it from event attributes.
                    The default string is "mdc:". This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>messageId</td>
                  <td>String</td>
                  <td>The default value to be used in the MSGID field of RFC 5424 syslog records. </td>
                </tr>
                <tr>
                  <td>name</td>
                  <td>String</td>
                  <td>The name of the Appender.</td>
                </tr>
                <tr>
                  <td>newLine</td>
                  <td>boolean</td>
                  <td>If true, a newline will be appended to the end of the syslog record. The default is false.</td>
                </tr>
                <tr>
                  <td>port</td>
                  <td>integer</td>
                  <td>The port on the host that is listening for log events. This parameter must be specified.</td>
                </tr>
                <tr>
                  <td>protocol</td>
                  <td>String</td>
                  <td>"TCP" or "UDP". This parameter is required.</td>
                </tr>
                <tr>
                  <td>SSL</td>
                  <td>SslConfiguration</td>
                  <td>Contains the configuration for the KeyStore and TrustStore.</td>
                </tr>
                <tr>
                  <td>reconnectionDelayMillis</td>
                  <td>integer</td>
                  <td>If set to a value greater than 0, after an error the SocketManager will attempt to reconnect to
                    the server after waiting the specified number of milliseconds. If the reconnect fails then
                    an exception will be thrown (which can be caught by the application if <code>ignoreExceptions</code> is
                    set to <code>false</code>).</td>
                </tr>
              </table>
              <p>
                A sample syslogAppender configuration that is configured with two <code>SyslogAppender</code>s, one using the BSD
                format and one using RFC 5424.
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <Syslog name="bsd" host="localhost" port="514" protocol="TCP"/>
        <Syslog name="RFC5424" format="RFC5424" host="localhost" port="8514"
                protocol="TCP" appName="MyApp" includeMDC="true"
                facility="LOCAL0" enterpriseNumber="18060" newLine="true"
                messageId="Audit" id="App"/>
      </Appenders>
      <Loggers>
        <Logger name="com.mycorp" level="error">
          <AppenderRef ref="RFC5424"/>
        </Logger>
        <Root level="error">
          <AppenderRef ref="bsd"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
              <p>
                For SSL this appender writes its output to a remote destination specified by a host and port over SSL in
                a format that conforms with either the BSD Syslog format or the RFC 5424 format.
              </p>
    
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <Appenders>
        <TLSSyslog name="bsd" host="localhost" port="6514">
          <SSL>
            <KeyStore location="log4j2-keystore.jks" password="changeme"/>
            <TrustStore location="truststore.jks" password="changeme"/>
          </SSL>
        </TLSSyslog>
      </Appenders>
      <Loggers>
        <Root level="error">
          <AppenderRef ref="bsd"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            </subsection>
    
            <a name="ZeroMQAppender"/>
            <subsection name="ZeroMQ Appender">
              <p>
                The ZeroMQ appender uses the <a href="https://github.com/zeromq/jeromq">JeroMQ</a> library to send log 
                events to one or more endpoints.  
              </p>
              <p>
                This is a simple JeroMQ configuration:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration name="JeroMQAppenderTest" status="TRACE">
      <Appenders>
        <JeroMQ name="JeroMQAppender">    
          <Property name="endpoint">tcp://*:5556</Property>
          <Property name="endpoint">ipc://info-topic</Property>
        </JeroMQ>
      </Appenders>
      <Loggers>
        <Root level="info">
          <AppenderRef ref="JeroMQAppender"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre> 
              <p>
                The table below describes all options. Please consult the JeroMQ and ZeroMQ documentation for details.
              </p>
              <table>
                <caption align="top">JeroMQ 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 Appender.</td>
                </tr>
                <tr>
                  <td>Layout</td>
                  <td>Layout</td>
                  <td>The Layout of the Appender.</td>
                </tr>
                <tr>
                  <td>Filters</td>
                  <td>Filter</td>
                  <td>The Filters of the Appender.</td>
                </tr>
                <tr>
                  <td>Property</td>
                  <td>Property</td>
                  <td>One or more Property elements, named <code>endpoint</code>.</td>
                </tr>
                <tr>
                  <td>ignoreExceptions</td>
                  <td>boolean</td>
                  <td>If true, exceptions will be logged and suppressed. If false errors will be logged and then passed to the application.</td>
                </tr>
                <tr>
                  <td>affinity</td>
                  <td>long</td>
                  <td>The ZMQ_AFFINITY option. Defaults to 0.</td>
                </tr>
                <tr>
                  <td>backlog</td>
                  <td>long</td>
                  <td>The ZMQ_BACKLOG option. Defaults to 100.</td>
                </tr>
                <tr>
                  <td>delayAttachOnConnect</td>
                  <td>boolean</td>
                  <td>The ZMQ_DELAY_ATTACH_ON_CONNECT option. Defaults to false.</td>
                </tr>
                <tr>
                  <td>identity</td>
                  <td>byte[]</td>
                  <td>The ZMQ_IDENTITY option. Defaults to none.</td>
                </tr>
                <tr>
                  <td>ipv4Only</td>
                  <td>boolean</td>
                  <td>The ZMQ_IPV4ONLY option. Defaults to true.</td>
                </tr>
                <tr>
                  <td>linger</td>
                  <td>long</td>
                  <td>The ZMQ_LINGER option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>maxMsgSize</td>
                  <td>long</td>
                  <td>The ZMQ_MAXMSGSIZE option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>rcvHwm</td>
                  <td>long</td>
                  <td>The ZMQ_RCVHWM option. Defaults to 1000.</td>
                </tr>
                <tr>
                  <td>receiveBufferSize</td>
                  <td>long</td>
                  <td>The ZMQ_RCVBUF option. Defaults to 0.</td>
                </tr>
                <tr>
                  <td>receiveTimeOut</td>
                  <td>int</td>
                  <td>The ZMQ_RCVTIMEO option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>reconnectIVL</td>
                  <td>long</td>
                  <td>The ZMQ_RECONNECT_IVL option. Defaults to 100.</td>
                </tr>
                <tr>
                  <td>reconnectIVLMax</td>
                  <td>long</td>
                  <td>The ZMQ_RECONNECT_IVL_MAX option. Defaults to 0.</td>
                </tr>
                <tr>
                  <td>sendBufferSize</td>
                  <td>long</td>
                  <td>The ZMQ_SNDBUF option. Defaults to 0.</td>
                </tr>
                <tr>
                  <td>sendTimeOut</td>
                  <td>int</td>
                  <td>The ZMQ_SNDTIMEO option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>sndHwm</td>
                  <td>long</td>
                  <td>The ZMQ_SNDHWM option. Defaults to 1000.</td>
                </tr>
                <tr>
                  <td>tcpKeepAlive</td>
                  <td>int</td>
                  <td>The ZMQ_TCP_KEEPALIVE option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>tcpKeepAliveCount</td>
                  <td>long</td>
                  <td>The ZMQ_TCP_KEEPALIVE_CNT option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>tcpKeepAliveIdle</td>
                  <td>long</td>
                  <td>The ZMQ_TCP_KEEPALIVE_IDLE option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>tcpKeepAliveInterval</td>
                  <td>long</td>
                  <td>The ZMQ_TCP_KEEPALIVE_INTVL option. Defaults to -1.</td>
                </tr>
                <tr>
                  <td>xpubVerbose</td>
                  <td>boolean</td>
                  <td>The ZMQ_XPUB_VERBOSE option. Defaults to false.</td>
                </tr>
              </table>          
            </subsection>
    
          </section>
      </body>
    </document>
    ���������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/architecture.xml��������������������������������������0000664�0000000�0000000�00000074577�12577562624�0024336�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Architecture</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
      </properties>
    
      <body>
        <section name="Architecture">
          <subsection name="Main Components">
            <p>Log4j uses the classes shown in the diagram below.</p>
            <img src="../images/Log4jClasses.jpg" title="Log4j 2 Class Relationships"
                 alt="Log4j 2 Class Relationships"/>
            <p>Applications using the Log4j 2 API will request a Logger with a specific name from the
              LogManager. The LogManager will locate the appropriate LoggerContext and then obtain the Logger from it.
              If the Logger must be created it will be associated with the LoggerConfig that contains either a) the
              same name as the Logger, b) the name of a parent package, or c) the root LoggerConfig. LoggerConfig
              objects are created from Logger declarations in the configuration. The LoggerConfig is associated with
              the Appenders that actually deliver the LogEvents.
            </p>
            <h4>Logger Hierarchy</h4>
            <p>The first and foremost advantage of any logging API over plain
              <code>System.out.println</code>
              resides in its ability to disable
              certain log statements while allowing others to print unhindered. This
              capability assumes that the logging space, that is, the space of all
              possible logging statements, is categorized according to some
              developer-chosen criteria.
            </p>
            <p>In Log4j 1.x the Logger Hierarchy was maintained through a relationship between Loggers.
              In Log4j 2 this relationship no longer exists. Instead, the hierarchy is maintained
              in the relationship between LoggerConfig objects.
            </p>
    
            <p>Loggers and LoggerConfigs are named entities. Logger names are case-sensitive and
              they follow the hierarchical naming rule:
            </p>
    
            <div class="well">
              <dl>
                <dt>Named Hierarchy</dt>
                <dd>
                  A LoggerConfig is said to be an <em>ancestor</em> of another LoggerConfig if its name followed by a dot
                  is a prefix of the <em>descendant</em> logger name. A LoggerConfig is said to be a <em>parent</em> of a
                  <em>child</em> LoggerConfig if there are no ancestors between itself and the descendant LoggerConfig.
                </dd>
              </dl>
            </div>
    
            <p>For example, the LoggerConfig named
              <code>"com.foo"</code>
              is a parent
              of the LoggerConfig named<code>"com.foo.Bar"</code>. Similarly,
              <code>"java"</code>
              is a parent of
              <code>"java.util"</code>
              and an
              ancestor of <code>"java.util.Vector"</code>. This naming scheme
              should be familiar to most developers.
            </p>
    
            <p>The root LoggerConfig resides at the top of the LoggerConfig hierarchy. It
              is exceptional in that it always exists and it is part of every hierarchy. A Logger
              that is directly linked to the root LoggerConfig can be obtained as follows:
            </p>
              <pre class="prettyprint">Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);</pre>
            <p>
              Alternatively, and more simply:
            </p>
              <pre class="prettyprint">Logger logger = LogManager.getRootLogger();</pre>
            <p>
              All other Loggers can be retrieved using the
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.String)">
                LogManager.getLogger
              </a>
              static method by passing the name of the desired Logger. Further information on the Logging
              API can be found in the <a href="../log4j-api/api.html">Log4j 2 API</a>.
            </p>
            <h4>LoggerContext</h4>
            <p>
              The
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/LoggerContext.html">LoggerContext</a>
              acts as the anchor point for the Logging system. However, it is possible to have multiple active
              LoggerContexts in an application depending on the circumstances.
              More details on the LoggerContext are in the <a href="logsep.html">Log Separation</a> section.
            </p>
            <h4>Configuration</h4>
            <p>Every LoggerContext has an active
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html">
                Configuration</a>.
              The Configuration contains all the Appenders,
              context-wide Filters, LoggerConfigs and contains the reference to the StrSubstitutor. During
              reconfiguration two Configuration objects will exist. Once all Loggers have been redirected to
              the new Configuration, the old Configuration will be stopped and discarded.
            </p>
            <h4>Logger</h4>
            <p>As stated previously, Loggers are created by calling
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.String)">LogManager.getLogger</a>.
              The Logger itself performs no direct actions. It simply has a name and is associated with a LoggerConfig.
              It extends
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/spi/AbstractLogger.html">
                AbstractLogger
              </a>
              and implements the required methods. As the configuration is modified Loggers may become associated
              with a different LoggerConfig, thus causing their behavior to be modified.
            </p>
            <h5>Retrieving Loggers</h5>
            <p>
              Calling the <code>LogManager.getLogger</code> method with the same name will always return a reference to the
              exact same Logger object.
            </p>
    
            <p>For example, in
            </p>
    <pre class="prettyprint">
    Logger x = LogManager.getLogger("wombat");
    Logger y = LogManager.getLogger("wombat");
    </pre>
            <p>
              <code>x</code> and <code>y</code> refer to <em>exactly</em> the same Logger object.
            </p>
    
            <p>Configuration of the log4j environment is typically done at
              application initialization. The preferred way is by reading a
              configuration file. This is discussed in <a href="configuration.html">Configuration</a>.
            </p>
    
            <p>Log4j makes it easy to name Loggers by <em>software component</em>. This can be accomplished
              by instantiating a Logger in each class, with the logger name equal to the fully
              qualified name of the class. This is a useful and straightforward
              method of defining loggers. As the log output bears the name of the
              generating Logger, this naming strategy makes it easy to identify
              the origin of a log message. However, this is only one possible,
              albeit common, strategy for naming loggers. Log4j does not restrict
              the possible set of loggers. The developer is free to name the
              loggers as desired.
            </p>
    
            <p>Since naming Loggers after their owning class is such a common idiom, the convenience method
              <code>LogManager.getLogger()</code> is provided to automatically use the calling class's fully
              qualified class name as the Logger name.
            </p>
    
            <p>Nevertheless, naming loggers after the class where they are
              located seems to be the best strategy known so far.
            </p>
            <h4>LoggerConfig</h4>
            <p>
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/LoggerConfig.html">LoggerConfig</a>
              objects are created when Loggers are declared in the logging configuration.
              The LoggerConfig contains a set of Filters that must allow the LogEvent to pass before it will be
              passed to any Appenders. It contains references to the set of Appenders that should be used to
              process the event.
            </p>
            <h5>Log Levels</h5>
            <p>LoggerConfigs will be assigned a Log
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/Level.html">Level</a>. The set of built-in
              levels includes TRACE, DEBUG, INFO, WARN, ERROR, and FATAL. Log4j 2 also supports
              <a href="customloglevels.html">custom log levels</a>.
              Another mechanism for getting more granularity is to use
              <a href="../log4j-api/api.html#Markers">Markers</a> instead.
            </p>
            <p>
              <a href="http://logging.apache.org/log4j/1.2/manual.html">Log4j 1.x</a>
              and
              <a href="http://logback.qos.ch/manual/architecture.html#effectiveLevel">Logback</a>
              both have the concept of "Level Inheritance". In Log4j 2, Loggers and LoggerConfigs are two different
              objects so this concept is implemented differently. Each Logger references the
              appropriate LoggerConfig which in turn can reference its parent, thus achieving the same effect.
            </p>
            <p>Below are five tables with various assigned level values and the resulting levels that
              will be associated with each Logger. Note that in all these cases if the root LoggerConfig
              is not configured a default Level will be assigned to it.
            </p>
    
            <table style="width: 40%">
              <caption align="bottom">Example 1</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>Logger Level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X.Y.Z</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
            </table>
    
            <p>In example 1 above, only the root logger is configured and has a Log Level. All the other
              Loggers reference the root LoggerConfig and use its Level.
            </p>
    
            <table style="width: 40%">
              <caption align="bottom">Example 2</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>Level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>X.Y</td>
                <td>INFO</td>
                <td>INFO</td>
              </tr>
              <tr>
                <td>X.Y.Z</td>
                <td>X.Y.Z</td>
                <td>WARN</td>
                <td>WARN</td>
              </tr>
            </table>
    
            <p>In example 2, all loggers have a configured LoggerConfig and obtain their Level
              from it.
            </p>
    
            <table style="width: 40%">
              <caption align="bottom">Example 3</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>Level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y.Z</td>
                <td>X.Y.Z</td>
                <td>WARN</td>
                <td>WARN</td>
              </tr>
            </table>
    
            <p>In example 3, the loggers<code>root</code>,
              <code>X</code>
              and
              <code>X.Y.Z</code>
              each have a configured LoggerConfig with the same name. The Logger
              <code>X.Y</code>
              does not have a configured LoggerConfig with a matching name so uses
              the configuration of LoggerConfig
              <code>X</code>
              since that is the LoggerConfig whose
              name has the longest match to the start of the Logger's name.
            </p>
    
            <table style="width: 40%">
              <caption align="bottom">Example 4</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y.Z</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
            </table>
    
            <p>In example 4, the loggers
              <code>root</code>
              and
              <code>X</code>
              each have a Configured
              LoggerConfig with the same name. The loggers
              <code>X.Y</code>
              and
              <code>X.Y.Z</code>
              do not have configured LoggerConfigs and so get their Level from the LoggerConfig
              assigned to them,<code>X</code>, since it is the LoggerConfig whose name has the
              longest match to the start of the Logger's name.
            </p>
    
            <table style="width: 40%">
              <caption align="bottom">Example 5</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>X.Y</td>
                <td>INFO</td>
                <td>INFO</td>
              </tr>
              <tr>
                <td>X.YZ</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
            </table>
    
            <p>In example 5, the loggers<code>root</code>.<code>X</code>, and
              <code>X.Y</code>
              each
              have a Configured LoggerConfig with the same name. The logger
              <code>X.YZ</code>
              does not have configured LoggerConfig and so gets its Level from the LoggerConfig
              assigned to it,<code>X</code>, since it is the LoggerConfig whose name has the
              longest match to the start of the Logger's name. It is not associated with LoggerConfig
              <code>X.Y</code>
              since tokens after periods must match exactly.
            </p>
            <table style="width: 40%">
              <caption align="bottom">Example 6</caption>
              <tr>
                <th>Logger Name</th>
                <th>Assigned LoggerConfig</th>
                <th>LoggerConfig Level</th>
                <th>Level</th>
              </tr>
              <tr>
                <td>root</td>
                <td>root</td>
                <td>DEBUG</td>
                <td>DEBUG</td>
              </tr>
              <tr>
                <td>X</td>
                <td>X</td>
                <td>ERROR</td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y</td>
                <td>X.Y</td>
                <td></td>
                <td>ERROR</td>
              </tr>
              <tr>
                <td>X.Y.Z</td>
                <td>X.Y</td>
                <td></td>
                <td>ERROR</td>
              </tr>
            </table>
    
            <p>In example 6, LoggerConfig X.Y it has no configured level so it inherits its level
              from LoggerConfig X. Logger X.Y.Z uses LoggerConfig X.Y since it doesn't have a LoggerConfig with
              a name that exactly matches. It too inherits its logging level from LoggerConfig X.
            </p>
    
            <p>The table below illustrates how Level filtering works. In the table, the vertical
              header shows the Level of the LogEvent, while the horizontal header shows the Level associated
              with the appropriate LoggerConfig. The intersection identifies whether the LogEvent would
              be allowed to pass for further processing (Yes) or discarded (No).
            </p>
            <table>
              <tr>
                <th>Event Level</th>
                <th style="text-align: center" colspan="6">LoggerConfig Level</th>
              </tr>
              <tr>
                <th>&#160;</th>
                <th>TRACE</th>
                <th>DEBUG</th>
                <th>INFO</th>
                <th>WARN</th>
                <th>ERROR</th>
                <th>FATAL</th>
                <th>OFF</th>
              </tr>
              <tr>
                <th>ALL</th>
                <td class="big-red">YES</td>
                <td class="big-red">YES</td>
                <td class="big-red">YES</td>
                <td class="big-red">YES</td>
                <td class="big-red">YES</td>
                <td class="big-red">YES</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>TRACE</th>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>DEBUG</th>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>INFO</th>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>WARN</th>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>ERROR</th>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>FATAL</th>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-green">YES</td>
                <td class="big-red">NO</td>
              </tr>
              <tr>
                <th>OFF</th>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
                <td class="big-red">NO</td>
              </tr>
            </table>
    
            <h4>Filter</h4>
            <p>In addition to the automatic log Level filtering that takes place as described in the previous
              section, Log4j provides
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/Filter.html">Filter</a>s that can
              be applied before control is passed to any LoggerConfig, after control is passed to a LoggerConfig
              but before calling any Appenders, after control is passed to a LoggerConfig but before calling a
              specific Appender, and on each Appender. In a manner very similar to firewall filters,
              each Filter can return one of three results, <code>Accept</code>, <code>Deny</code> or <code>Neutral</code>.
              A response of <code>Accept</code> means that no other Filters should be called and the event should progress.
              A response of <code>Deny</code> means the event should be immediately ignored and control should be returned
              to the caller. A response of <code>Neutral</code> indicates the event should be passed to other Filters. If
              there are no other Filters the event will be processed.
            </p>
            <p>Although an event may be accepted by a Filter the event still might not be logged. This can happen
              when the event is accepted by the pre-LoggerConfig Filter but is then denied by a LoggerConfig
              filter or is denied by all Appenders.
            </p>
    
            <h4>Appender</h4>
    
            <p>The ability to selectively enable or disable logging requests based
              on their logger is only part of the picture. Log4j allows logging
              requests to print to multiple destinations. In log4j speak, an output
              destination is called an
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html">Appender</a>.
              Currently, appenders exist for the console, files, remote socket servers, Apache Flume,
              JMS, remote UNIX Syslog daemons, and various database APIs. See the section on
              <a href="appenders.html">Appenders</a> for more details on the various types available.
              More than one Appender can be attached to a Logger.
            </p>
            <p>An Appender can be added to a Logger by calling the
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html#addLoggerAppender(org.apache.logging.log4j.core.Logger, org.apache.logging.log4j.core.Appender)">addLoggerAppender</a>
              method of the current Configuration. If a LoggerConfig matching the name of the Logger does
              not exist, one will be created, the Appender will be attached to it and then all Loggers
              will be notified to update their LoggerConfig references.
            </p>
            <p><b>Each enabled logging request for a given logger will be forwarded to all the appenders in
              that Logger's LoggerConfig as well as the Appenders of the LoggerConfig's parents.</b> In
              other words, Appenders are inherited additively from the LoggerConfig hierarchy. For example,
              if a console appender is added to the root logger, then all enabled logging requests will at
              least print on the console. If in addition a file appender is added to a LoggerConfig, say
              <em>C</em>, then enabled logging requests for <em>C</em> and <em>C</em>'s children will print
              in a file <em>and</em> on the console. It is possible to override this default behavior so that
              Appender accumulation is no longer additive by setting <code>additivity="false"</code> on the
              Logger declaration in the configuration file.
            </p>
            <p>The rules governing appender additivity are summarized below.</p>
    
            <div class="well">
              <dl>
    	        <dt><b>Appender Additivity</b></dt>
    	          <dd>
                    <p>
                      The output of a log statement of Logger <i>L</i> will go to all the Appenders in the LoggerConfig
                      associated with <i>L</i> and the ancestors of that LoggerConfig. This is the meaning of the term
                      "appender additivity".
                    </p>
    	            <p>
                      However, if an ancestor of the LoggerConfig associated with Logger <i>L</i>, say <i>P</i>, has the
                      additivity flag set to <code>false</code>, then <i>L</i>'s output will be directed to all the
                      appenders in <i>L</i>'s LoggerConfig and it's ancestors up to and including <i>P</i> but not the
                      Appenders in any of the ancestors of <i>P</i>.
                    </p>
    	            <p>Loggers have their additivity flag set to <code>true</code> by default.</p>
                </dd>
              </dl>
            </div>
    
            <p>The table below shows an example:</p>
    
            <table>
              <tr>
                <th>Logger<br />Name </th>
                <th>Added<br/>Appenders</th>
                <th>Additivity<br/>Flag</th>
                <th>Output Targets</th>
                <th>Comment</th>
              </tr>
              <tr>
                <td>root</td>
                <td>A1</td>
                <td>not applicable</td>
                <td>A1</td>
                <td>The root logger has no parent so additivity does not apply to it.</td>
              </tr>
              <tr>
                <td>x</td>
                <td>A-x1, A-x2</td>
                <td>true </td>
                <td>A1, A-x1, A-x2</td>
                <td>Appenders of "x" and root.</td>
              </tr>
              <tr>
                <td>x.y</td>
                <td>none</td>
                <td>true </td>
                <td>A1, A-x1, A-x2</td>
                <td>Appenders of "x" and root. It would not be typical to configure a Logger with no Appenders.</td>
              </tr>
              <tr>
                <td>x.y.z</td>
                <td>A-xyz1</td>
                <td>true </td>
                <td>A1, A-x1, A-x2, A-xyz1</td>
                <td>Appenders in "x.y.z", "x" and root.</td>
              </tr>
              <tr>
                <td>security</td>
                <td>A-sec</td>
                <td><font color="blue">false</font></td>
                <td>A-sec</td>
                <td>No appender accumulation since the additivity flag is set to <code>false</code>.</td>
              </tr>
              <tr>
                <td>security.access</td>
                <td>none</td>
                <td>true</td>
                <td>A-sec</td>
                <td>Only appenders of "security" because the additivity flag in "security" is
                  set to <code>false</code>.
                </td>
              </tr>
            </table>
    
            <h4>Layout</h4>
            <p>More often than not, users wish to customize not only the output destination but also the output format.
              This is accomplished by associating a
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/Layout.html">Layout</a>
              with an Appender. The Layout is responsible for formatting the LogEvent according to the user's
              wishes, whereas an appender takes care of sending the formatted output to its destination.
              The <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html">PatternLayout</a>,
              part of the standard log4j distribution, lets the user specify the output
              format according to conversion patterns similar to the C language <code>printf</code> function.
            </p>
    
            <p>For example, the PatternLayout with the conversion pattern "%r [%t]
              %-5p %c - %m%n" will output something akin to:
            </p>
              <pre>176 [main] INFO  org.foo.Bar - Located nearest gas station.</pre>
    
            <p>The first field is the number of milliseconds elapsed since the
              start of the program.  The second field is the thread making the log
              request.  The third field is the level of the log statement. The
              fourth field is the name of the logger associated with the log
              request. The text after the '-' is the message of the statement.
            </p>
    
            <p>Log4j comes with many different <a href="layouts.html">Layouts</a> for various use cases such as
              JSON, XML, HTML, and Syslog (including the new RFC 5424 version). Other appenders such as the
              database connectors fill in specified fields instead of a particular textual layout.
            </p>
    
            <p>Just as importantly, log4j will render the content of the log
              message according to user specified criteria. For example, if you
              frequently need to log <code>Oranges</code>, an object type used in
              your current project, then you can create an OrangeMessage that accepts an
              Orange instance and pass that to Log4j so that the Orange object can
              be formatted into an appropriate byte array when required.
            </p>
    
            <h4>StrSubstitutor and StrLookup</h4>
            <p>The
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrSubstitutor.html">
                StrSubstitutor
              </a>
              class and
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a>
              interface were borrowed from
              <a href="https://commons.apache.org/proper/commons-lang/">Apache Commons Lang</a> and then modified
              to support evaluating LogEvents. In addition the
              <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/Interpolator.html">Interpolator</a>
              class was borrowed from Apache Commons Configuration to allow the StrSubstitutor to evaluate variables
              that from multiple StrLookups. It too was modified to support evaluating LogEvents. Together these
              provide a mechanism to allow the configuration to reference variables coming from System Properties,
              the configuration file, the ThreadContext Map, StructuredData in the LogEvent. The variables can
              either be resolved when the configuration is processed or as each event is processed, if the component
              is capable of handling it. See
              <a href="lookups.html">Lookups</a>
              for more information.
            </p>
    
          </subsection>
    
        </section>
      </body>
    </document>
    ���������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/async.xml���������������������������������������������0000664�0000000�0000000�00000134216�12577562624�0022754�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Asynchronous Loggers for Low-Latency Logging</title>
        <author email="rpopma@apache.org">Remko Popma</author>
      </properties>
      <body>
        <section name="Asynchronous Loggers for Low-Latency Logging">
          <p>
            Asynchronous logging can improve your application's performance by executing the I/O operations
            in a separate thread. Log4j 2 makes a number of improvements in this area.
          </p>
          <ul>
            <li>
              <b>Asynchronous Loggers</b> are a new addition to Log4j 2.
              Their aim is to return from the call to Logger.log to the application as
              soon as possible. You can choose between making all Loggers asynchronous
              or using a mixture of synchronous and asynchronous Loggers. Making all
              Loggers asynchronous will give the best performance, while mixing
              gives you more flexibility.
            </li>
            <li>
              <b>LMAX Disruptor technology</b>. Asynchronous Loggers internally use the
              <a href="#UnderTheHood">Disruptor</a>, a lock-free inter-thread
              communication library, instead of queues, resulting in higher throughput and lower latency.
            </li>
            <li>
              <b>Asynchronous Appenders</b> already existed in Log4j 1.x, but have
              been enhanced to flush to disk at the end of a batch (when the queue is empty).
              This produces the same result as configuring "immediateFlush=true", that is, all
              received log events are always available on disk, but is more efficient because it does not need to
              touch the disk on each and every log event. (Async Appenders use ArrayBlockingQueue internally and
              do not need the disruptor jar on the classpath.)
            </li>
            <li>(For synchronous and asynchronous use) <b>Random Access File Appenders</b>
              are an alternative to Buffered File Appenders. Under the hood, these
              new appenders use a ByteBuffer + RandomAccessFile instead of a BufferedOutputStream. In our testing
              this was about 20-200% faster. These appenders can also be used
              with synchronous loggers and will give the same performance benefits.
              Random Access File Appenders do not need the disruptor jar on the classpath.
            </li>
          </ul>
          <a name="Trade-offs" />
          <subsection name="Trade-offs">
            <p>
              Although asynchronous logging can give significant performance benefits,
              there are situations where you may want to choose synchronous logging.
              This section describes some of the trade-offs of asynchronous logging.
            </p>
            <p>
              <b>Benefits</b>
            </p>
            <ul>
              <li>
                Higher <a href="#Performance">throughput</a>. With an asynchronous logger
                your application can log messages at 6 - 68 times the rate of a synchronous logger.
              </li>
              <li>
                Lower logging <a href="#Latency">latency</a>.
                Latency is the time it takes for a call to Logger.log to return.
                Asynchronous Loggers have consistently lower latency than synchronous loggers or even
                queue-based asynchronous appenders. Applications interested in low latency often care
                not only about average latency, but also about worst-case latency.
                Our performance comparison shows that Asynchronous Loggers also do better when comparing the
                maximum latency of 99% or even 99.99% of observations with other logging methods.
              </li>
              <li>Prevent or dampen latency spikes during bursts of events. If the queue size is configured
                large enough to handle spikes, asynchronous logging will help prevent your
                application from falling behind (as much) during sudden bursts of activity.
              </li>
            </ul>
            <b>Drawbacks</b>
            <ul>
              <li>
                Error handling. If a problem happens during the logging process and an exception is thrown,
                it is less easy for an asynchronous logger or appender to signal this problem to the
                application. This can partly be alleviated by configuring an <tt>ExceptionHandler</tt>,
                but this may still not cover all cases. For this reason, if logging is part of your business logic,
                for example if you are using Log4j as an audit logging framework, we would
                recommend to synchronously log those audit messages.
                (Note that you can still <a href="#MixedSync-Async">combine</a> them
                and use asynchronous logging for debug/trace logging in addition to synchronous
                logging for the audit trail.)
              </li>
              <li>
                In some rare cases, care must be taken with mutable messages.
                Most of the time you don't need to worry about this. Log4 will ensure that log messages like
                <code>logger.debug("My object is {}", myObject)</code> will use the state of the
                <code>myObject</code> parameter at the time of the call to <code>logger.debug()</code>.
                The log message will not change even if <code>myObject</code> is modified later.
                It is safe to asynchronously log mutable objects because most
                <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/Message.html">Message</a>
                implementations built-in to Log4j take a snapshot of the parameters.
                There are some exceptions however:
                <a
                  href="../log4j-api/apidocs/org/apache/logging/log4j/message/MapMessage.html">MapMessage</a>
                and
                <a
                  href="../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html">StructuredDataMessage</a>
                are mutable by design: fields can be added to these messages after the message object was created.
                These messages should not be modified after they are logged with asynchronous loggers or
                asynchronous appenders; you may or may not see the modifications in the resulting log output.
                Similarly, custom
                <a
                  href="../log4j-api/apidocs/org/apache/logging/log4j/message/Message.html">Message</a>
                implementations should be designed with asynchronous use in mind, and either take a snapshot
                of their parameters at construction time, or document their thread-safety characteristics.
              </li>
            </ul>
          </subsection>
          <a name="AllAsync" />
          <subsection name="Making All Loggers Asynchronous">
            <p>
              <i>Requires disruptor-3.0.0.jar or higher on the classpath.
              </i>
            </p>
            <p>
              This is simplest to configure and gives the best performance. To make all loggers asynchronous,
              add the disruptor jar to the classpath and set the system property <tt>Log4jContextSelector</tt>
              to <tt>org.apache.logging.log4j.core.async.AsyncLoggerContextSelector</tt>.
            </p>
            <p>
              By default, <a href="#Location">location</a> is not passed to the I/O thread by
              asynchronous loggers. If one of your layouts or custom filters needs location information, you need to set
              "includeLocation=true" in the configuration of all relevant loggers, including the root logger.
            </p>
            <p>
              A configuration that does not require location might look like:
            </p>
            <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    
    <!-- Don't forget to set system property
    -DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
         to make all loggers asynchronous. -->
    
    <Configuration status="WARN">
      <Appenders>
        <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
        <RandomAccessFile name="RandomAccessFile" fileName="async.log" immediateFlush="false" append="false">
          <PatternLayout>
            <Pattern>%d %p %c{1.} [%t] %m %ex%n</Pattern>
          </PatternLayout>
        </RandomAccessFile>
      </Appenders>
      <Loggers>
        <Root level="info" includeLocation="false">
          <AppenderRef ref="RandomAccessFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            <p>
              When <tt>AsyncLoggerContextSelector</tt> is used to make all loggers asynchronous, make sure to use normal
              <tt>&lt;root&gt;</tt> and <tt>&lt;logger&gt;</tt> elements in the configuration. The
              AsyncLoggerContextSelector will ensure that all loggers are asynchronous, using a mechanism
              that is different from what happens when you configure <tt>&lt;asyncRoot&gt;</tt>
              or <tt>&lt;asyncLogger&gt;</tt>.
              The latter elements are intended for mixing async with sync loggers. If you use both mechanisms
              together you will end up with two background threads, where your application passes the log
              message to thread A, which passes the message to thread B, which then finally
              logs the message to disk. This works, but there will be an unnecessary step in the middle.
            </p>
            <p>
              There are a few system properties you can use to control aspects of the asynchronous logging subsystem.
              Some of these can be used to tune logging performance.
            </p>
            <a name="SysPropsAllAsync" />
            <table>
              <caption align="top">System Properties to configure all asynchronous loggers
              </caption>
              <tr>
                <th>System Property</th>
                <th>Default Value</th>
                <th>Description</th>
              </tr>
              <tr>
                <td>AsyncLogger.ExceptionHandler</td>
                <td>
                  <tt>null</tt>
                </td>
                <td>
                  Fully qualified name of a class that implements the <tt>com.lmax.disruptor.ExceptionHandler</tt>
                  interface. The class needs to have a public zero-argument constructor.
                  If specified, this class will be notified when an exception occurs while logging the messages.
                </td>
              </tr>
              <tr>
                <td>AsyncLogger.RingBufferSize</td>
                <td>256&#160;*&#160;1024</td>
                <td>
                  Size (number of slots) in the RingBuffer used by the asynchronous logging subsystem.
                  Make this value large enough to deal with bursts of activity. The minimum size is 128.
                  The RingBuffer will be pre-allocated at first use and will never grow or shrink
                  during the life of the system.
                </td>
              </tr>
              <tr>
                <td>AsyncLogger.WaitStrategy</td>
                <td>
                  <tt>Sleep</tt>
                </td>
                <td>
                  Valid values: Block, Sleep, Yield.
                  <br />
                  <tt>Block</tt> is a strategy that uses a lock and condition variable for the I/O thread waiting for log events.
                  Block can be used when throughput and low-latency are not as important as CPU resource.
                  Recommended for resource constrained/virtualised environments.
                  <br />
                  <tt>Sleep</tt> is a strategy that initially spins, then uses a Thread.yield(), and
                  eventually parks for the minimum number of nanos the OS and JVM will allow
                  while the I/O thread is waiting for log events. Sleep is a good compromise between performance
                  and CPU resource. 
                  This strategy has very low impact on the application thread, in exchange for some additional
                  latency for actually getting the message logged.
                  <br />
                  <tt>Yield</tt> is a strategy that uses a Thread.yield() for waiting for log events after an initially spinning.
                  Yield is a good compromise between performance and CPU resource, but may use more CPU than Sleep
                  in order to get the message logged to disk sooner.
                </td>
              </tr>
              <tr>
                <td>AsyncLogger.ThreadNameStrategy</td>
                <td>
                  <tt>CACHED</tt>
                </td>
                <td>
                  Valid values: CACHED, UNCACHED.
                  <br />
                  By default, AsyncLogger caches the thread name in a ThreadLocal variable to improve performance.
                  Specify the <tt>UNCACHED</tt> option if your application modifies the thread name at runtime (with
                  <tt>Thread.currentThread().setName()</tt>)
                  and you want to see the new thread name reflected in the log.
                </td>
              </tr>
              <tr>
                <td>log4j.Clock</td>
                <td>
                  <tt>SystemClock</tt>
                </td>
                <td>
                  <p>
                    Implementation of the <tt>org.apache.logging.log4j.core.helpers.Clock</tt>
                    interface that is used for timestamping the log events when all loggers are asynchronous.
                    <br />
                    By default, <tt>System.currentTimeMillis</tt> is called on every log event.
                  </p>
                  <p>
                    <tt>CachedClock</tt> is an optimization intended for low-latency applications where
                    time stamps are generated from a clock that updates its internal time in a background thread once
                    every millisecond, or every 1024 log events, whichever comes first.
                    This reduces logging latency a little, at the cost of some precision in the logged time stamps.
                    Unless you are logging many events, you may see "jumps" of 10-16 milliseconds between log time stamps.
                    WEB APPLICATION WARNING: The use of a background thread may cause issues
                    for web applications and OSGi applications so CachedClock is not recommended for this kind
                    of applications.
                  </p>
                  <p>
                    You can also specify a fully qualified class name of a custom class that implements the
                    <tt>Clock</tt> interface.
                  </p>
                </td>
              </tr>
            </table>
          </subsection>
          <a name="MixedSync-Async" />
          <subsection name="Mixing Synchronous and Asynchronous Loggers">
            <p><i>Requires disruptor-3.0.0.jar or higher on the classpath. There is no need to set system property
                "Log4jContextSelector" to any value.</i></p>
            <p>
              Synchronous and asynchronous loggers can be combined in configuration.
              This gives you more flexibility at the cost of a slight loss in performance (compared to making
              all loggers asynchronous). Use the <tt>&lt;asyncRoot&gt;</tt> or <tt>&lt;asyncLogger&gt;</tt>
              configuration elements to specify the loggers that need to be asynchronous.
              A configuration can contain only one root logger (either a <tt>&lt;root&gt;</tt>
              or an <tt>&lt;asyncRoot&gt;</tt> element), but otherwise async and non-async loggers may be
              combined.
              For example, a configuration file containing <tt>&lt;asyncLogger&gt;</tt> elements
              can also contain <tt>&lt;root&gt;</tt> and
              <tt>&lt;logger&gt;</tt> elements for the synchronous loggers.
            </p>
            <p>
              By default, <a href="#Location">location</a> is not passed to the I/O thread by asynchronous loggers.
              If one of your layouts or custom filters needs location information, you need to set
              "includeLocation=true" in the configuration of all relevant loggers, including the root logger.
            </p>
            <p>
              A configuration that mixes asynchronous loggers might look like:
            </p>
            <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    
    <!-- No need to set system property "Log4jContextSelector" to any value
         when using <asyncLogger> or <asyncRoot>. -->
    
    <Configuration status="WARN">
      <Appenders>
        <!-- Async Loggers will auto-flush in batches, so switch off immediateFlush. -->
        <RandomAccessFile name="RandomAccessFile" fileName="asyncWithLocation.log"
                  immediateFlush="false" append="false">
          <PatternLayout>
            <Pattern>%d %p %class{1.} [%t] %location %m %ex%n</Pattern>
          </PatternLayout>
        </RandomAccessFile>
      </Appenders>
      <Loggers>
        <!-- pattern layout actually uses location, so we need to include it -->
        <AsyncLogger name="com.foo.Bar" level="trace" includeLocation="true">
          <AppenderRef ref="RandomAccessFile"/>
        </AsyncLogger>
        <Root level="info" includeLocation="true">
          <AppenderRef ref="RandomAccessFile"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
            <p>
              There are a few system properties you can use to control aspects of the asynchronous logging subsystem.
              Some of these can be used to tune logging performance.
            </p>
            <a name="SysPropsMixedSync-Async" />
            <table>
              <caption align="top">System Properties to configure mixed asynchronous and normal loggers</caption>
              <tr>
                <th>System Property</th>
                <th>Default Value</th>
                <th>Description</th>
              </tr>
              <tr>
                <td>AsyncLoggerConfig.ExceptionHandler</td>
                <td>
                  <tt>null</tt>
                </td>
                <td>
                  Fully qualified name of a class that implements the <tt>com.lmax.disruptor.ExceptionHandler</tt>
                  interface. The class needs to have a public zero-argument constructor.
                  If specified, this class will be notified when an exception occurs while logging the messages.
                </td>
              </tr>
              <tr>
                <td>AsyncLoggerConfig.RingBufferSize</td>
                <td>256&#160;*&#160;1024</td>
                <td>
                  Size (number of slots) in the RingBuffer used by the asynchronous logging subsystem.
                  Make this value large enough to deal with bursts of activity. The minimum size is 128.
                  The RingBuffer will be pre-allocated at first use and will never grow
                  or shrink during the life of the system.
                </td>
              </tr>
              <tr>
                <td>AsyncLoggerConfig.WaitStrategy</td>
                <td>
                  <tt>Sleep</tt>
                </td>
                <td>
                  Valid values: Block, Sleep, Yield.
                  <br />
                  <tt>Block</tt> is a strategy that uses a lock and condition variable for the I/O thread waiting for log events.
                  Block can be used when throughput and low-latency are not as important as CPU resource.
                  Recommended for resource constrained/virtualised environments.
                  <br />
                  <tt>Sleep</tt> is a strategy that initially spins, then uses a Thread.yield(), and
                  eventually parks for the minimum number of nanos the OS and JVM will allow
                  while the I/O thread is waiting for log events. Sleep is a good compromise between performance
                  and CPU resource.
                  This strategy has very low impact on the application thread, in exchange for some additional
                  latency for actually getting the message logged.
                  <br />
                  <tt>Yield</tt> is a strategy that uses a Thread.yield() for waiting for log events after an initially spinning.
                  Yield is a good compromise between performance and CPU resource, but may use more CPU than Sleep
                  in order to get the message logged to disk sooner.
                </td>
              </tr>
            </table>
          </subsection>
          <a name="Location" />
          <subsection name="Location, location, location...">
            <p>
              If one of the layouts is configured with a location-related attribute like HTML
              <a href="layouts.html#HtmlLocationInfo">locationInfo</a>,
              or one of the patterns <a href="layouts.html#PatternClass">%C or $class</a>,
              <a href="layouts.html#PatternFile">%F or %file</a>,
              <a href="layouts.html#PatternLocation">%l or %location</a>,
              <a href="layouts.html#PatternLine">%L or %line</a>,
              <a href="layouts.html#PatternMethod">%M or %method</a>,
              Log4j will take a snapshot of the stack, and walk the stack trace to find the location information.
            </p>
            <p>
              This is an expensive operation: 1.3 - 5 times slower for synchronous loggers. Synchronous loggers wait as
              long as possible before they take this stack snapshot. If no location is required, the snapshot will never be taken.
            </p>
            <p>
              However, asynchronous loggers need to make this decision before passing the
              log message to another thread; the location information will be lost after that point.
              The performance impact of taking a stack trace snapshot is even higher for asynchronous loggers:
              logging with location is 4 - 20 times slower than without location.
              For this reason, asynchronous loggers and asynchronous appenders do not include location information by default.
            </p>
            <p>
              You can override the default behaviour in your logger or asynchronous appender configuration
              by specifying <tt>includeLocation="true"</tt>.
            </p>
            <p>
            </p>
          </subsection>
          <a name="Performance" />
          <subsection name="Asynchronous Logging Performance">
            <p>
              The performance results below were all derived from running the PerfTest, MTPerfTest and PerfTestDriver
              classes which can be found in the Log4j 2 unit test source directory.
              All tests were done using the default settings (SystemClock and SleepingWaitStrategy).
              The methodology used was the same for all tests:
            </p>
            <ul>
              <li>First, warm up the JVM by logging 200,000 log messages of 500 characters.
              </li>
              <li>Repeat the warm-up 10 times, then wait 10 seconds for the I/O thread to catch up and buffers to drain.</li>
              <li>Latency test: at less than saturation, measure how long a call to Logger.log takes.
                Pause for 10 microseconds * threadCount between measurements. Repeat this 5 million times,
                and measure average latency, latency of 99% of observations and 99.99% of observations.</li>
              <li>Throughput test: measure how long it takes to execute 256 * 1024 / threadCount calls to Logger.log
                and express the result in messages per second.
              </li>
              <li>Repeat the test 5 times and average the results.</li>
            </ul>
            <p>The results below were obtained with log4j-2.0-beta5, disruptor-3.0.0.beta3,
              log4j-1.2.17 and logback-1.0.10.
            </p>
            <h4>Logging Throughput</h4>
            <p>
              The graph below compares the throughput of synchronous loggers, asynchronous appenders and asynchronous
              loggers. This is the total throughput of all threads together. In the test with 64 threads,
              asynchronous loggers are 12 times faster than asynchronous appenders, and 68 times faster than
              synchronous loggers.
            </p>
            <p>
              Asynchronous loggers' throughput increases with the number of threads,
              whereas both synchronous loggers and asynchronous appenders
              have more or less constant throughput regardless of the number of
              threads that are doing the logging.
            </p>
            <p>
              <img src="../images/async-vs-sync-throughput.png"
                alt="Async loggers have much higher throughput than sync loggers." />
            </p>
    
            <h4>Asynchronous Throughput Comparison with Other Logging Packages</h4>
            <p>
              We also compared throughput of asynchronous loggers to the synchronous loggers and asynchronous
              appenders available in other logging packages, specifically log4j-1.2.17 and
              logback-1.0.10, with similar results. For asynchronous appenders, total logging throughput of all
              threads together remains roughly constant when adding more threads.
              Asynchronous loggers make more effective use of the multiple cores
              available on the machine in multi-threaded scenarios.
            </p>
            <p>
              <img src="../images/async-throughput-comparison.png" alt="Async loggers have the highest throughput." />
            </p>
            <p>On Solaris 10 (64bit) with JDK1.7.0_06, 4-core Xeon X5570 dual CPU
              @2.93Ghz with hyperthreading switched on (16 virtual cores):
            </p>
            <table>
              <caption align="top">Throughput per thread in
                messages/second</caption>
              <tr>
                <th>Logger</th>
                <th>1 thread</th>
                <th>2 threads</th>
                <th>4 threads</th>
                <th>8 threads</th>
                <th>16 threads</th>
                <th>32 threads</th>
                <th>64 threads</th>
              </tr>
              <tr>
                <td>Log4j 2: Loggers all asynchronous</td>
                <td align="right">2,652,412</td>
                <td align="right">909,119</td>
                <td align="right">776,993</td>
                <td align="right">516,365</td>
                <td align="right">239,246</td>
                <td align="right">253,791</td>
                <td align="right">288,997</td>
              </tr>
              <tr>
                <td>Log4j 2: Loggers mixed sync/async</td>
                <td align="right">2,454,358</td>
                <td align="right">839,394</td>
                <td align="right">854,578</td>
                <td align="right">597,913</td>
                <td align="right">261,003</td>
                <td align="right">216,863</td>
                <td align="right">218,937</td>
              </tr>
              <tr>
                <td>Log4j 2: Async Appender</td>
                <td align="right">1,713,429</td>
                <td align="right">603,019</td>
                <td align="right">331,506</td>
                <td align="right">149,408</td>
                <td align="right">86,107</td>
                <td align="right">45,529</td>
                <td align="right">23,980</td>
              </tr>
              <tr>
                <td>Log4j1: Async Appender</td>
                <td align="right">2,239,664</td>
                <td align="right">494,470</td>
                <td align="right">221,402</td>
                <td align="right">109,314</td>
                <td align="right">60,580</td>
                <td align="right">31,706</td>
                <td align="right">14,072</td>
              </tr>
              <tr>
                <td>Logback: Async Appender</td>
                <td align="right">2,206,907</td>
                <td align="right">624,082</td>
                <td align="right">307,500</td>
                <td align="right">160,096</td>
                <td align="right">85,701</td>
                <td align="right">43,422</td>
                <td align="right">21,303</td>
              </tr>
              <tr>
                <td>Log4j 2: Synchronous</td>
                <td align="right">273,536</td>
                <td align="right">136,523</td>
                <td align="right">67,609</td>
                <td align="right">34,404</td>
                <td align="right">15,373</td>
                <td align="right">7,903</td>
                <td align="right">4,253</td>
              </tr>
              <tr>
                <td>Log4j1: Synchronous</td>
                <td align="right">326,894</td>
                <td align="right">105,591</td>
                <td align="right">57,036</td>
                <td align="right">30,511</td>
                <td align="right">13,900</td>
                <td align="right">7,094</td>
                <td align="right">3,509</td>
              </tr>
              <tr>
                <td>Logback: Synchronous</td>
                <td align="right">178,063</td>
                <td align="right">65,000</td>
                <td align="right">34,372</td>
                <td align="right">16,903</td>
                <td align="right">8,334</td>
                <td align="right">3,985</td>
                <td align="right">1,967</td>
              </tr>
            </table>
            <p />
            <p>On Windows 7 (64bit) with JDK1.7.0_11, 2-core Intel i5-3317u CPU
              @1.70Ghz with hyperthreading switched on (4 virtual cores):
            </p>
            <table>
              <caption align="top">Throughput per thread in
                messages/second</caption>
              <tr>
                <th>Logger</th>
                <th>1 thread</th>
                <th>2 threads</th>
                <th>4 threads</th>
                <th>8 threads</th>
                <th>16 threads</th>
                <th>32 threads</th>
              </tr>
              <tr>
                <td>Log4j 2: Loggers all asynchronous</td>
                <td align="right">1,715,344</td>
                <td align="right">928,951</td>
                <td align="right">1,045,265</td>
                <td align="right">1,509,109</td>
                <td align="right">1,708,989</td>
                <td align="right">773,565</td>
              </tr>
              <tr>
                <td>Log4j 2: Loggers mixed sync/async</td>
                <td align="right">571,099</td>
                <td align="right">1,204,774</td>
                <td align="right">1,632,204</td>
                <td align="right">1,368,041</td>
                <td align="right">462,093</td>
                <td align="right">908,529</td>
              </tr>
              <tr>
                <td>Log4j 2: Async Appender</td>
                <td align="right">1,236,548</td>
                <td align="right">1,006,287</td>
                <td align="right">511,571</td>
                <td align="right">302,230</td>
                <td align="right">160,094</td>
                <td align="right">60,152</td>
              </tr>
              <tr>
                <td>Log4j1: Async Appender</td>
                <td align="right">1,373,195</td>
                <td align="right">911,657</td>
                <td align="right">636,899</td>
                <td align="right">406,405</td>
                <td align="right">202,777</td>
                <td align="right">162,964</td>
              </tr>
              <tr>
                <td>Logback: Async Appender</td>
                <td align="right">1,979,515</td>
                <td align="right">783,722</td>
                <td align="right">582,935</td>
                <td align="right">289,905</td>
                <td align="right">172,463</td>
                <td align="right">133,435</td>
              </tr>
              <tr>
                <td>Log4j 2: Synchronous</td>
                <td align="right">281,250</td>
                <td align="right">225,731</td>
                <td align="right">129,015</td>
                <td align="right">66,590</td>
                <td align="right">34,401</td>
                <td align="right">17,347</td>
              </tr>
              <tr>
                <td>Log4j1: Synchronous</td>
                <td align="right">147,824</td>
                <td align="right">72,383</td>
                <td align="right">32,865</td>
                <td align="right">18,025</td>
                <td align="right">8,937</td>
                <td align="right">4,440</td>
              </tr>
              <tr>
                <td>Logback: Synchronous</td>
                <td align="right">149,811</td>
                <td align="right">66,301</td>
                <td align="right">32,341</td>
                <td align="right">16,962</td>
                <td align="right">8,431</td>
                <td align="right">3,610</td>
              </tr>
            </table>
    
            <h4>Throughput of Logging With Location (includeLocation="true")
            </h4>
            <p>On Solaris 10 (64bit) with JDK1.7.0_06, 4-core Xeon X5570 dual CPU
              @2.93Ghz with hyperthreading switched off (8 virtual cores):
            </p>
            <table>
              <caption align="top">Throughput in log messages/second per thread</caption>
              <tr>
                <th>Logger (Log4j 2)</th>
                <th>1 thread</th>
                <th>2 threads</th>
                <th>4 threads</th>
                <th>8 threads</th>
              </tr>
              <tr>
                <td>Loggers all asynchronous</td>
                <td align="right">75,862</td>
                <td align="right">88,775</td>
                <td align="right">80,240</td>
                <td align="right">68,077</td>
              </tr>
              <tr>
                <td>Loggers mixed sync/async</td>
                <td align="right">61,993</td>
                <td align="right">66,164</td>
                <td align="right">55,735</td>
                <td align="right">52,843</td>
              </tr>
              <tr>
                <td>Async Appender</td>
                <td align="right">47,033</td>
                <td align="right">52,426</td>
                <td align="right">50,882</td>
                <td align="right">36,905</td>
              </tr>
              <tr>
                <td>Synchronous</td>
                <td align="right">31,054</td>
                <td align="right">33,175</td>
                <td align="right">29,791</td>
                <td align="right">23,628</td>
              </tr>
            </table>
            <p>As expected, logging location information has a large performance impact. Asynchronous loggers are 4 - 20
              times slower, while synchronous loggers are 1.3 - 5 times slower. However, if you do need
              location information, asynchronous logging will still be faster than synchronous logging.
            </p>
    
            <a name="Latency" />
            <h4>Latency</h4>
            <p>Latency tests are done by logging at less than saturation, measuring how long a call to Logger.log
              takes to return. After each call to Logger.log, the test waits for 10 microseconds * threadCount before continuing.
              Each thread logs 5 million messages.
            </p>
            <p>All the latency measurements below are results of tests run
              on Solaris 10 (64bit) with JDK1.7.0_06, 4-core Xeon X5570 dual CPU
              @2.93Ghz with hyperthreading switched on (16 virtual cores).
            </p>
            <p>
              <img src="../images/async-latency-histogram-64-threads.png"
                alt="Histogram of async latency" />
            </p>
            <p>Note that this is log-scale, not linear. The above graph compares the latency distributions of
              an asynchronous logger and a Log4j 1.2.17 Async Appender. This shows the latency of one thread
              during a test where 64 threads are logging in parallel.
              The test was run once for the async logger and once for the async appender.
            </p>
            <table>
              <caption align="top">Latency of a call to Logger.log() in nanoseconds</caption>
              <tr>
                <th />
                <th colspan="2">Average latency</th>
                <th colspan="2">99% observations less than</th>
                <th colspan="2">99.99% observations less than</th>
              </tr>
              <tr>
                <th />
                <th>1 thread</th>
                <th>64 threads</th>
                <th>1 thread</th>
                <th>64 threads</th>
                <th>1 thread</th>
                <th>64 threads</th>
              </tr>
              <tr>
                <td>Log4j 2: Loggers all async</td>
                <td align="right">677</td>
                <td align="right">4,135</td>
                <td align="right">1,638</td>
                <td align="right">4,096</td>
                <td align="right">8,192</td>
                <td align="right">16,128</td>
              </tr>
              <tr>
                <td>Log4j 2: Loggers mixed sync/async</td>
                <td align="right">648</td>
                <td align="right">4,873</td>
                <td align="right">1,228</td>
                <td align="right">4,096</td>
                <td align="right">8,192</td>
                <td align="right">16,384</td>
              </tr>
              <tr>
                <td>Log4j 2: Async Appender</td>
                <td align="right">2,423</td>
                <td align="right">2,117,722</td>
                <td align="right">4,096</td>
                <td align="right">67,108,864</td>
                <td align="right">16,384</td>
                <td align="right">268,435,456</td>
              </tr>
              <tr>
                <td>Log4j1: Async Appender</td>
                <td align="right">1,562</td>
                <td align="right">1,781,404</td>
                <td align="right">4,096</td>
                <td align="right">109,051,904</td>
                <td align="right">16,384</td>
                <td align="right">268,435,456</td>
              </tr>
              <tr>
                <td>Logback: Async Appender</td>
                <td align="right">2,123</td>
                <td align="right">2,079,020</td>
                <td align="right">3,276</td>
                <td align="right">67,108,864</td>
                <td align="right">14,745</td>
                <td align="right">268,435,456</td>
              </tr>
            </table>
            <p>
              The latency comparison graph below is also log-scale, and shows the average latency of asynchronous loggers and
              ArrayBlockingQueue-based asynchronous appenders in scenarios with more and more threads running in parallel.
              Up to 8 threads asynchronous appenders have comparable average latency, two or three times that of asynchronous loggers.
              With more threads, the average latency of asynchronous appenders is orders of magnitude larger than
              asynchronous loggers.
            </p>
            <p>
              <img src="../images/async-average-latency.png" alt="Average async logger latency" />
            </p>
            <p>
              Applications interested in low latency often care not only about average latency, but also about worst-case latency.
              The graph below shows that asynchronous loggers also do better when comparing the maximum latency of 99.99% of
              observations with other logging methods.
              When increasing the number of threads the vast majority of latency measurements for asynchronous
              loggers stay in the 10-20 microseconds range where Asynchronous Appenders start experiencing many
              latency spikes in the 100 millisecond range, a difference of four orders of magnitude.
            </p>
            <p>
              <img src="../images/async-max-latency-99.99pct.png" alt="Maximum async logger latency" />
            </p>
    
            <a name="RandomAccessFileAppenderPerformance" />
            <h4>FileAppender vs. RandomAccessFileAppender</h4>
            <p>
              The appender comparison below was done with <em>synchronous loggers</em>.
            </p>
            <p>On Windows 7 (64bit) with JDK1.7.0_11, 2-core Intel i5-3317u CPU
              @1.70Ghz with hyperthreading switched on (4 virtual cores):
            </p>
            <table>
              <caption align="top">Throughput per thread in messages/second</caption>
              <tr>
                <th>Appender</th>
                <th>1 thread</th>
                <th>2 threads</th>
                <th>4 threads</th>
                <th>8 threads</th>
              </tr>
              <tr>
                <td>RandomAccessFileAppender</td>
                <td align="right">250,438</td>
                <td align="right">169,939</td>
                <td align="right">109,074</td>
                <td align="right">58,845</td>
              </tr>
              <tr>
                <td>FileAppender</td>
                <td align="right">186,695</td>
                <td align="right">118,587</td>
                <td align="right">57,012</td>
                <td align="right">28,846</td>
              </tr>
              <tr>
                <td>RollingRandomAccessFileAppender</td>
                <td align="right">278,369</td>
                <td align="right">213,176</td>
                <td align="right">125,300</td>
                <td align="right">63,103</td>
              </tr>
              <tr>
                <td>RollingFileAppender</td>
                <td align="right">182,518</td>
                <td align="right">114,690</td>
                <td align="right">55,147</td>
                <td align="right">28,153</td>
              </tr>
            </table>
            <p>On Solaris 10 (64bit) with JDK1.7.0_06, 4-core dual Xeon X5570 CPU
              @2.93GHz with hyperthreading switched off (8 virtual cores):
            </p>
            <table>
              <caption align="top">Throughput per thread in messages/second</caption>
              <tr>
                <th>Appender</th>
                <th>1 thread</th>
                <th>2 threads</th>
                <th>4 threads</th>
                <th>8 threads</th>
              </tr>
              <tr>
                <td>RandomAccessFileAppender</td>
                <td align="right">240,760</td>
                <td align="right">128,713</td>
                <td align="right">66,555</td>
                <td align="right">30,544</td>
              </tr>
              <tr>
                <td>FileAppender</td>
                <td align="right">172,517</td>
                <td align="right">106,587</td>
                <td align="right">55,885</td>
                <td align="right">25,675</td>
              </tr>
              <tr>
                <td>RollingRandomAccessFileAppender</td>
                <td align="right">228,491</td>
                <td align="right">135,355</td>
                <td align="right">69,277</td>
                <td align="right">32,484</td>
              </tr>
              <tr>
                <td>RollingFileAppender</td>
                <td align="right">186,422</td>
                <td align="right">97,737</td>
                <td align="right">55,766</td>
                <td align="right">25,097</td>
              </tr>
            </table>
          </subsection>
          <!-- <a name="PerformanceTuning" /> <subsection name="Async Logger 
            Performance Tuning"> <p>While the default settings should give good results 
            out of the box, you may want to change settings to improve your logging throughput 
            and/or latency. We suggest the following steps for tuning your logging performance:</p> 
            <ol> <li>Create a base line by running the performance tests in your environment.</li> 
            <li>Change a parameter (e.g. WaitStrategy or RingBufferSize) and run the 
            tests again. Check performance results.</li> <li>Repeat (2) until you find 
            a parameter combination that gives acceptable performance.</li> </ol> <p>Use 
            the following command to run the performance tests:</p> <blockquote> <tt>java 
            -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 
            \<br /> [-DWaitStrategy=Sleep] [-DRingBufferSize=262144] org.apache.logging.log4j.async.perftest.PerfTestDriver 
            [path-to-java] [repeats]</tt> <br /><br /> [<b>WaitStrategy</b>] is an optional 
            system property with valid values "Block", "Sleep", or "Yield". Details are 
            documented under "System Properties to configure ... loggers". <br /> [<b>RingBufferSize</b>] 
            is an optional system property with an integer value of at least 128. Details 
            are documented under "System Properties to configure ... loggers". <br /> 
            [<b>path-to-java</b>] is an optional parameter that is the full path to the 
            "java" executable. Specify this if just running "java" in the current directory 
            does not specify the version of java that you want to test with. <br /> [<b>repeats</b>] 
            is an optional parameter that specifies how often each test is repeated. 
            The default is 5. </blockquote> <p>For reference, below are some of the numbers 
            we used to determine the default settings. (Solaris 10 (64bit), 2.93GHz Xeon 
            X5570 with JDK1.7.0_06):</p> <table> <caption align="top">Throughput in log 
            messages/second per thread</caption> <tr> <th>Logger</th> <th>WaitStrategy</th> 
            <th>1 thread</th> <th>2 threads</th> <th>4 threads</th> <th>8 threads</th> 
            </tr> <tr> <td rowspan="3" valign="top">All Async System Clock</td> <td align="center">Block</td> 
            <td align="right">1,717,261</td> <td align="right">727,075</td> <td align="right">263,760</td> 
            <td align="right">150,533</td> </tr> <tr> <td align="center">Sleep</td> <td 
            align="right">1,568,623</td> <td align="right">948,653</td> <td align="right">629,951</td> 
            <td align="right">651,340</td> </tr> <tr> <td align="center">Yield</td> <td 
            align="right">1,618,103</td> <td align="right">884,314</td> <td align="right">628,008</td> 
            <td align="right">675,879</td> </tr> <tr> <td rowspan="3" valign="top">All 
            Async Cached Clock</td> <td align="center">Block</td> <td align="right">2,771,734</td> 
            <td align="right">642,899</td> <td align="right">331,003</td> <td align="right">172,877</td> 
            </tr> <tr> <td align="center">Sleep</td> <td align="right">2,393,901</td> 
            <td align="right">1,211,425</td> <td align="right">770,416</td> <td align="right">632,361</td> 
            </tr> <tr> <td align="center">Yield</td> <td align="right">2,331,763</td> 
            <td align="right">1,132,529</td> <td align="right">684,109</td> <td align="right">671,957</td> 
            </tr> <tr> <td rowspan="3" valign="top">Mixed Async</td> <td align="center">Block</td> 
            <td align="right">1,347,853</td> <td align="right">443,652</td> <td align="right">251,433</td> 
            <td align="right">136,152</td> </tr> <tr> <td align="center">Sleep</td> <td 
            align="right">1,371,511</td> <td align="right">567,829</td> <td align="right">407,676</td> 
            <td align="right">408,071</td> </tr> <tr> <td align="center">Yield</td> <td 
            align="right">1,360,267</td> <td align="right">675,570</td> <td align="right">389,609</td> 
            <td align="right">391,969</td> </tr> </table> </subsection> -->
          <a name="UnderTheHood" />
          <subsection name="Under The Hood">
            <p>
              Asynchronous Loggers are implemented using the
              <a href="http://lmax-exchange.github.com/disruptor/">LMAX Disruptor</a>
              inter-thread messaging library. From the LMAX web site:
            </p>
            <blockquote>
              <p>... using queues to pass data between stages of the system was introducing latency, so we
                focused on optimising this area. The Disruptor is the result of our research and testing.
                We found that cache misses at the CPU-level, and locks requiring kernel arbitration are both
                extremely costly, so we created a framework which has "mechanical sympathy" for
                the hardware it's running on, and that's lock-free.
              </p>
            </blockquote>
    
            <p>
              LMAX Disruptor internal performance comparisons with <tt>java.util.concurrent.ArrayBlockingQueue</tt>
              can be found
              <a href="https://github.com/LMAX-Exchange/disruptor/wiki/Performance-Results">here</a>.
            </p>
          </subsection>
        </section>
      </body>
    </document>����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/configuration.xml.vm����������������������������������0000664�0000000�0000000�00000244352�12577562624�0025132�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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, or YAML.</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>.
            </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 then in weighted
                order from highest to lowest. As delivered, Log4j contains three ConfigurationFactory implementations:
                one for JSON, one for YAML, 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 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 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>
              <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>
            </subsection>
            <a name="Additivity"/>
            <subsection name="Additivity">
              <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 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>status</td>
                    <td>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.</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>
              <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>
        <Appender type="List" name="List">
        </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="List"/>
        </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" }
          },
          "List": { "name": "List",
            "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"},
                { "AppenderRef": "List", "key": "Service"}
              ]
            }
          }
        },
        "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" }},
             { "type": "List", "name": "List", "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"},
                  { "AppenderRef": "List", "key": "Service"}
                ]
              }
            }
          ]
        },
        "loggers": {
          "logger": [
            { "name": "EventLogger", "level": "info", "additivity": "false",
              "AppenderRef": { "ref": "Routing" }},
            { "name": "com.foo.bar", "level": "error", "additivity": "false",
              "AppenderRef": { "ref": "Console" }}
          ],
          "root": { "level": "error", "AppenderRef": { "ref": "STDOUT" }}
        }
      }
    }
    ]]></pre>
              <p>
                The JSON support uses the Jackson Data Processor to parse the JSON files. These dependencies must be added
                to a project that wants to use JSON for configuration:
              </p>
              <pre class="prettyprint linenums"><![CDATA[
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>${jackson2Version}</version>
    </dependency>
    
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>${jackson2Version}</version>
    </dependency>
    
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>${jackson2Version}</version>
    </dependency>
    ]]></pre>
            <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 false 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>
        <List name="List">
        </List>
      </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="List"/>
        </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>
                  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.identifier</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. Each individual component MUST have a "type" attribute
                  specified that identifies the component's Plugin type.
                </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,
                  status, and verbose attrbutes. See <a href="#ConfigurationSyntax">Configuration Syntax</a> for the
                  definitions of these attributes.
                </p>
              <pre class="prettyprint linenums">
    status = error
    name = PropertiesConfig
    
    property.filename = target/rolling/rollingtest.log
    
    filters = threshold
    
    filter.threshold.type = ThresholdFilter
    filter.threshold.level = debug
    
    appenders = console, rolling, list
    
    appender.console.type = Console
    appender.console.name = STDOUT
    appender.console.layout.type = PatternLayout
    appender.console.layout.pattern = %m%n
    
    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.list.type = List
    appender.list.name = List
    appender.list.filters = threshold
    appender.list.filter.threshold.type = ThresholdFilter
    appender.list.filter.threshold.level = error
    
    loggers = rolling
    
    logger.rolling.name = org.apache.logging.log4j.core.appender.rolling
    logger.rolling.level = debug
    logger.rolling.additivity = false
    logger.rolling.appenderRefs = rolling
    logger.rolling.appenderRef.rolling.ref = RollingFile
    
    rootLogger.level = info
    rootLogger.appenderRefs = stdout
    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"/>
        </Console>
        <List name="List">
          <ThresholdFilter level="debug"/>
        </List>
        <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"/>
            <Route ref="List" key="Service"/>
          </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. 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</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</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>
              <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 variable 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="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="StatusMessages"/>
            <subsection name="Status Messages">
              <table>
                <tr>
                <td>
                <b>Troubleshooting tip for the impatient:</b>
                <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"/>
        </Console>
        <List name="List">
          <ThresholdFilter level="debug"/>
        </List>
        <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"/>
            <Route ref="List" key="Service"/>
          </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,806 DEBUG Calling createAppender on class org.apache.logging.log4j.test.
           appender.ListAppender for element List with params(name="List", entryPerNewLine="null",
           raw="null", null, ThresholdFilter(DEBUG))
    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,824 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.
           routing.Route for element Route with params(AppenderRef="List", key="Service", 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'),
           Route(type=static Reference=List key='Service')})
    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'),
           Route(type=static Reference=List key='Service')}), 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, List, 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,806 DEBUG Calling createAppender on class org.apache.logging.log4j.test.appender.ListAppender for element List with params(name="List", entryPerNewLine="null", raw="null", null, ThresholdFilter(DEBUG))
    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,824 DEBUG Calling createRoute on class org.apache.logging.log4j.core.appender.routing.Route for element Route with params(AppenderRef="List", key="Service", 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'), Route(type=static Reference=List key='Service')})
    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'),Route(type=static Reference=List key='Service')}), 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, List, 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>InitialLoggerContext</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 InitialLoggerContext init = new InitialLoggerContext("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>
              Below follows a number of system properties that can be used to control Log4j 2 behaviour.
              Any spaces present in the property name are for visual flow and should be removed.
            </p>
    <table>
      <caption align="top">Log4j 2 System Properties</caption>
      <tr>
        <th>System Property</th>
        <th>Default Value</th>
        <th>Description</th>
      </tr>
      <tr>
        <td>log4j.configurationFile</td>
        <td>&nbsp;</td>
        <td>
          Path to an XML or JSON Log4j 2 configuration file.
        </td>
      </tr>
      <tr>
        <td>Log4jContextSelector</td>
        <td>ClassLoaderContextSelector</td>
        <td>
          Creates the <tt>LoggerContext</tt>s. An application can have one or more active LoggerContexts depending
          on the circumstances.
          See <a href="logsep.html">Log Separation</a> for more details.
          Available context selector implementation classes:<br />
        <!-- deliberately inserted spaces to allow line break -->
          <tt>org.apache.logging.log4j.core.async .AsyncLoggerContextSelector</tt> - makes <a href="async.html">all loggers asynchronous</a>.<br />
          <tt>org.apache.logging.log4j.core.selector .BasicContextSelector</tt> - creates a single shared LoggerContext.<br />
          <tt>org.apache.logging.log4j.core.selector .ClassLoaderContextSelector</tt> - separate LoggerContexts for each web application.<br />
          <tt>org.apache.logging.log4j.core.selector .JndiContextSelector</tt> - use JNDI to locate each web application's LoggerContext.<br/>
          <tt>org.apache.logging.log4j.core.osgi .BundleContextSelector</tt> - separate LoggerContexts for each OSGi bundle.
        </td>
      </tr>
      <tr>
        <td>Log4jLogEventFactory</td>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.core.impl .DefaultLogEventFactory</td>
        <td>
          Factory class used by LoggerConfig to create <tt>LogEvent</tt> instances.
          (Ignored when the <tt>AsyncLoggerContextSelector</tt> is used.)
        </td>
      </tr>
      <tr>
        <td>log4j2.loggerContextFactory</td>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simple .SimpleLoggerContextFactory</td>
        <td>
          Factory class used by LogManager to bootstrap the logging implementation.
          The core jar provides <tt>org.apache.logging.log4j.core.impl.Log4jContextFactory</tt>.
        </td>
      </tr>
      <tr>
        <td>log4j.configurationFactory</td>
        <td>&nbsp;</td>
        <td>
          Fully specified class name of a class extending <tt>org.apache.logging.log4j.core.config.ConfigurationFactory</tt>.
          If specified, an instance of this class is added to the list of configuration factories.
        </td>
      </tr>
      <tr>
        <td>log4j.shutdownHookEnabled</td>
        <td>true</td>
        <td>
          Overrides the global flag for whether or not a shutdown hook should be used to stop a <tt>LoggerContext</tt>.
          By default, this is enabled and can be disabled on a per-configuration basis. When running with the
          <tt>log4j-web</tt> module, this is automatically disabled.
        </td>
      </tr>
      <tr>
        <td>log4j.shutdownCallbackRegistry</td>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.core.util .DefaultShutdownCallbackRegistry</td>
        <td>
          Fully specified class name of a class implementing
          <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/util/ShutdownCallbackRegistry.html">ShutdownCallbackRegistry</a>.
          If specified, an instance of this class is used instead of <tt>DefaultShutdownCallbackRegistry</tt>.
          The specified class must have a default constructor.
        </td>
      </tr>
      <tr>
        <td>log4j.Clock</td>
        <td>SystemClock</td>
        <td>
          Implementation of the <tt>org.apache.logging.log4j.core.util.Clock</tt>
          interface that is used for timestamping the log events.
          <br />
          By default, <tt>System.currentTimeMillis</tt> is called on every log event.
          <br />
          You can also specify a fully qualified class name of a custom class that implements the
          <tt>Clock</tt> interface.
        </td>
      </tr>
      <tr>
        <td>org.apache.logging.log4j.level</td>
        <td>ERROR</td>
        <td>
          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).
        </td>
      </tr>
    
      <tr>
        <td>disableThreadContext</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, the ThreadContext stack and map are disabled.
          (May be ignored if a custom ThreadContext map is specified.)
        </td>
      </tr>
      <tr>
        <td>disableThreadContextStack</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, the ThreadContext stack is disabled.
        </td>
      </tr>
      <tr>
        <td>disableThreadContextMap</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, the ThreadContext map is disabled.
          (May be ignored if a custom ThreadContext map is specified.)
        </td>
      </tr>
      <tr>
        <td>log4j2.threadContextMap</td>
        <td>&nbsp;</td>
        <td>
          Fully specified class name of a custom <tt>ThreadContextMap</tt> implementation class.
        </td>
      </tr>
      <tr>
        <td>isThreadContextMapInheritable</td>
        <td>false</td>
        <td>
          If <tt>true</tt> use a <tt>InheritableThreadLocal</tt> to implement the ThreadContext map.
          Otherwise, use a plain <tt>ThreadLocal</tt>.
          (May be ignored if a custom ThreadContext map is specified.)
        </td>
      </tr>
      <tr>
        <td>log4j2.disable.jmx</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, Log4j configuration objects like LoggerContexts, Appenders, Loggers, etc.
          will not be instrumented with MBeans and cannot be remotely monitored and managed.
        </td>
      </tr>
      <tr>
        <td>log4j2.jmx.notify.async</td>
        <td>false for web apps, true otherwise</td>
        <td>
          If <tt>true</tt>, log4j's JMX notifications are sent from a separate background thread,
          otherwise they are sent from the caller thread.
          If the <tt>javax.servlet.Servlet</tt> class is on the classpath, the default behaviour
          is to use the caller thread to send JMX notifications.
        </td>
      </tr>
      <tr>
        <td>log4j.skipJansi</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, the ConsoleAppender will not try to use the Jansi output stream on Windows.
        </td>
      </tr>
      <tr>
        <td>log4j.ignoreTCL</td>
        <td>false</td>
        <td>
          If <tt>true</tt>, 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.
        </td>
      </tr>
      <tr>
        <td>org.apache.logging.log4j.uuidSequence</td>
        <td>0</td>
        <td>
          System property that may be used to seed the UUID generation with an integer value.
        </td>
      </tr>
      <!--
      <tr>
        <td>org.apache.logging.log4j.assignedSequences</td>
        <td>true</td>
        <td>
          TODO: used to seed UUID generation. Not sure when or why one would use this...
        </td>
      </tr>
      -->
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .showContextMap</td>
        <td>false</td>
        <td>If <tt>true</tt>, the full ThreadContext map is included in each SimpleLogger log message.</td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .showlogname</td>
        <td>false</td>
        <td>If <tt>true</tt>, the logger name is included in each SimpleLogger log message.</td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .showShortLogname</td>
        <td>true</td>
        <td>If <tt>true</tt>, 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.
        </td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .showdatetime</td>
        <td>false</td>
        <td>If <tt>true</tt>, SimpleLogger log messages contain timestamp information.
        </td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .dateTimeFormat</td>
        <td>"yyyy/MM/dd HH:mm:ss:SSS zzz"</td>
        <td>Date-time format to use.
        Ignored if <tt>org.apache.logging.log4j.simplelog.showdatetime</tt> is <tt>false</tt>.
        </td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.logj.simplelog .logFile</td>
        <td>system.err</td>
        <td>"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.
        </td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .level</td>
        <td>ERROR</td>
        <td>Default level for new SimpleLogger instances.
        </td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog.&lt;loggerName&gt;level</td>
        <td>SimpleLogger default log level</td>
        <td>Log level for a the SimpleLogger instance with the specified name.</td>
      </tr>
      <tr>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.simplelog .StatusLogger.level</td>
        <td>ERROR</td>
        <td>This property is used to control the initial StatusLogger level, and can be overridden in code by calling
        <code>StatusLogger.getLogger().setLevel(someLevel)</code>.
        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).</td>
      </tr>
      <tr>
        <td>Log4jDefaultStatusLevel</td>
        <td>ERROR</td>
        <td>
          <p>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.
          </p><p>
          Note: this property is used by the log4j-core implementation only after a configuration file has been found.</p>
        </td>
      </tr>
      <tr>
        <td>log4j2.StatusLogger.level</td>
        <td>WARN</td>
        <td>
          <p>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.
          </p><p>
          By default, StatusLogger listeners are added when a configuration is found and by the JMX
          StatusLoggerAdmin MBean. For example, if a configuration contains
          <code>&lt;Configuration status="trace"&gt;</code>, a listener with statusLevel TRACE is registered
          and the StatusLogger listenerLevel is set to TRACE, resulting in verbose status messages displayed on the console.
          </p><p>
          If no listeners are registered, the listenersLevel is not used, and the StatusLogger output level
          is determined by <code>StatusLogger.getLogger().getLevel()</code>
          (see property <code>org.apache.logging.log4j.simplelog .StatusLogger.level</code>).</p>
        </td>
      </tr>
      <tr>
        <td>log4j2.status.entries</td>
        <td>200</td>
        <td>
          Number of StatusLogger events that are kept in a buffer and can be retrieved with
          <tt>StatusLogger.getStatusData()</tt>.
        </td>
      </tr>
      <tr>
        <td>AsyncLogger.ExceptionHandler</td>
        <td>&nbsp;
        </td>
        <td>
          See <a href="async.html#SysPropsAllAsync">Async Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLogger.RingBufferSize</td>
        <td>256&#160;*&#160;1024</td>
        <td>
          See <a href="async.html#SysPropsAllAsync">Async Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLogger.WaitStrategy</td>
        <td>
          Sleep
        </td>
        <td>
          See <a href="async.html#SysPropsAllAsync">Async Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLogger.ThreadNameStrategy</td>
        <td>
          CACHED
        </td>
        <td>
          See <a href="async.html#SysPropsAllAsync">Async Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLoggerConfig.ExceptionHandler</td>
        <td>&nbsp;    </td>
        <td>
          See <a href="async.html#SysPropsMixedSync-Async">Mixed Async/Synchronous Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLoggerConfig.RingBufferSize</td>
        <td>256&#160;*&#160;1024</td>
        <td>
          See <a href="async.html#SysPropsMixedSync-Async">Mixed Async/Synchronous Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>AsyncLoggerConfig.WaitStrategy</td>
        <td>
          Sleep
        </td>
        <td>
          See <a href="async.html#SysPropsMixedSync-Async">Mixed Async/Synchronous Logger System Properties</a> for details.
        </td>
      </tr>
      <tr>
        <td>log4j.jul.LoggerAdapter</td>
        <!-- deliberately inserted spaces to allow line break -->
        <td>org.apache.logging.log4j.jul .ApiLoggerAdapter</td>
        <td>
          Default LoggerAdapter to use in the JUL adapter. By default, if log4j-core is available, then the class
          <code>org.apache.logging.log4j.jul .CoreLoggerAdapter</code> will be used. Otherwise, the
          <code>ApiLogggerAdapter</code> will be used. Custom implementations must provide a public default constructor.
        </td>
      </tr>
    </table>
    
            </subsection>
          </section>
        </body>
    </document>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/customconfig.xml��������������������������������������0000664�0000000�0000000�00000035653�12577562624�0024344�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Extending Log4j 2 Configuration</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
          <section name="Custom Configurations">
            <p>
              Log4j 2 provides a few ways for applications to create their own custom configurations:
            </p>
            <ul>
              <li>Specify a custom ConfigurationFactory</li>
              <li>Use the Configurator</li>
              <li>Modify the current Configuration after initialization</li>
            </ul>
            <a name="ConfigurationBuilder"/>
              <subsection name="The ConfigurationBuilder API">
                <p>
                  Starting with release 2.4, Log4j provides a ConfigurationBuilder and a set of component builders that
                  allow a Configuration to be created fairly easily.
                  Actual configuration objects like LoggerConfig or Appender can be unwieldy; they require a lot
                  of knowledge on Log4j internals which makes them difficult to work with if all you want is 
                  create a Configuration.
                </p>
                <p>
                  The new ConfigurationBuilder API (in the <code>org.apache.logging.log4j.core.config.builder.api</code> package)
                  allows users to create Configurations in code by constructing component <i>definitions</i>.
                  There is no need to work directly with actual configuration objects.
                  Component definitions are added to the ConfigurationBuilder, and once all the definitions have
                  been collected all the actual configuration objects (like Loggers and Appenders) are constructed.
                </p>
                <p>
                  ConfigurationBuilder has convenience methods for the base components that can be configured such as
                  Loggers, Appenders, Filter, Properties, etc. 
                  However, Log4j 2's plugin mechanism means that users can create any number of custom components.
                  As a trade-off, the ConfigurationBuilder API provides only a limited number of "strongly typed"
                  convenience methods like <code>newLogger()</code>, <code>newLayout()</code> etc.
                  The generic <code>builder.newComponent()</code> method can be used if no convenience method exists
                  for the component you want to configure.
                </p>
                <p>
                  For example, the builder does not know what components can be configured on specific components
                  such as the RollingFileAppender vs. the RoutingAppender. To specify a triggering policy on a 
                  RollingFileAppender you would use builder.newComponent().
                </p>
              </subsection>
              <a name="ConfigurationFactory"/>
              <subsection name="Understanding ConfigurationFactory">
                <p>
                  Log4j 2 will search for available ConfigurationFactories and then select the one to use. The
                  selected ConfigurationFactory creates the Configuration that Log4j will use. Here is how Log4j finds
                  the available ConfigurationFactories:
                </p>
                <ol>
                  <li>A system property named "log4j.configurationFactory" can be set with the name of the ConfigurationFactory to be used.</li>
                  <li><code>ConfigurationFactory.setConfigurationFactory(ConfigurationFactory)</code> can be called with the instance of the
                  ConfigurationFactory to be used. This must be called before any other calls to Log4j.</li>
                  <li>A ConfigurationFactory implementation can be added to the classpath and configured as a plugin
                    in the "ConfigurationFactory" category.
                    The Order annotation can be used to specify the relative priority when multiple applicable 
                    ConfigurationFactories are found.</li>
                </ol>
                <p>
                  ConfigurationFactories have the concept of "supported types", which basically maps to the
                  file extension of the configuration file that the ConfigurationFactory can handle. 
                  If a configuration file location is specified, ConfigurationFactories whose supported type
                  does not include "*" or the matching file extension will not be used.
                </p>
              </subsection>
              <a name="Example"/>
              <subsection name="Using ConfigurationBuilder with a Custom ConfigurationFactory">
                <p>
                  One way to programmatically configure Log4j 2 is to create a custom ConfigurationFactory
                  that uses the <a href="#ConfigurationBuilder">ConfigurationBuilder</a> to create a Configuration.
                  The below example overrides the <code>getConfiguration()</code> method to return a
                  Configuration created by the ConfigurationBuilder.
                  This will cause the Configuration to automatically be hooked into Log4j when the LoggerContext is created.
                  In the example below, because it specifies a supported type of "*" it will override any configuration files provided.
                </p>
                <pre class="prettyprint linenum"><![CDATA[
    @Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY)
    @Order(50)
    public class CustomConfigurationFactory extends ConfigurationFactory {
    
        static Configuration createConfiguration(final String name, ConfigurationBuilder<BuiltConfiguration> builder) {
            builder.setConfigurationName(name);
            builder.setStatusLevel(Level.ERROR);
            builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL).
                addAttribute("level", Level.DEBUG));
            AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").
                addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT);
            appenderBuilder.add(builder.newLayout("PatternLayout").
                addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
            appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY,
                Filter.Result.NEUTRAL).addAttribute("marker", "FLOW"));
            builder.add(appenderBuilder);
            builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
                add(builder.newAppenderRef("Stdout")).
                addAttribute("additivity", false));
            builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
            return builder.build();
        }
    
        @Override
        public Configuration getConfiguration(ConfigurationSource source) {
            return getConfiguration(source.toString(), null);
        }
    
        @Override
        public Configuration getConfiguration(final String name, final URI configLocation) {
            ConfigurationBuilder<BuiltConfiguration> builder = newConfigurationBuilder();
            return createConfiguration(name, builder);
        }
    
        @Override
        protected String[] getSupportedTypes() {
            return new String[] {"*"};
        }
    }]]></pre>
              </subsection>
            <a name="Configurator"/>
              <subsection name="Using ConfigurationBuilder with the Configurator">
                <p>
                  An alternative to a custom ConfigurationFactory is to configure with the <code>Configurator</code>.
                  Once a Configuration object has been constructed, it can be passed to one of the 
                  <code>Configurator.initialize</code> methods to set up the Log4j configuration.
                </p>
                <p>
                  Using the Configurator in this manner allows the application control over when Log4j is initialized.
                  However, should any logging be attempted before Configurator.initialize() is called then the
                  default configuration will be used for those log events.
                </p>
                <pre class="prettyprint linenum"><![CDATA[
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();
    builder.setStatusLevel(Level.ERROR);
    builder.setConfigurationName("BuilderTest");
    builder.add(builder.newFilter("ThresholdFilter", Filter.Result.ACCEPT, Filter.Result.NEUTRAL)
        .addAttribute("level", Level.DEBUG));
    AppenderComponentBuilder appenderBuilder = builder.newAppender("Stdout", "CONSOLE").addAttribute("target",
        ConsoleAppender.Target.SYSTEM_OUT);
    appenderBuilder.add(builder.newLayout("PatternLayout").
        addAttribute("pattern", "%d [%t] %-5level: %msg%n%throwable"));
    appenderBuilder.add(builder.newFilter("MarkerFilter", Filter.Result.DENY, Filter.Result.NEUTRAL).
        addAttribute("marker", "FLOW"));
    builder.add(appenderBuilder);
    builder.add(builder.newLogger("org.apache.logging.log4j", Level.DEBUG).
        add(builder.newAppenderRef("Stdout")).addAttribute("additivity", false));
    builder.add(builder.newRootLogger(Level.ERROR).add(builder.newAppenderRef("Stdout")));
    ctx = Configurator.initialize(builder.build());
    ]]></pre>
            </subsection>
    
              <a name="Hybrid"/>
              <subsection name="Combining Configuration File with Programmatic Configuration">
                <p>
                  Sometimes you want to configure with a configuration file but do some additional programmatic
                  configuration. A possible use case might be that you want to allow for a flexible configuration using XML 
                  but at the same time make sure there are a few configuration elements that are always present that can't be removed.
                </p>
                <p>
                  The easiest way to achieve this is to extend one of the standard Configuration classes
                  (XMLConfiguration, JSONConfiguration) and then create a new ConfigurationFactory for the extended class.
                  After the standard configuration completes the custom configuration can be added to it.
                </p>
                <p>
                  The example below shows how to extend XMLConfiguration to manually add an Appender and a LoggerConfig
                  to the configuration.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "MyXMLConfigurationFactory", category = "ConfigurationFactory")
    @Order(10)
    public class MyXMLConfigurationFactory extends ConfigurationFactory {
    
        /**
         * Valid file extensions for XML files.
         */
        public static final String[] SUFFIXES = new String[] {".xml", "*"};
    
        /**
         * Return the Configuration.
         * @param source The InputSource.
         * @return The Configuration.
         */
        public Configuration getConfiguration(InputSource source) {
            return new MyXMLConfiguration(source, configFile);
        }
    
        /**
         * Returns the file suffixes for XML files.
         * @return An array of File extensions.
         */
        public String[] getSupportedTypes() {
            return SUFFIXES;
        }
    }
    
    public class MyXMLConfiguration extends XMLConfiguration {
        public MyXMLConfiguration(final ConfigurationFactory.ConfigurationSource configSource) {
          super(configSource);
        }
    
        @Override
        protected void doConfigure() {
            super.doConfigure();
            final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            final Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null,
                  null,null, null);
            final Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true",
                  "false", "false", "4000", layout, null, "false", null, config);
            appender.start();
            addAppender(appender);
            LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j",
                  "true", refs, null, config, null );
            loggerConfig.addAppender(appender, null, null);
            addLogger("org.apache.logging.log4j", loggerConfig);
        }
    }</pre>
              </subsection>
            <a name="AddingToCurrent"/>
            <subsection name="Programmatically Adding to the Current Configuration">
                <p>
                  Applications sometimes have the need to customize logging separate from the actual configuration.
                  Log4j allows this although it suffers from a few limitations:
                </p>
                  <ol>
                    <li>If the configuration file is changed the configuration will be reloaded and the manual changes
                    will be lost.</li>
                    <li>Modification to the running configuration requires that all the methods being called (addAppender
                      and addLogger) be synchronized.</li>
                  </ol>
                <p>
                  As such, the recommended approach for customizing a configuration is to extend one of the standard
                  Configuration classes, override the setup method to first do super.setup() and then add the custom
                  Appenders, Filters and LoggerConfigs to the configuration before it is registered for use.
                </p>
                <p>
                  The following example adds an Appender and a new LoggerConfig using that Appender to the current
                  configuration.
                </p>
                <!-- TODO: update code example below with new plugin API -->
                <pre class="prettyprint linenums"><![CDATA[
            final LoggerContext ctx = (LoggerContext) LogManager.getContext(false);
            final Configuration config = ctx.getConfiguration();
            Layout layout = PatternLayout.createLayout(PatternLayout.SIMPLE_CONVERSION_PATTERN, config, null,
                null,null, null);
            Appender appender = FileAppender.createAppender("target/test.log", "false", "false", "File", "true",
                "false", "false", "4000", layout, null, "false", null, config);
            appender.start();
            config.addAppender(appender);
            AppenderRef ref = AppenderRef.createAppenderRef("File", null, null);
            AppenderRef[] refs = new AppenderRef[] {ref};
            LoggerConfig loggerConfig = LoggerConfig.createLogger("false", "info", "org.apache.logging.log4j",
                "true", refs, null, config, null );
            loggerConfig.addAppender(appender, null, null);
            config.addLogger("org.apache.logging.log4j", loggerConfig);
            ctx.updateLoggers();
    }]]></pre>
              </subsection>
    
          </section>
    
        </body>
    </document>
    �������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/customloglevels.xml.vm��������������������������������0000664�0000000�0000000�00000035704�12577562624�0025511�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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.Generate${dollar}ExtendedLogger \
            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>
              </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.Generate${dollar}CustomLogger \
            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>
              </subsection>
          </section>
    
        </body>
    </document>
    ������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/eventlogging.xml��������������������������������������0000664�0000000�0000000�00000015064�12577562624�0024326�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 API</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
            <section name="Log4j 2 API">
              <a name="EventLogging"/>
              <subsection name="Event Logging">
                <p>
                  The EventLogger class provides a simple mechanism for logging events that occur in an application.
                  While the EventLogger is useful as a way of initiating events that should be processed by an audit
                  Logging system, by itself it does not implement any of the features an audit logging system would require
                  such as guaranteed delivery.
                </p>
                <p>The recommended way of using the EventLogger in a typical web application is to populate
                  the ThreadContext Map with data that is related to the entire lifespan of the request such as the user's
                  id, the user's IP address, the product name, etc. This can easily be done in a servlet filter where
                  the ThreadContext Map can also be cleared at the end of the request. When an event that needs to be
                  recorded occurs a StructuredDataMessage should be created and populated.
                  Then call EventLogger.logEvent(msg) where msg is a reference to the StructuredDataMessage.</p>
    
                <pre class="prettyprint linenums">
    import org.apache.logging.log4j.ThreadContext;
    import org.apache.commons.lang.time.DateUtils;
    
    import javax.servlet.Filter;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.FilterChain;
    import javax.servlet.http.HttpSession;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.Cookie;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.util.TimeZone;
    
    public class RequestFilter implements Filter {
        private FilterConfig filterConfig;
        private static String TZ_NAME = "timezoneOffset";
    
        public void init(FilterConfig filterConfig) throws ServletException {
            this.filterConfig = filterConfig;
        }
    
        /**
         * Sample filter that populates the MDC on every request.
         */
        public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
                throws IOException, ServletException {
            HttpServletRequest request = (HttpServletRequest)servletRequest;
            HttpServletResponse response = (HttpServletResponse)servletResponse;
            ThreadContext.put("ipAddress", request.getRemoteAddr());
            HttpSession session = request.getSession(false);
            TimeZone timeZone = null;
            if (session != null) {
                // Something should set this after authentication completes
                String loginId = (String)session.getAttribute("LoginId");
                if (loginId != null) {
                    ThreadContext.put("loginId", loginId);
                }
                // This assumes there is some javascript on the user's page to create the cookie.
                if (session.getAttribute(TZ_NAME) == null) {
                    if (request.getCookies() != null) {
                        for (Cookie cookie : request.getCookies()) {
                            if (TZ_NAME.equals(cookie.getName())) {
                                int tzOffsetMinutes = Integer.parseInt(cookie.getValue());
                                timeZone = TimeZone.getTimeZone("GMT");
                                timeZone.setRawOffset((int)(tzOffsetMinutes * DateUtils.MILLIS_PER_MINUTE));
                                request.getSession().setAttribute(TZ_NAME, tzOffsetMinutes);
                                cookie.setMaxAge(0);
                                response.addCookie(cookie);
                            }
                        }
                    }
                }
            }
            ThreadContext.put("hostname", servletRequest.getServerName());
            ThreadContext.put("productName", filterConfig.getInitParameter("ProductName"));
            Threadcontext.put("locale", servletRequest.getLocale().getDisplayName());
            if (timeZone == null) {
                timeZone = TimeZone.getDefault();
            }
            ThreadContext.put("timezone", timeZone.getDisplayName());
            filterChain.doFilter(servletRequest, servletResponse);
            ThreadContext.clear();
        }
    
        public void destroy() {
        }
    }</pre>
                <p>Sample class that uses EventLogger.</p>
                <pre class="prettyprint linenums">
    import org.apache.logging.log4j.StructuredDataMessage;
    import org.apache.logging.log4j.EventLogger;
    
    import java.util.Date;
    import java.util.UUID;
    
    public class MyApp {
    
        public String doFundsTransfer(Account toAccount, Account fromAccount, long amount) {
            toAccount.deposit(amount);
            fromAccount.withdraw(amount);
            String confirm = UUID.randomUUID().toString();
            StructuredDataMessage msg = new StructuredDataMessage(confirm, null, "transfer");
            msg.put("toAccount", toAccount);
            msg.put("fromAccount", fromAccount);
            msg.put("amount", amount);
            EventLogger.logEvent(msg);
            return confirm;
        }
    }</pre>
                <p>The EventLogger class uses a Logger named "EventLogger". EventLogger uses a logging level
                  of OFF as the default to indicate that it cannot be filtered. These events can be
                  formatted for printing using the
                  <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/layout/StructuredDataLayout.html">StructuredDataLayout</a>.
                </p>
              </subsection>
            </section>
        </body>
    </document>
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/extending.xml�����������������������������������������0000664�0000000�0000000�00000052623�12577562624�0023625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Extending Log4j 2</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    <!-- TODO: add in documentation regarding plugin builders, factories, and typed attributes -->
        <body>
          <section name="Extending Log4j">
            <p>
              Log4j 2 provides numerous ways that it can be manipulated and extended. This section includes an
              overview of the various ways that are directly supported by the Log4j 2 implementation.
            </p>
              <subsection name="LoggerContextFactory">
                <p>
                  The <code>LoggerContextFactory</code> binds the Log4j API to its implementation. The Log4j
                  <code>LogManager</code> locates a <code>LoggerContextFactory</code> by locating all instances of
                  <code>META-INF/log4j-provider.properties</code>, a standard <code>java.util.Properties</code> file,
                  and then inspecting each to verify that it specifies a value for the <var>Log4jAPIVersion</var> property
                  that conforms to the version required by the <code>LogManager</code>. If more than one valid
                  implementation is located the value for <var>FactoryPriority</var> will be used to identify the factory
                  with the highest priority. Finally, the value of the <var>LoggerContextFactory</var> property will be
                  used to locate the <code>LoggerContextFactory</code>. In Log4j 2 this is provided by
                  <code>Log4jContextFactory</code>.
                </p>
                <p>
                  Applications may change the LoggerContextFactory that will be used by
                </p>
                <ol>
                  <li>Implementing a new <code>LoggerContextFactory</code> and creating a <code>log4j-provider.properties</code>
                    to reference it making sure that it has the highest priority.
                  </li>
                  <li>Create a new <code>log4j-provider.xml</code> and configure it with the desired
                    <code>LoggerContextFactory</code> making sure that it has the highest priority.
                  </li>
                  <li>Setting the system property <var>log4j2.loggerContextFactory</var> to the name of the
                    <code>LoggerContextFactory</code> class to use.
                  </li>
                  <li>Setting the property "log4j2.loggerContextFactory" in a properties file named
                    "log4j2.LogManager.properties" to the name of the LoggerContextFactory class to use. The properties
                    file must be on the classpath.
                  </li>
                </ol>
              </subsection>
              <subsection name="ContextSelector">
                <p>
                  ContextSelectors are called by the
                  <a href="../log4j-core/apidocs/org/apache/logging/log4j/core/impl/Log4jContextFactory.html">Log4j
                  LoggerContext factory</a>. They perform the actual work of
                  locating or creating a LoggerContext, which is the anchor for Loggers and their configuration.
                  ContextSelectors are free to implement any mechanism they desire to manage LoggerContexts. The
                  default Log4jContextFactory checks for the presence of a System Property named "Log4jContextSelector".
                  If found, the property is expected to contain the name of the Class that implements the
                  ContextSelector to be used.
                </p>
                <p>
                  Log4j provides five ContextSelectors:
                </p>
                <dl>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/BasicContextSelector.html">BasicContextSelector</a></dt>
                  <dd>Uses either a LoggerContext that has been stored in a ThreadLocal or a common LoggerContext.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/ClassLoaderContextSelector.html">ClassLoaderContextSelector</a></dt>
                  <dd>Associates LoggerContexts with the ClassLoader that created the caller of the getLogger call. This is
                  the default ContextSelector.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/JndiContextSelector.html">JndiContextSelector</a></dt>
                  <dd>Locates the LoggerContext by querying JNDI.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/async/AsyncLoggerContextSelector.html">AsyncLoggerContextSelector</a></dt>
                  <dd>Creates a LoggerContext that ensures that all loggers are AsyncLoggers.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/osgi/BundleContextSelector.html">BundleContextSelector</a></dt>
                  <dd>Associates LoggerContexts with the ClassLoader of the bundle that created the caller of the getLogger
                  call. This is enabled by default in OSGi environments.</dd>
                </dl>
              </subsection>
              <subsection name="ConfigurationFactory">
                <p>
                  Modifying the way in which logging can be configured is usually one of the areas with the most
                  interest. The primary method for doing that is by implementing or extending a ConfigurationFactory.
                  Log4j provides two ways of adding new ConfigurationFactories. The first is by defining the system
                  property named "log4j.configurationFactory" to the name of the class that should be searched first
                  for a configuration. The second method is by defining the ConfigurationFactory as a Plugin.
                </p>
                <p>
                  All the ConfigurationFactories are then processed in order. Each factory is called on its
                  getSupportedTypes method to determine the file extensions it supports. If a configuration file
                  is located with one of the specified file extensions then control is passed to that
                  ConfigurationFactory to load the configuration and create the Configuration object.
                </p>
                <p>
                  Most Configuration extend the BaseConfiguration class. This class expects that the subclass will
                  process the configuration file and create a hierarchy of Node objects. Each Node is fairly simple
                  in that it consists of the name of the node, the name/value pairs associated with the node, The
                  PluginType of the node and a List of all of its child Nodes. BaseConfiguration will then be
                  passed the Node tree and instantiate the configuration objects from that.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "XMLConfigurationFactory", category = "ConfigurationFactory")
    @Order(5)
    public class XMLConfigurationFactory extends ConfigurationFactory {
    
        /**
         * Valid file extensions for XML files.
         */
        public static final String[] SUFFIXES = new String[] {".xml", "*"};
    
        /**
         * Return the Configuration.
         * @param source The InputSource.
         * @return The Configuration.
         */
        public Configuration getConfiguration(InputSource source) {
            return new XMLConfiguration(source, configFile);
        }
    
        /**
         * Returns the file suffixes for XML files.
         * @return An array of File extensions.
         */
        public String[] getSupportedTypes() {
            return SUFFIXES;
        }
    }</pre>
              </subsection>
              <subsection name="LoggerConfig">
                <p>
                  LoggerConfig objects are where Loggers created by applications tie into the configuration. The Log4j
                  implementation requires that all LoggerConfigs be based on the LoggerConfig class, so applications
                  wishing to make changes must do so by extending the LoggerConfig class. To declare the new
                  LoggerConfig, declare it as a Plugin of type "Core" and providing the name that applications
                  should specify as the element name in the configuration. The LoggerConfig should also define
                  a PluginFactory that will create an instance of the LoggerConfig.
                </p>
                <p>
                  The following example shows how the root LoggerConfig simply extends a generic LoggerConfig.
                </p>
                <pre class="prettyprint linenums"><![CDATA[
    @Plugin(name = "root", category = "Core", printObject = true)
    public static class RootLogger extends LoggerConfig {
    
        @PluginFactory
        public static LoggerConfig createLogger(@PluginAttribute(value = "additivity", defaultBooleanValue = true) boolean additivity,
                                                @PluginAttribute(value = "level", defaultStringValue = "ERROR") Level level,
                                                @PluginElement("AppenderRef") AppenderRef[] refs,
                                                @PluginElement("Filters") Filter filter) {
            List<AppenderRef> appenderRefs = Arrays.asList(refs);
            return new LoggerConfig(LogManager.ROOT_LOGGER_NAME, appenderRefs, filter, level, additivity);
        }
    }]]></pre>
              </subsection>
              <subsection name="LogEventFactory">
                <p>A LogEventFactory is used to generate LogEvents. Applications may replace the standard LogEventFactory
                  by setting the value of the system property Log4jLogEventFactory to the name of the custom
                  LogEventFactory class. </p>
              </subsection>
              <subsection name="Lookups">
                <p>
                  Lookups are the means in which parameter substitution is performed. During Configuration initialization
                  an "Interpolator" is created that locates all the Lookups and registers them for use when a variable
                  needs to be resolved. The interpolator matches the "prefix" portion of the variable name to a
                  registered Lookup and passes control to it to resolve the variable.
                </p>
                <p>
                  A Lookup must be declared using a Plugin annotation with a type of "Lookup". The name specified on
                  the Plugin annotation will be used to match the prefix.  Unlike other Plugins, Lookups do not
                  use a PluginFactory. Instead, they are required to provide a constructor that accepts no arguments.
                  The example below shows a Lookup that will return the value of a System Property.
                </p>
                <p>The provided Lookups are documented here: <a href="./lookups.html">Lookups</a></p>
                <pre class="prettyprint linenums">
    @Plugin(name = "sys", category = "Lookup")
    public class SystemPropertiesLookup implements StrLookup {
    
        /**
         * Lookup the value for the key.
         * @param key  the key to be looked up, may be null
         * @return The value for the key.
         */
        public String lookup(String key) {
            return System.getProperty(key);
        }
    
        /**
         * Lookup the value for the key using the data in the LogEvent.
         * @param event The current LogEvent.
         * @param key  the key to be looked up, may be null
         * @return The value associated with the key.
         */
        public String lookup(LogEvent event, String key) {
            return System.getProperty(key);
        }
    }</pre>
              </subsection>
              <subsection name="Filters">
                <p>
                  As might be expected, Filters are the used to reject or accept log events as they pass through the
                  logging system. A Filter is declared using a Plugin annotation of type "Core" and an elementType of
                  "filter". The name attribute on the Plugin annotation is used to specify the name of the element
                  users should use to enable the Filter. Specifying the printObject attribute with a value of "true"
                  indicates that a call to toString will format the arguments to the filter as the configuration
                  is being processed. The Filter must also specify a PluginFactory method that will be called to
                  create the Filter.
                </p>
                <p>
                  The example below shows a Filter used to reject LogEvents based upon their logging level. Notice the
                  typical pattern where all the filter methods resolve to a single filter method.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "ThresholdFilter", category = "Core", elementType = "filter", printObject = true)
    public final class ThresholdFilter extends AbstractFilter {
    
        private final Level level;
    
        private ThresholdFilter(Level level, Result onMatch, Result onMismatch) {
            super(onMatch, onMismatch);
            this.level = level;
        }
    
        public Result filter(Logger logger, Level level, Marker marker, String msg, Object[] params) {
            return filter(level);
        }
    
        public Result filter(Logger logger, Level level, Marker marker, Object msg, Throwable t) {
            return filter(level);
        }
    
        public Result filter(Logger logger, Level level, Marker marker, Message msg, Throwable t) {
            return filter(level);
        }
    
        @Override
        public Result filter(LogEvent event) {
            return filter(event.getLevel());
        }
    
        private Result filter(Level level) {
            return level.isAtLeastAsSpecificAs(this.level) ? onMatch : onMismatch;
        }
    
        @Override
        public String toString() {
            return level.toString();
        }
    
        /**
         * Create a ThresholdFilter.
         * @param loggerLevel The log Level.
         * @param match The action to take on a match.
         * @param mismatch The action to take on a mismatch.
         * @return The created ThresholdFilter.
         */
        @PluginFactory
        public static ThresholdFilter createFilter(@PluginAttribute(value = "level", defaultStringValue = "ERROR") Level level,
                                                   @PluginAttribute(value = "onMatch", defaultStringValue = "NEUTRAL") Result onMatch,
                                                   @PluginAttribute(value = "onMismatch", defaultStringValue = "DENY") Result onMismatch) {
            return new ThresholdFilter(level, onMatch, onMismatch);
        }
    }</pre>
              </subsection>
              <subsection name="Appenders">
                <p>
                  Appenders are passed an event, (usually) invoke a Layout to format the event, and then "publish"
                  the event in whatever manner is desired. Appenders are declared as Plugins with a type of "Core"
                  and an elementType of "appender". The name attribute on the Plugin annotation specifies the name
                  of the element users must provide in their configuration to use the Appender. Appenders should
                  specify printObject as "true" if the toString method renders the values of the attributes passed
                  to the Appender.
                </p>
                <p>
                  Appenders must also declare a PluginFactory method that will create the appender. The example
                  below shows an Appender named "Stub" that can be used as an initial template.
                </p>
                <p>
                  Most Appenders use Managers. A manager actually "owns" the resources, such as an OutputStream or
                  socket. When a reconfiguration occurs a new Appender will be created. However, if nothing significant
                  in the previous Manager has changed, the new Appender will simply reference it instead of creating a
                  new one. This insures that events are not lost while a reconfiguration is taking place without
                  requiring that logging pause while the reconfiguration takes place.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "Stub", category = "Core", elementType = "appender", printObject = true)
    public final class StubAppender extends OutputStreamAppender {
    
        private StubAppender(String name, Layout layout, Filter filter, StubManager manager,
                             boolean ignoreExceptions) {
        }
    
        @PluginFactory
        public static StubAppender createAppender(@PluginAttribute("name") String name,
                                                  @PluginAttribute("ignoreExceptions") boolean ignoreExceptions,
                                                  @PluginElement("Layout") Layout layout,
                                                  @PluginElement("Filters") Filter filter) {
    
            if (name == null) {
                LOGGER.error("No name provided for StubAppender");
                return null;
            }
    
            StubManager manager = StubManager.getStubManager(name);
            if (manager == null) {
                return null;
            }
            if (layout == null) {
                layout = PatternLayout.createDefaultLayout();
            }
            return new StubAppender(name, layout, filter, manager, ignoreExceptions);
        }
    }</pre>
              </subsection>
              <subsection name="Layouts">
                <p>
                  Layouts perform the formatting of events into the printable text that is written by Appenders to
                  some destination. All Layouts must implement the Layout interface. Layouts that format the
                  event into a String should extend AbstractStringLayout, which will take care of converting the
                  String into the required byte array.
                </p>
                <p>
                  Every Layout must declare itself as a plugin using the Plugin annotation. The type must be "Core",
                  and the elementType must be "Layout". printObject should be set to true if the plugin's toString
                  method will provide a representation of the object and its parameters. The name of the plugin must
                  match the value users should use to specify it as an element in their Appender configuration.
                  The plugin also must provide a static method annotated as a PluginFactory and with each of the
                  methods parameters annotated with PluginAttr or PluginElement as appropriate.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "SampleLayout", category = "Core", elementType = "layout", printObject = true)
    public class SampleLayout extends AbstractStringLayout {
    
        protected SampleLayout(boolean locationInfo, boolean properties, boolean complete,
                               Charset charset) {
        }
    
        @PluginFactory
        public static SampleLayout createLayout(@PluginAttribute("locationInfo") boolean locationInfo,
                                                @PluginAttribute("properties") boolean properties,
                                                @PluginAttribute("complete") boolean complete,
                                                @PluginAttribute(value = "charset", defaultStringValue = "UTF-8") Charset charset) {
            return new SampleLayout(locationInfo, properties, complete, charset);
        }
    }</pre>
              </subsection>
              <subsection name="PatternConverters">
                <p>
                  PatternConverters are used by the PatternLayout to format the log event into a printable String. Each
                  Converter is responsible for a single kind of manipulation, however Converters are free to format
                  the event in complex ways. For example, there are several converters that manipulate Throwables and
                  format them in various ways.
                </p>
                <p>
                  A PatternConverter must first declare itself as a Plugin using the standard Plugin annotation but
                  must specify value of "Converter" on the type attribute. Furthermore, the Converter must also
                  specify the ConverterKeys attribute to define the tokens that can be specified in the pattern
                  (preceded by a '%' character) to identify the Converter.
                </p>
                <p>
                  Unlike most other Plugins, Converters do not use a PluginFactory. Instead, each Converter is
                  required to provide a static newInstance method that accepts an array of Strings as the only
                  parameter. The String array are the values that are specified within the curly braces that can
                  follow the converter key.
                </p>
                <p>
                  The following shows the skeleton of a Converter plugin.
                </p>
                <pre class="prettyprint linenums">
    @Plugin(name = "query", category = "Converter")
    @ConverterKeys({"q", "query"})
    public final class QueryConverter extends LogEventPatternConverter {
    
        public QueryConverter(String[] options) {
        }
    
        public static QueryConverter newInstance(final String[] options) {
          return new QueryConverter(options);
        }
    }</pre>
              </subsection>
              <subsection name="Custom Plugins">
                <p>See the <a href="plugins.html">Plugins</a> section of the manual.</p>
    <!-- TODO: some documentation here! -->
              </subsection>
          </section>
    
        </body>
    </document>
    �������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/filters.xml�������������������������������������������0000664�0000000�0000000�00000072073�12577562624�0023311�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>
        <Marker 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.
              </p>
              <table>
                <caption align="top">Dynamic Threshold Filter Parameters</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>defaultThreshold</td>
                  <td>String</td>
                  <td>Level of messages to be filtered. If there is no matching key in the key/value pairs
                    then this level will be compared against the event's level.
                  </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="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">
              <p>
                The ThreadContextMapFilter allows filtering against data elements that are in the ThreadContext Map.
              </p>
              <table>
                <caption align="top">ThreadContext 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 ThreadContextMapFilter might look like:
              </p>
              <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" name="MyApp" packages="">
      <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
        <KeyValuePair key="User1" value="DEBUG"/>
        <KeyValuePair key="User2" value="WARN"/>
      </ThreadContextMapFilter>
      <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 ThreadContextMapFilter 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"/>
          <ThreadContextMapFilter onMatch="ACCEPT" onMismatch="NEUTRAL" operator="or">
            <KeyValuePair key="foo" value="bar"/>
            <KeyValuePair key="User2" value="WARN"/>
          </ThreadContextMapFilter>
        </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>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/flowtracing.xml���������������������������������������0000664�0000000�0000000�00000034466�12577562624�0024164�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 API</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
            <section name="Log4j 2 API">
              <a name="FlowTracing"/>
              <subsection name="Flow Tracing">
                <p>
                  The Logger class provides logging methods that are quite useful for following the
                  execution path of applications. These methods generate logging events that can be filtered
                  separately from other debug logging. Liberal use of these methods is encouraged as the output has
                  been found to
                </p>
                <ul>
                  <li>aid in problem diagnosis in development without requiring a debug session</li>
                  <li>aid in problem diagnosis in production where no debugging is possible</li>
                  <li>help educate new developers in learning the application.</li>
                </ul>
                <p>
                  The two most used methods are the entry() and exit() methods. entry() should be placed at the
                  beginning of methods, except perhaps for simple getters and setters. entry() can be called
                  passing from 0 to 4 parameters. Typically these will be parameters passed to the method.
                  The entry() method logs with a level of TRACE and uses a Marker with a name of "ENTER" which
                  is also a "FLOW" Marker.
                </p>
                <p>
                  The exit() method should be placed before any return statement or as the last statement of
                  methods without a return. exit() can be called with or without a parameter. Typically, methods
                  that return void will use exit() while methods that return an Object will use exit(Object obj).
                  The entry() method logs with a level of TRACE and uses a Marker with a name of "EXIT" which is
                  also a "FLOW" Marker.
                </p>
                <p>
                  The throwing() method can be used by an application when it is throwing an exception that is
                  unlikely to be handled, such as a RuntimeException. This will insure that proper diagnostics
                  are available if needed. The logging event generated will have a level of ERROR and will have
                  an associated Marker with a name of "THROWING" which is also an "EXCEPTION" Marker.
                </p>
                <p>
                  The catching() method can be used by an application when it catches an Exception that it is not
                  going to rethrow, either explicitly or attached to another Exception. The logging event generated
                  will have a level of ERROR and will have an associated Marker with a name of "CATCHING" which is
                  also an "EXCEPTION" Marker.
                </p>
                <p>
                  The following example shows a simple application using these methods in a fairly typcial manner. The
                  throwing() is not present since no Exceptions are explicitly thrown and not handled.
                </p>
    <pre class="prettyprint linenums">
    package com.test;
    
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.LogManager;
    
    import java.util.Random;
    
    public class TestService {
        private Logger logger = LogManager.getLogger(TestService.class.getName());
    
        private String[] messages = new String[] {
            "Hello, World",
            "Goodbye Cruel World",
            "You had me at hello"
        };
        private Random rand = new Random(1);
    
        public String retrieveMessage() {
            logger.entry();
    
            String testMsg = getMessage(getKey());
    
            return logger.exit(testMsg);
        }
    
        public void exampleException() {
            logger.entry();
            try {
                String msg = messages[messages.length];
                logger.error("An exception should have been thrown");
            } catch (Exception ex) {
                logger.catching(ex);
            }
            logger.exit();
        }
    
        public String getMessage(int key) {
            logger.entry(key);
    
            String value = messages[key];
    
            return logger.exit(value);
        }
    
        private int getKey() {
            logger.entry();
            int key = rand.nextInt(messages.length);
            return logger.exit(key);
        }
    }</pre>
                <p>
                  This test application uses the preceding service to generate logging events.
                </p>
    <pre class="prettyprint linenums">
    package com.test;
    
    public class App {
    
        public static void main( String[] args ) {
            TestService service = new TestService();
            service.retrieveMessage();
            service.retrieveMessage();
            service.exampleException();
        }
    }</pre>
                <p>
                  The configuration below will cause all output to be routed to target/test.log. The pattern for
                  the FileAppender includes the class name, line number and method name. Including these
                  in the pattern are critical for the log to be of value.
                </p>
    <pre class="prettyprint linenums"><![CDATA[
    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="error">
      <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
          <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY"/>
          <!-- Flow tracing is most useful with a pattern that shows location.
               Below pattern outputs class, line number and method name. -->
          <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </Console>
        <File name="log" fileName="target/test.log" append="false">
          <PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/>
        </File>
      </Appenders>
      <Loggers>
        <Root level="trace">
          <AppenderRef ref="log"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
                <p>
                  Here is the output that results from the Java classes and configuration above.
                </p>
                <pre>
    19:08:07.056 TRACE com.test.TestService 19 retrieveMessage -  entry
    19:08:07.060 TRACE com.test.TestService 46 getKey -  entry
    19:08:07.060 TRACE com.test.TestService 48 getKey -  exit with (0)
    19:08:07.060 TRACE com.test.TestService 38 getMessage -  entry parms(0)
    19:08:07.060 TRACE com.test.TestService 42 getMessage -  exit with (Hello, World)
    19:08:07.060 TRACE com.test.TestService 23 retrieveMessage -  exit with (Hello, World)
    19:08:07.061 TRACE com.test.TestService 19 retrieveMessage -  entry
    19:08:07.061 TRACE com.test.TestService 46 getKey -  entry
    19:08:07.061 TRACE com.test.TestService 48 getKey -  exit with (1)
    19:08:07.061 TRACE com.test.TestService 38 getMessage -  entry parms(1)
    19:08:07.061 TRACE com.test.TestService 42 getMessage -  exit with (Goodbye Cruel World)
    19:08:07.061 TRACE com.test.TestService 23 retrieveMessage -  exit with (Goodbye Cruel World)
    19:08:07.062 TRACE com.test.TestService 27 exampleException -  entry
    19:08:07.077 DEBUG com.test.TestService 32 exampleException - catching java.lang.ArrayIndexOutOfBoundsException: 3
            at com.test.TestService.exampleException(TestService.java:29) [classes/:?]
            at com.test.App.main(App.java:9) [classes/:?]
            at com.test.AppTest.testApp(AppTest.java:15) [test-classes/:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.6.0_29]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[?:1.6.0_29]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[?:1.6.0_29]
            at java.lang.reflect.Method.invoke(Method.java:597) ~[?:1.6.0_29]
            at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52) [junit-4.3.1.jar:?]
            at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35) [surefire-junit4-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115) [surefire-junit4-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97) [surefire-junit4-2.7.2.jar:2.7.2]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.6.0_29]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[?:1.6.0_29]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[?:1.6.0_29]
            at java.lang.reflect.Method.invoke(Method.java:597) ~[?:1.6.0_29]
            at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) [surefire-booter-2.7.2.jar:2.7.2]
            at $Proxy0.invoke(Unknown Source) [?:?]
            at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150) [surefire-booter-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91) [surefire-booter-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) [surefire-booter-2.7.2.jar:2.7.2]
    19:08:07.087 TRACE com.test.TestService 34 exampleException -  exit</pre>
                <p>
                  Simply changing the root logger level to DEBUG in the example above will reduce the output
                  considerably.
                </p>
                <pre>
    19:13:24.963 DEBUG com.test.TestService 32 exampleException - catching java.lang.ArrayIndexOutOfBoundsException: 3
            at com.test.TestService.exampleException(TestService.java:29) [classes/:?]
            at com.test.App.main(App.java:9) [classes/:?]
            at com.test.AppTest.testApp(AppTest.java:15) [test-classes/:?]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.6.0_29]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[?:1.6.0_29]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[?:1.6.0_29]
            at java.lang.reflect.Method.invoke(Method.java:597) ~[?:1.6.0_29]
            at org.junit.internal.runners.TestMethodRunner.executeMethodBody(TestMethodRunner.java:99) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.runUnprotected(TestMethodRunner.java:81) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.runMethod(TestMethodRunner.java:75) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestMethodRunner.run(TestMethodRunner.java:45) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassMethodsRunner.invokeTestMethod(TestClassMethodsRunner.java:66) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassMethodsRunner.run(TestClassMethodsRunner.java:35) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassRunner$1.runUnprotected(TestClassRunner.java:42) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.BeforeAndAfterRunner.runProtected(BeforeAndAfterRunner.java:34) [junit-4.3.1.jar:?]
            at org.junit.internal.runners.TestClassRunner.run(TestClassRunner.java:52) [junit-4.3.1.jar:?]
            at org.apache.maven.surefire.junit4.JUnit4TestSet.execute(JUnit4TestSet.java:35) [surefire-junit4-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:115) [surefire-junit4-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:97) [surefire-junit4-2.7.2.jar:2.7.2]
            at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[?:1.6.0_29]
            at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) ~[?:1.6.0_29]
            at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) ~[?:1.6.0_29]
            at java.lang.reflect.Method.invoke(Method.java:597) ~[?:1.6.0_29]
            at org.apache.maven.surefire.booter.ProviderFactory$ClassLoaderProxy.invoke(ProviderFactory.java:103) [surefire-booter-2.7.2.jar:2.7.2]
            at $Proxy0.invoke(Unknown Source) [?:?]
            at org.apache.maven.surefire.booter.SurefireStarter.invokeProvider(SurefireStarter.java:150) [surefire-booter-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.booter.SurefireStarter.runSuitesInProcess(SurefireStarter.java:91) [surefire-booter-2.7.2.jar:2.7.2]
            at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:69) [surefire-booter-2.7.2.jar:2.7.2]</pre>
              </subsection>
            </section>
        </body>
    </document>
    ����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/index.xml���������������������������������������������0000664�0000000�0000000�00000022457�12577562624�0022751�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Overview</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
          <section name="Welcome to Log4j 2!">
            <subsection name="Introduction">
              <p>Almost every large application includes its own logging or tracing
              API. In conformance with this rule, the E.U.  <a
              href="http://www.semper.org">SEMPER</a> project decided to write its
              own tracing API. This was in early 1996. After countless enhancements,
              several incarnations and much work that API has evolved to become
              log4j, a popular logging package for Java. The package is distributed
              under the <a href="../LICENSE">Apache Software License</a>, a
              fully-fledged open source license certified by the <a
              href="http://www.opensource.org">open source</a> initiative. The
              latest log4j version, including full-source code, class files and
              documentation can be found at <a
              href="http://logging.apache.org/log4j/2.x/index.html"><b>http://logging.apache.org/log4j/2.x/index.html</b></a>.
              </p>
    
              <p>Inserting log statements into code is a low-tech method for
              debugging it. It may also be the only way because debuggers are not
              always available or applicable. This is usually the case for
              multithreaded applications and distributed applications at large.</p>
    
              <p>Experience indicates that logging was an important component of the
              development cycle. It offers several advantages. It provides precise
              <em>context</em> about a run of the application. Once inserted into
              the code, the generation of logging output requires no human
              intervention.  Moreover, log output can be saved in persistent medium
              to be studied at a later time. In addition to its use in the
              development cycle, a sufficiently rich logging package can also be
              viewed as an auditing tool.</p>
    
              <p>As Brian W. Kernighan and Rob Pike put it in their truly excellent
              book <i>"The Practice of Programming":</i></p>
    
              <div class="well">
                As personal choice, we tend not to use debuggers beyond getting a
                stack trace or the value of a variable or two. One reason is that it
                is easy to get lost in details of complicated data structures and
                control flow; we find stepping through a program less productive
                than thinking harder and adding output statements and self-checking
                code at critical places. Clicking over statements takes longer than
                scanning the output of judiciously-placed displays. It takes less
                time to decide where to put print statements than to single-step to
                the critical section of code, even assuming we know where that
                is. More important, debugging statements stay with the program;
                debugging sessions are transient.
              </div>
    
              <p>Logging does have its drawbacks. It can slow down an
              application. If too verbose, it can cause scrolling blindness. To
              alleviate these concerns, log4j is designed to be reliable, fast and
              extensible. Since logging is rarely the main focus of an application,
              the log4j API strives to be simple to understand and to use.</p>
            </subsection>
            <subsection name="Log4j 2">
              <p>
              Log4j 1.x has been widely adopted and used in many applications. However,
              through the years development on it has slowed down. It has become more
              difficult to maintain due to its need to be compliant with very old versions
              of Java.  Its alternative, SLF4J/Logback made many needed improvements to the
              framework. So why bother with Log4j 2? Here are a few of the reasons.
              </p>
              <ol>
                <li>Log4j 2 is designed to be usable as an audit logging framework. Both Log4j
                  1.x and Logback will lose events while reconfiguring. Log4j 2 will not. in
                  Logback exceptions in Appenders are never visible to the application. In
                  Log4j 2 Appenders can be configured to allow the exception to percolate
                  to the application</li>
                <li>Log4j 2 contains next-generation lock-free <a href="async.html">Asynchronous Loggers</a> based
                  on the <a href="https://lmax-exchange.github.io/disruptor/">LMAX Disruptor library</a>.
                  In multi-threaded scenarios Asynchronous Loggers have 10 times higher throughput and
                  orders of magnitude lower latency than Log4j 1.x and Logback.</li>
                <li>Log4j 2 uses a <a href="plugins.html">Plugin system</a> that makes it extremely easy to
                  <a href="extending.html">extend the framework</a> by adding new <a href="appenders.html">Appenders</a>,
                  <a href="filters.html">Filters</a>, <a href="layouts.html">Layouts</a>, <a href="lookups.html">Lookups</a>,
                  and Pattern Converters without requiring any changes to Log4j.</li>
                <li>Due to the Plugin system configuration is simpler. Entries in the configuration
                  do not require a class name to be specified.</li>
                <li>Support for <a href="customloglevels.html">custom log levels</a>.
                  Custom log levels can be defined in code or in configuration.</li>
                <li>Support for <a href="api.html#LambdaSupport">lambda expressions</a>.
                  Client code running on Java 8 can use lambda expressions to lazily construct a log message only if
                  the requested log level is enabled. Explicit level checks are not needed, resulting in cleaner code.</li>
                <li>Support for <a href="messages.html">Message objects</a>. Messages allow support for interesting and
                  complex constructs to be passed through the logging system and be efficiently
                  manipulated. Users are free to create their own
                  <code><a href="../log4j-api/apidocs/org/apache/logging/log4j/message/Message.html">Message</a></code>
                  types and write custom <a href="layouts.html">Layouts</a>, <a href="filters.html">Filters</a> and
                  <a href="lookups.html">Lookups</a> to manipulate them.</li>
                <li>Log4j 1.x supports Filters on Appenders. Logback added TurboFilters to allow
                  filtering of events before they are processed by a Logger. Log4j 2 supports
                  Filters that can be configured to process events before they are handled by
                  a Logger, as they are processed by a Logger or on an Appender.</li>
                <li>Many Logback Appenders do not accept a Layout and will only send data in a
                  fixed format. Most Log4j 2 Appenders accept a Layout, allowing the data to
                  be transported in any format desired.</li>
                <li>Layouts in Log4j 1.x and Logback return a String. This resulted in the problems
                  discussed at <a href="http://logback.qos.ch/manual/encoders.html">Logback Encoders</a>.
                  Log4j 2 takes the simpler approach that Layouts always return a byte array. This has
                  the advantage that it means they can be used in virtually any Appender, not just
                  the ones that write to an OutputStream.</li>
                <!-- and coming up: ByteBuffers, too! -->
                <li>The <a href="appenders.html#SyslogAppender">Syslog Appender</a> supports both TCP and UDP as well as
                  support for the BSD syslog
                  and the <a href="http://tools.ietf.org/html/rfc5424">RFC 5424</a> formats.</li>
                <li>Log4j 2 takes advantage of Java 5 concurrency support and performs locking
                  at the lowest level possible. Log4j 1.x has known deadlock issues. Many of these
                  are fixed in Logback but many Logback classes still require synchronization at
                  a fairly high level.</li>
                <li>It is an Apache Software Foundation project following the community and support
                  model used by all ASF projects. If you want to contribute or gain the right to
                  commit changes just follow the path outlined at
                  <a href="http://jakarta.apache.org/site/contributing.html">Contributing</a></li>
              </ol>
            </subsection>
          </section>
        </body>
    </document>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/jmx.xml.vm��������������������������������������������0000664�0000000�0000000�00000025767�12577562624�0023070�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 <code>log4j2.disable.jmx=true</code> 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>
    ���������logging-log4j2-log4j-2.4/src/site/xdoc/manual/layouts.xml.vm����������������������������������������0000664�0000000�0000000�00000234633�12577562624�0023764�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>
        <properties>
            <title>Log4j 2 Layouts</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="ggregory@apache.org">Gary Gregory</author>
        </properties>
      #set($dollar = '$')
      #set($sharp = '#')
      #set($javadocRoot = 'http://docs.oracle.com/javase/6/docs/api')
      #macro(javadoc $path $class)
          <a class="javadoc" href="${javadocRoot}/${path}/${class}.html">${class}</a>
      #end
      #set($Charset = "<a class='javadoc' href='${javadocRoot}/java/nio/charset/Charset.html'>Charset</a>")
      #if (!$alignedFileName)
        #set ($isPDF = true)
        #set ($break = '<br />')
      #else
        #set ($isPDF = false)
        #set ($break = '')
      #end
        <body>
          <section name="Layouts">
            <p>An Appender uses a Layout to format a LogEvent into a form that meets the needs of whatever will be
              consuming the log event. In Log4j 1.x and Logback Layouts were expected to transform an event into a
              String. In Log4j 2 Layouts return a byte array. This allows the result of the Layout to be useful in
              many more types of Appenders. However, this means you need to configure most Layouts with a ${Charset} to
              ensure the byte array contains correct values.
            </p>
            <p>
              The root class for layouts that use a Charset is <code>org.apache.logging.log4j.core.layout.AbstractStringLayout</code> 
              where the default there is UTF-8. Each layout that extends <code>org.apache.logging.log4j.core.layout.AbstractStringLayout</code> 
              can provide its own default. See each layout below.
            </p>
            <a name="CSVLayouts"/>
            <subsection name="CSV Layouts">
              <p>
                The CSV layout can be used in two ways: First, using <code>CsvParameterLayout</code> to log event parameters 
                to create a custom database, usually to a logger and file appender uniquely configured for this purpose. 
                Second, using <code>CsvLogEventLayout</code> to log events to create a database, as an alternative to using a 
                full DBMS or using a JDBC driver that supports the CSV format.
              </p>
              <p>
                The <code>CsvParameterLayout</code> converts an event's parameters into a CSV record, ignoring the message. 
                To log CSV records, you can use the usual Logger methods <code>info()</code>, <code>debug()</code>, and so on:
              </p>
              <pre class="prettyprint linenums">
    logger.info("Ignored", value1, value2, value3);
    </pre>
              <p>
                Which will create the CSV record:
              </p>            
              <pre class="prettyprint linenums">
    value1, value2, value3
    </pre>            
              <p>
                Alternatively, you can use a <code>ObjectArrayMessage</code>, which only carries parameters:
              </p>
              <pre class="prettyprint linenums">
    logger.info(new ObjectArrayMessage(value1, value2, value3));
    </pre>
              <p>
                The layouts CsvParameterLayout and CsvLogEventLayout are configured with the following parameters:
              </p>
              <table>
                <caption>CsvParameterLayout and CsvLogEventLayout</caption>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>format</td>
                  <td>String</td>
                  <td>
                    One of the predefined formats: <code>Default</code>, <code>Excel</code>, <code>MySQL</code>, 
                    <code>RFC4180</code>, <code>TDF</code>.
                    See 
                      <a href="https://commons.apache.org/proper/commons-csv/archives/1.2/apidocs/org/apache/commons/csv/CSVFormat.Predefined.html">CSVFormat.Predefined</a>.
                  </td>
                </tr>
                <tr>
                  <td>delimiter</td>
                  <td>Character</td>
                  <td>Sets the delimiter of the format to the specified character.</td>
                </tr>
                <tr>
                  <td>escape</td>
                  <td>Character</td>
                  <td>Sets the escape character of the format to the specified character.</td>
                </tr>
                <tr>
                  <td>quote</td>
                  <td>Character</td>
                  <td>Sets the quoteChar of the format to the specified character.</td>
                </tr>
                <tr>
                  <td>quoteMode</td>
                  <td>String</td>
                  <td>
                    Sets the output quote policy of the format to the specified value. One of: <code>ALL</code>, 
                    <code>MINIMAL</code>, <code>NON_NUMERIC</code>, <code>NONE</code>.
                  </td>
                </tr>
                <tr>
                  <td>nullString</td>
                  <td>String</td>
                  <td>Writes null as the given nullString when writing records.</td>
                </tr>
                <tr>
                  <td>recordSeparator</td>
                  <td>String</td>
                  <td>Sets the record separator of the format to the specified String.</td>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>Charset</td>
                  <td>The output Charset.</td>
                </tr>
                <tr>
                  <td>header</td>
                  <td>Sets the header to include when the stream is opened.</td>
                  <td>Desc.</td>
                </tr>
                <tr>
                  <td>footer</td>
                  <td>Sets the footer to include when the stream is closed.</td>
                  <td>Desc.</td>
                </tr>
            </table>           
            <p>
              Logging as a CSV events looks like this:
            </p>
            <pre class="prettyprint linenums">
    logger.debug("one={}, two={}, three={}", 1, 2, 3); 
    </pre>                    
            <p>
              Produces a CSV record with the following fields:
              <ol>
                <li>Time Nanos</li>
                <li>Time Millis</li>
                <li>Level</li>
                <li>Thread Name</li>
                <li>Formatted Message</li>
                <li>Logger FQCN</li>
                <li>Logger Name</li>
                <li>Marker</li>
                <li>Thrown Proxy</li>
                <li>Source</li>
                <li>Context Map</li>
                <li>Context Stack</li>
              </ol>
            </p>            
            <pre class="prettyprint linenums">
    0,1441617184044,DEBUG,main,"one=1, two=2, three=3",org.apache.logging.log4j.spi.AbstractLogger,,,,org.apache.logging.log4j.core.layout.CsvLogEventLayoutTest.testLayout(CsvLogEventLayoutTest.java:98),{},[]
    </pre>                    
            </subsection>
            <a name="JSONLayout"/>
            <subsection name="JSONLayout">
              <!-- From Javadoc of org.apache.logging.log4j.core.layout.JSONLayout -->
              <p>
              Appends a series of JSON events as strings serialized as bytes. This layout requires Jackson jar files
              (see pom.xml for details).
              </p>
              <h4>Complete well-formed JSON vs. fragment JSON</h4>
              <p>
              If you configure <code>complete="true"</code>, the appender outputs a well-formed JSON document. By default,
              with <code>complete="false"</code>, you should include the output as an <em>external file</em> in a
              separate file to form a well-formed JSON document.
              </p>
              <p>
              A well-formed JSON document follows this pattern:
              </p>
              <pre class="prettyprint linenums">[
      {
        "logger":"com.foo.Bar",
        "timestamp":"1376681196470",
        "level":"INFO",
        "thread":"main",
        "message":"Message flushed with immediate flush=true"
      },
      {
        "logger":"com.foo.Bar",
        "timestamp":"1376681196471",
        "level":"ERROR",
        "thread":"main",
        "message":"Message flushed with immediate flush=true",
        "throwable":"java.lang.IllegalArgumentException: badarg\\n\\tat org.apache.logging.log4j.core.appender.JSONCompleteFileAppenderTest.testFlushAtEndOfBatch(JSONCompleteFileAppenderTest.java:54)\\n\\tat sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)\\n\\tat sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)\\n\\tat sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)\\n\\tat java.lang.reflect.Method.invoke(Method.java:606)\\n\\tat org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)\\n\\tat org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)\\n\\tat org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:44)\\n\\tat org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)\\n\\tat org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:271)\\n\\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:70)\\n\\tat org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)\\n\\tat org.junit.runners.ParentRunner$3.run(ParentRunner.java:238)\\n\\tat org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:63)\\n\\tat org.junit.runners.ParentRunner.runChildren(ParentRunner.java:236)\\n\\tat org.junit.runners.ParentRunner.access$000(ParentRunner.java:53)\\n\\tat org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:229)\\n\\tat org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)\\n\\tat org.junit.runners.ParentRunner.run(ParentRunner.java:309)\\n\\tat org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)\\n\\tat org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)\\n\\tat org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)\\n\\tat org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)\\n\\tat org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)\\n\\tat org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)\\n"
      }
    ]
    </pre>
              <p>
              If <code>complete="false"</code>, the appender does not write the JSON open array character "[" at the start
              of the document. and "]" and the end.
              </p>
              <p>
              This approach enforces the independence of the JSONLayout and the appender where you embed it.
              </p>
              <h4>Encoding</h4>
              <p>
              Appenders using this layout should have their <code>charset</code> set to <code>UTF-8</code> or
              <code>UTF-16</code>, otherwise events containing non-ASCII characters could result in corrupted log files.
              If not specified, this layout uses UTF-8.
              </p>
              <h4>Pretty vs. compact JSON</h4>
              <p>
              By default, the JSON layout is not compact (a.k.a. not "pretty") with <code>compact="false"</code>, which
              means the appender uses end-of-line characters and indents lines to format the text. If
              <code>compact="true"</code>,  then no end-of-line or indentation is used. Message content may contain,
              of course, escaped end-of-lines.
              </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the HTML String to a byte array. The value must be
                    a valid ${Charset}. If not specified, UTF-8 will be used.</td>
                </tr>
                <tr>
                  <td>compact</td>
                  <td>boolean</td>
                  <td>If true, the appender does not use end-of-lines and indentation. Defaults to false.</td>
                </tr>
                <tr>
                  <td>eventEol</td>
                  <td>boolean</td>
                  <td>
                    If true, the appender appends an end-of-line after each record. Defaults to false.
                    Use with eventEol=true and compact=true to get one record per line.
                  </td>
                </tr>
                <tr>
                  <td>complete</td>
                  <td>boolean</td>
                  <td>If true, the appender includes the JSON header and footer. Defaults to false.</td>
                </tr>
                <tr>
                  <td>properties</td>
                  <td>boolean</td>
                  <td>If true, the appender includes the thread context in the generated JSON. Defaults to false.</td>
                </tr>
                <tr>
                  <td>locationInfo</td>
                  <td>boolean</td>
                  <td>
                  <p>If true, the appender includes the location information in the generated JSON. Defaults to false.</p>
                  <p>Generating <a href="#LocationInformation">location information</a>
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <caption align="top">JSON Layout Parameters</caption>
              </table>
            </subsection>
            <a name="HTMLLayout"/>
            <subsection name="HTMLLayout">
              <p>The HTMLLayout generates an HTML page and adds each LogEvent to a row in a table.
              </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the HTML String to a byte array. The value must be
                    a valid ${Charset}. If not specified, this layout uses UTF-8.</td>
                </tr>
                <tr>
                  <td>contentType</td>
                  <td>String</td>
                  <td>The value to assign to the Content-Type header. The default is "text/html".</td>
                </tr>
                <tr>
                  <td>locationInfo</td>
                  <td>boolean</td>
                  <td>
                  <a name="HtmlLocationInfo" />
                  <p>If true, the filename and line number will be included in the HTML output. The default value is
                    false.</p>
                    <p>Generating <a href="#LocationInformation">location information</a>
                    is an expensive operation and may impact performance. Use with caution.</p>
                    </td>
                </tr>
                <tr>
                  <td>title</td>
                  <td>String</td>
                  <td>A String that will appear as the HTML title.</td>
                </tr>
                <caption align="top">HTML Layout Parameters</caption>
              </table>
            </subsection>
            <a name="PatternLayout"/>
            <subsection name="PatternLayout">
              <p>A flexible layout configurable with pattern string. The goal of this class is to format a LogEvent and
                return the results. The format of the result depends on the <em>conversion pattern</em>.
              </p>
              <p>The conversion pattern is closely related to the conversion pattern of the printf function in C.
                A conversion pattern is composed of literal text and format control expressions called
                <em>conversion specifiers</em>.
              </p>
              <p><i>Note that any literal text, including <b>Special Characters</b>, may be included in the conversion
                pattern.</i> Special Characters include <b>\t</b>, <b>\n</b>, <b>\r</b>, <b>\f</b>. Use <b>\\</b> to
                insert a single backslash into the output.
              </p>
              <p>Each conversion specifier starts with a percent sign (%) and is followed by optional <em>format
                modifiers</em> and a <em>conversion character</em>. The conversion character specifies the type of
                data, e.g. category, priority, date, thread name. The format modifiers control such things as field width,
                padding, left and right justification. The following is a simple example.
              </p>
              <p>Let the conversion pattern be <b>"%-5p [%t]: %m%n"</b> and assume that the Log4j environment was set to
                use a PatternLayout. Then the statements
     <pre>Logger logger = LogManager.getLogger("MyLogger");
    logger.debug("Message 1");
    logger.warn("Message 2");</pre>
                would yield the output
     <pre>DEBUG [main]: Message 1
    WARN  [main]: Message 2</pre>
              </p>
              <p>Note that there is no explicit separator between text and conversion specifiers. The pattern parser
                knows when it has reached the end of a conversion specifier when it reads a conversion character.
                In the example above the conversion specifier <b>%-5p</b> means the priority of the logging event should
                be left justified to a width of five characters.
              </p>
              <p>
                If the pattern string does not contain a specifier to handle a Throwable being logged, parsing of the
                pattern will act as if the "%xEx" specifier had be added to the end of the string. To suppress
                formatting of the Throwable completely simply add "%ex{0}" as a specifier in the pattern string.
              </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the syslog String to a byte array. The String must be
                    a valid ${Charset}. If not specified, this layout uses UTF-8.
                  </td>
                </tr>
                <tr>
                  <td>pattern</td>
                  <td>String</td>
                  <td>A composite pattern string of one or more conversion patterns from the table below.</td>
                </tr>
                <tr>
                  <td>replace</td>
                  <td>RegexReplacement</td>
                  <td>Allows portions of the resulting String to be replaced. If configured, the replace element must
                    specify the regular expression to match and the substitution. This performs a function similar to
                    the RegexReplacement converter but applies to the whole message while the converter only
                    applies to the String its pattern generates.
                  </td>
                </tr>
                <tr>
                  <td>alwaysWriteExceptions</td>
                  <td>boolean</td>
                  <td>If <code>true</code> (it is by default) exceptions are always written even if the pattern contains no
                    exception conversions. This means that if you do not include a way to output exceptions in your pattern,
                    the default exception formatter will be added to the end of the pattern. Setting this to
                    <code>false</code> disables this behavior and allows you to exclude exceptions from your pattern
                    output.</td>
                </tr>
                <tr>
                  <td>header</td>
                  <td>String</td>
                  <td>The optional header string to include at the top of each log file.</td>
                </tr>
                <tr>
                  <td>footer</td>
                  <td>String</td>
                  <td>The optional footer string to include at the bottom of each log file.</td>
                </tr>
                <tr>
                  <td>noConsoleNoAnsi</td>
                  <td>boolean</td>
                  <td>If <code>true</code> (default is false) and <code>System.console()</code> is null, do not output ANSI escape codes.</td>
                </tr>
                <caption align="top">PatternLayout Parameters</caption>
              </table>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>regex</td>
                  <td>String</td>
                  <td>A Java-compliant regular expression to match in the resulting string. See
                      #javadoc('java/util/regex', 'Pattern').</td>
                </tr>
                <tr>
                  <td>replacement</td>
                  <td>String</td>
                  <td>The string to replace any matched sub-strings with.</td>
                </tr>
                <caption align="top">RegexReplacement Parameters</caption>
              </table>
              <h4>Patterns</h4>
              <p>The conversions that are provided with Log4j are:
              </p>
              <table>
                <tr>
                  <th>Conversion Pattern</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td align="center">
                    <b>c</b>{precision}<br />
                    <b>logger</b>{precision}
                  </td>
                  <td>
                    <p>Outputs the name of the logger that published the logging event. The logger conversion
                      specifier can be optionally followed by<em>precision specifier</em>, which consists of a
                      decimal integer, or a pattern starting with a decimal integer.
                    </p>
                    <p>If a precision specifier is given and it is an integer value, then only the corresponding number
                      of right most components of the logger name will be printed. If the precision contains
                      other non-integer characters then the name will be abbreviated based on the pattern. If the
                      precision integer is less than one the right-most token will still be printed in full.
                      By default the logger name is printed in full.
                    </p>
                    <table>
                      <tr>
                        <th>Conversion Pattern</th>
                        <th>Logger Name</th>
                        <th>Result</th>
                      </tr>
                      <tr>
                        <td>%c{1}</td>
                        <td>org.apache.${break}commons.Foo</td>
                        <td>Foo</td>
                      </tr>
                      <tr>
                        <td>%c{2}</td>
                        <td>org.apache.${break}commons.Foo</td>
                        <td>commons.Foo</td>
                      </tr>
                      <tr>
                        <td>%c{1.}</td>
                        <td>org.apache.${break}commons.Foo</td>
                        <td>o.a.c.Foo</td>
                      </tr>
                      <tr>
                        <td>%c{1.1.~.~}</td>
                        <td>org.apache.${break}commons.test.${break}Foo</td>
                        <td>o.a.~.~.Foo</td>
                      </tr>
                      <tr>
                        <td>%c{.}</td>
                        <td>org.apache.${break}commons.test.${break}Foo</td>
                        <td>....Foo</td>
                      </tr>
                    </table>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="PatternClass" />
                    <b>C</b>{precision}<br />
                    <b>class</b>{precision}
                  </td>
                  <td>
                    <p>Outputs the fully qualified class name of the caller issuing the logging request.
                      This conversion specifier can be optionally followed by<em>precision specifier</em>, that
                      follows the same rules as the logger name converter.
                    </p>
                    <p>Generating the class name of the caller (<a href="#LocationInformation">location information</a>)
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>d</b>{pattern}<br />
                    <b>date</b>{pattern}
                  </td>
                  <td>
                    <p>Outputs the date of the logging event. The date conversion specifier may be
                      followed by a set of braces containing a date and time pattern string per
                      #javadoc('java/text', 'SimpleDateFormat').
                    </p>
                    <p>The predefined formats are
                      <code>DEFAULT</code>,
                      <code>ABSOLUTE</code>,
                      <code>COMPACT</code>,
                      <code>DATE</code>,
                      <code>ISO8601</code>,
                      and
                      <code>ISO8601_BASIC</code>.
                    </p>
                    <p>You can also use a set of braces containing a time zone id per
                      <a class="javadoc" href="${javadocRoot}/java/util/TimeZone.html${sharp}getTimeZone(java.lang.String)">
                        java.util.TimeZone.getTimeZone</a>. If no date format specifier is given then ISO8601 format is assumed.
                      <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>
                    </p>
                    <p>
                      %d{UNIX} outputs the UNIX time in seconds. %d{UNIX_MILLIS} outputs the UNIX time in milliseconds.
                      The UNIX time is the difference, in seconds for UNIX and in milliseconds for UNIX_MILLIS, between
                      the current time and midnight, January 1, 1970 UTC. While the time unit is milliseconds, the
                      granularity depends on the operating system
                      (<a href="http://msdn.microsoft.com/en-us/windows/hardware/gg463266.aspx">Windows</a>).
                      This is an efficient way to output the event time because only a conversion from long to String
                      takes place, there is no Date formatting involved.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>enc</b>{pattern}<br />
                    <b>encode</b>{pattern>
                  </td>
                  <td>
                    <p>Escape newlines and HTML special characters in the specified pattern.
                    </p>
                    <p>Allows HTML to be safely logged.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>enc{pattern}</b><br />
                    <b>encode{pattern}</b>
                  </td>
                  <td>
                    <p>
                      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. Anytime
                      user provided data is logged, this can provide a safeguard.
                    </p>
                    <p>
                      A typical usage would encode the message
                      <pre>%enc{%m}</pre>
                      but user input could come from other locations as well, such as the MDC
                      <pre>%enc{%mdc{key}}</pre>
                    </p>
                    <p>The replaced characters are:
                     <table>
                       <tr>
                         <th>Character</th>
                         <th>Replacement</th>
                       </tr>
                       <tr>
                         <th>'\r', '\n'</th>
                         <th>Removed from the pattern</th>
                       </tr>
                       <tr>
                         <td>&amp;, &lt;, &gt;, &quot;, &apos;, &#x2F;</td>
                         <td>Replaced with the corresponding HTML entity</td>
                       </tr>
                     </table>
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>ex</b>|<b>exception</b>|<b>throwable</b><br />
                    &nbsp;&nbsp;{["none"<br />
                    &nbsp;&nbsp;|"full"<br />
                    &nbsp;&nbsp;|depth<br />
                    &nbsp;&nbsp;|"short"<br />
                    &nbsp;&nbsp;|"short.className"<br />
                    &nbsp;&nbsp;|"short.fileName"<br />
                    &nbsp;&nbsp;|"short.lineNumber"<br />
                    &nbsp;&nbsp;|"short.methodName"<br />
                    &nbsp;&nbsp;|"short.message"<br />
                    &nbsp;&nbsp;|"short.localizedMessage"]}
                  </td>
                  <td>
                    <p>
                      Outputs the Throwable trace bound to the LoggingEvent, by default this will output the full trace
                      as one would normally find with a call to Throwable.printStackTrace().
                    </p>
                    <p>
                      You can follow the throwable conversion word with an option in the form <b>%throwable{option}</b>.
                    </p>
                    <p>
                      <b>%throwable{short}</b> outputs the first line of the Throwable.
                    </p>
                    <p>
                      <b>%throwable{short.className}</b> outputs the name of the class where the exception occurred.
                    </p>
                    <p>
                      <b>%throwable{short.methodName}</b> outputs the method name where the exception occurred.
                    </p>
                    <p>
                      <b>%throwable{short.fileName}</b> outputs the name of the class where the exception occurred.
                    </p>
                    <p>
                      <b>%throwable{short.lineNumber}</b> outputs the line number where the exception occurred.
                    </p>
                    <p>
                      <b>%throwable{short.message}</b> outputs the message.
                    </p>
                    <p>
                      <b>%throwable{short.localizedMessage}</b> outputs the localized message.
                    </p>
                    <p>
                      <b>%throwable{n}</b> outputs the first n lines of the stack trace.
                    </p>
                    <p>
                      Specifying <b>%throwable{none}</b> or <b>%throwable{0}</b> suppresses output of the exception.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="PatternFile" />
                    <b>F</b><br />
                    <b>file</b>
                  </td>
                  <td><p>Outputs the file name where the logging request was issued.</p>
                    <p>Generating the file information (<a href="#LocationInformation">location information</a>)
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>highlight</b>{pattern}{style}
                  </td>
                  <td>
                    <p>Adds ANSI colors to the result of the enclosed pattern based on the current event's logging level.
                    </p>
                    <p>The default colors for each level are:
                     <table>
                       <tr>
                         <th>Level</th>
                         <th>ANSI color</th>
                       </tr>
                       <tr>
                         <td>FATAL</td>
                         <td>Bright red</td>
                       </tr>
                       <tr>
                         <td>ERROR</td>
                         <td>Bright red</td>
                       </tr>
                       <tr>
                         <td>WARN</td>
                         <td>Yellow</td>
                       </tr>
                       <tr>
                         <td>INFO</td>
                         <td>Green</td>
                       </tr>
                       <tr>
                         <td>DEBUG</td>
                         <td>Cyan</td>
                       </tr>
                       <tr>
                         <td>TRACE</td>
                         <td>Black (looks dark grey)</td>
                       </tr>
                     </table>
                    </p>
                    <p>The color names are ANSI names defined in the
                      <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/pattern/AnsiEscape.html">AnsiEscape</a> class.
                    </p>
                    <p>The color and attribute names and are standard, but the exact shade, hue, or value.
                    </p>
                    <table>
                      <caption>Color table</caption>
                      <tbody>
                        <tr>
                          <th>Intensity Code</th>
                          <th>0</th>
                          <th>1</th>
                          <th>2</th>
                          <th>3</th>
                          <th>4</th>
                          <th>5</th>
                          <th>6</th>
                          <th>7</th>
                        </tr>
                        <tr>
                          <th>Normal</th>
                          <td style="background: black;color:white">Black</td>
                          <td style="background: maroon;color:white">Red</td>
                          <td style="background: green;color:white">Green</td>
                          <td style="background: olive;color:white">Yellow</td>
                          <td style="background: navy;color:white">Blue</td>
                          <td style="background: purple;color:white">Magenta</td>
                          <td style="background: teal;color:white">Cyan</td>
                          <td style="background: silver;color:black">White</td>
                        </tr>
                        <tr>
                          <th>Bright</th>
                          <td style="background: gray;color:white">Black</td>
                          <td style="background: red;color:black">Red</td>
                          <td style="background: lime;color:black">Green</td>
                          <td style="background: yellow;color:black">Yellow</td>
                          <td style="background: blue;color:white">Blue</td>
                          <td style="background: fuchsia;color:black">Magenta</td>
                          <td style="background: cyan;color:black">Cyan</td>
                          <td style="background: white;color:black">White</td>
                        </tr>
                      </tbody>
                    </table>
                    <p>You can use the default colors with:
                     <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}</pre>
                    </p>
                    <p>You can override the default colors in the optional {style} option. For example:
     #if ($isPDF)
                     <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}
       {FATAL=white, ERROR=red, WARN=blue, INFO=black,
        DEBUG=green, TRACE=blue}</pre>
     #else
                     <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}{FATAL=white, ERROR=red, WARN=blue, INFO=black, DEBUG=green, TRACE=blue}</pre>
     #end
                    </p>
                    <p>You can highlight only the a portion of the log event:
                     <pre>%d [%t] %highlight{%-5level: %msg%n%throwable}</pre>
                    </p>
                    <p>You can style one part of the message and highlight the rest the log event:
     #if ($isPDF)
                     <pre>%style{%d [%t]}{black} %highlight{%-5level:
                         %msg%n%throwable}</pre>
     #else
                     <pre>%style{%d [%t]}{black} %highlight{%-5level: %msg%n%throwable}</pre>
     #end
                    </p>
                      #if ($isPDF)
                          <!--PB-->
                      #end
                    <p>You can also use the STYLE key to use a predefined group of colors:
     #if ($isPDF)
                     <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}
       {STYLE=Logback}</pre>
     #else
                     <pre>%highlight{%d [%t] %-5level: %msg%n%throwable}{STYLE=Logback}</pre>
     #end
                     The STYLE value can be one of:
                     <table>
                       <?dbfo keep-together="auto" ?>
                       <tr>
                         <th>Style</th>
                         <th>Description</th>
                       </tr>
                       <tr>
                         <td>Default</td>
                         <td>See above</td>
                       </tr>
                       <tr>
                         <td>Logback</td>
                         <td>
                           <table>
                             <tr>
                               <th>Level</th>
                               <th>ANSI color</th>
                             </tr>
                             <tr>
                               <td>FATAL</td>
                               <td>Blinking bright red</td>
                             </tr>
                             <tr>
                               <td>ERROR</td>
                               <td>Bright red</td>
                             </tr>
                             <tr>
                               <td>WARN</td>
                               <td>Red</td>
                             </tr>
                             <tr>
                               <td>INFO</td>
                               <td>Blue</td>
                             </tr>
                             <tr>
                               <td>DEBUG</td>
                               <td>Normal</td>
                             </tr>
                             <tr>
                               <td>TRACE</td>
                               <td>Normal</td>
                             </tr>
                           </table>
                         </td>
                       </tr>
                     </table>
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>K</b>{key}<br />
                    <b>map</b>{key}<br />
                    <b>MAP</b>{key}
                  </td>
                  <td>
                    <p>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. The <b>K</b> conversion character can be followed by the key
                      for the map placed between braces, as in
                      <b>%K{clientNumber}</b> where <code>clientNumber</code> is the key. The value in the Map
                      corresponding to the key will be output. If no additional sub-option
                      is specified, then the entire contents of the Map key value pair set
                      is output using a format {{key1,val1},{key2,val2}}
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="PatternLocation" />
                    <b>l</b><br />
                    <b>location</b>
                  </td>
                  <td>
                    <p>Outputs location information of the caller which generated the logging event.
                    </p>
                    <p>The location information depends on the JVM implementation but usually consists of the fully
                      qualified name of the calling method followed by the callers source the file name and line
                      number between parentheses.
                    </p>
                    <p>Generating <a href="#LocationInformation">location information</a>
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="PatternLine" />
                    <b>L</b><br />
                    <b>line</b>
                  </td>
                  <td><p>Outputs the line number from where the logging request
                    was issued.</p>
                    <p>Generating line number information (<a href="#LocationInformation">location information</a>)
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>m</b><br />
                    <b>msg</b><br />
                    <b>message</b>
                  </td>
                  <td>Outputs the application supplied message associated with the logging event.
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="PatternMethod" />
                    <b>M</b><br />
                    <b>method</b>
                  </td>
                  <td><p>Outputs the method name where the logging request was issued.</p>
                    <p>Generating the method name of the caller (<a href="#LocationInformation">location information</a>)
                    is an expensive operation and may impact performance. Use with caution.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>marker</b>
                  </td>
                  <td>The name of the marker, if one is present.</td>
                </tr>
                <tr>
                  <td align="center">
                    <b>n</b>
                  </td>
                  <td>
                    <p>Outputs the platform dependent line separator character or characters.
                    </p>
                    <p>This conversion character offers practically the same
                      performance as using non-portable line separator strings such as
                      "\n", or "\r\n". Thus, it is the preferred way of specifying a
                      line separator.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                  <a name="NanoTime" />
                    <b>N</b><br />
                    <b>nano</b>
                  </td>
                  <td><p>Outputs the result of <code>System.nanoTime()</code> at the time the log event was created.</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>p</b>|<b>level</b>{<em>level</em>=<em>label</em>, <em>level</em>=<em>label</em>, ...}
                    <b>p</b>|<b>level</b>{length=<em>n</em>}
                    <b>p</b>|<b>level</b>{lowerCase=<em>true</em>|<em>false</em>}
                  </td>
                  <td>
                    <p>
                      Outputs the level of the logging event. You provide a level name map in the form
                      "level=value, level=value" where level is the name of the Level and value is the value that
                      should be displayed instead of the name of the Level.
                    </p>
                    <p>
                      For example:
                      <pre>%level{WARN=Warning, DEBUG=Debug, ERROR=Error, TRACE=Trace, INFO=Info}</pre>
                    </p>
                    <p>
                      Alternatively, for the compact-minded:
                      <pre>%level{WARN=W, DEBUG=D, ERROR=E, TRACE=T, INFO=I}</pre>
                    </p>
                    <p>
                      More succinctly, for the same result as above, you can define the length of the level label:
                      <pre>%level{length=1}</pre>
                      If the length is greater than a level name length, the layout uses the normal level name.
                    </p>
                    <p>
                      You can combine the two kinds of options:
                      <pre>%level{ERROR=Error, length=2}</pre>
                      This give you the <code>Error</code> level name and all other level names of length 2.
                    </p>
                    <p>
                      Finally, you can output lower-case level names (the default is upper-case):
                      <pre>%level{lowerCase=true}</pre>
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>r</b><br />
                    <b>relative</b>
                  </td>
                  <td>Outputs the number of milliseconds elapsed since the JVM was started until the creation
                    of the logging event.
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>replace</b>{pattern}{regex}{substitution}
                  </td>
                  <td>
                    <p>Replaces occurrences of 'regex', a regular expression, with its replacement 'substitution' in the
                      string resulting from evaluation of the pattern. For example, "%replace(%msg}{\s}{}" will remove
                      all spaces contained in the event message.
                    </p>
                    <p>The pattern can be arbitrarily complex and in particular can contain multiple conversion keywords.
                      For instance, "%replace{%logger %msg}{\.}{/}" will replace all dots in the logger or the message of
                      the event with a forward slash.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>rEx</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                    <b>rException</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                    <b>rThrowable</b>["none"|"short"|"full"|depth],[filters(packages)}
                  </td>
                  <td>
                    <p>The same as the %throwable conversion word but the stack trace is printed starting with the
                      first exception that was thrown followed by each subsequent wrapping exception.
                    </p>
                    <p>The throwable conversion word can be followed by an option in the form
                      <b>%rEx{short}</b>
                      which will only output the first line of the Throwable or <b>%rEx{n}</b> where
                      the first n lines of the stacktrace will be printed. The conversion word can also be
                      followed by "filters(packages)" where packages is a list of package names that should
                      be suppressed from stack traces. Specifying <b>%rEx{none}</b>
                      or <b>%rEx{0}</b> will suppress printing of the exception.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>sn</b><br />
                    <b>sequenceNumber</b>
                  </td>
                  <td>Includes a sequence number that will be incremented in every event. The counter is a
                    static variable so will only be unique within applications that share the same converter Class
                    object.</td>
                </tr>
                <tr>
                  <td align="center">
                    <b>style</b>{pattern}{ANSI style}
                  </td>
                  <td>
                    <p>Uses ANSI escape sequences to style the result of the enclosed pattern. The style can consist of
                      a comma separated list of style names from the following table.
                      <table>
                        <tr>
                          <th>Style Name</th>
                          <th>Description</th>
                        </tr>
                        <tr>
                          <td>Normal</td>
                          <td>Normal display</td>
                        </tr>
                        <tr>
                          <td>Bright</td>
                          <td>Bold</td>
                        </tr>
                        <tr>
                          <td>Dim</td>
                          <td>Dimmed or faint characters</td>
                        </tr>
                        <tr>
                          <td>Underline</td>
                          <td>Underlined characters</td>
                        </tr>
                        <tr>
                          <td>Blink</td>
                          <td>Blinking characters</td>
                        </tr>
                        <tr>
                          <td>Reverse</td>
                          <td>Reverse video</td>
                        </tr>
                        <tr>
                          <td>Hidden</td>
                          <td></td>
                        </tr>
                        <tr>
                          <td>Black or FG_Black</td>
                          <td>Set foreground color to black</td>
                        </tr>
                        <tr>
                          <td>Red or FG_Red</td>
                          <td>Set foreground color to red</td>
                        </tr>
                        <tr>
                          <td>Green or FG_Green</td>
                          <td>Set foreground color to green</td>
                        </tr>
                        <tr>
                          <td>Yellow or FG_Yellow</td>
                          <td>Set foreground color to yellow</td>
                        </tr>
                        <tr>
                          <td>Blue or FG_Blue</td>
                          <td>Set foreground color to blue</td>
                        </tr>
                        <tr>
                          <td>Magenta or FG_Magenta</td>
                          <td>Set foreground color to magenta</td>
                        </tr>
                        <tr>
                          <td>Cyan or FG_Cyan</td>
                          <td>Set foreground color to cyan</td>
                        </tr>
                        <tr>
                          <td>White or FG_White</td>
                          <td>Set foreground color to white</td>
                        </tr>
                        <tr>
                          <td>Default or FG_Default</td>
                          <td>Set foreground color to default (white)</td>
                        </tr>
                        <tr>
                          <td>BG_Black</td>
                          <td>Set background color to black</td>
                        </tr>
                        <tr>
                          <td>BG_Red</td>
                          <td>Set background color to red</td>
                        </tr>
                        <tr>
                          <td>BG_Green</td>
                          <td>Set background color to green</td>
                        </tr>
                        <tr>
                          <td>BG_Yellow</td>
                          <td>Set background color to yellow</td>
                        </tr>
                        <tr>
                          <td>BG_Blue</td>
                          <td>Set background color to blue</td>
                        </tr>
                        <tr>
                          <td>BG_Magenta</td>
                          <td>Set background color to magenta</td>
                        </tr>
                        <tr>
                          <td>BG_Cyan</td>
                          <td>Set background color to cyan</td>
                        </tr>
                        <tr>
                          <td>BG_White</td>
                          <td>Set background color to white</td>
                        </tr>
                      </table>
                    </p>
    				<p>For example:
                      <pre>%style{%d{ISO8601}}{black} %style{[%t]}{blue} %style{%-5level:}{yellow} %style{%msg%n%throwable}{green}</pre>
                    </p>
    				<p>You can also combine styles:
                      <pre>%d %highlight{%p} %style{%logger}{bright,cyan} %C{1.} %msg%n</pre>
                    </p>
    				<p>You can also use <code>%</code> with a color like <code>%black</code>, <code>%blue</code>, <code>%cyan</code>, and so on. For example:
                      <pre>%black{%d{ISO8601}} %blue{[%t]} %yellow{%-5level:} %green{%msg%n%throwable}</pre>
    				</p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>t</b><br />
                    <b>thread</b>
                  </td>
                  <td>Outputs the name of the thread that generated the logging event.</td>
                </tr>
                <tr>
                  <td align="center">
                    <b>x</b><br />
                    <b>NDC</b>
                  </td>
                  <td>Outputs the Thread Context Stack (also known as the Nested Diagnostic Context or NDC)
                    associated with the thread that generated the logging event.
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>X</b>{key[,key2...]}<br />
                    <b>mdc</b>{key[,key2...]}<br />
                    <b>MDC</b>{key[,key2...]}
                  </td>
                  <td>
                    <p>Outputs the Thread Context Map (also known as the Mapped Diagnostic Context or MDC)
                      associated with the thread that generated the logging event. The
                      <b>X</b>
                      conversion character can be followed by one or more keys for the
                      map placed between braces, as in
                      <b>%X{clientNumber}</b>
                      where
                      <code>clientNumber</code>
                      is the key. The value in the MDC
                      corresponding to the key will be output.</p>
                    <p>If a list of keys are provided, such as <b>%X{name, number}</b>, then each key that is present in the
                        ThreadContext will be output using the format {name=val1, number=val2}. The key/value pairs will be
                      printed in the order they appear in the list.</p>
                    <p>If no sub-options are specified then the entire contents of the MDC key value pair set
                      is output using a format {key1=val1, key2=val2}. The key/value pairs will be printed in sorted order.
                    </p>
                    <p>See the
                      <a class="javadoc" href="../log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html">ThreadContext</a>
                      class for more details.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>u</b>{"RANDOM" | "TIME"}<br />
                    <b>uuid</b>
                  </td>
                  <td>Includes either a random or a time-based UUID. The time-based UUID is a Type 1 UUID that can
                    generate up to 10,000 unique ids per millisecond, will use the MAC address of each host, and to
                    try to insure uniqueness across multiple JVMs and/or ClassLoaders on the same host a
                    random number between 0 and 16,384 will be associated with each instance of the UUID generator
                    Class and included in each time-based UUID generated. Because time-based UUIDs contain
                    the MAC address and timestamp they should be used with care as they can cause a security
                    vulnerability.
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>xEx</b>{"none"|"short"|"full"|depth],[filters(packages)}<br />
                    <b>xException</b>["none"|"short"|"full"|depth],[filters(packages)}<br />
                    <b>xThrowable</b>["none"|"short"|"full"|depth],[filters(packages)}
                  </td>
                  <td>
                    <p>The same as the %throwable conversion word but also includes class packaging information.
                    </p>
                    <p>At the end of each stack element of the exception, a string containing the name of the jar file
                      that contains the class or the directory the class is located in and the "Implementation-Version"
                      as found in that jar's manifest will be added. If the information is uncertain, then the class
                      packaging data will be preceded by a tilde, i.e. the '~' character.
                    </p>
                    <p>The throwable conversion word can be followed by an option in the form
                      <b>%xEx{short}</b>
                      which will only output the first line of the Throwable or <b>%xEx{n}</b> where
                      the first n lines of the stacktrace will be printed. The conversion word can also be
                      followed by "filters(packages)" where packages is a list of package names that should
                      be suppressed from stack traces. Specifying <b>%xEx{none}</b>
                      or <b>%xEx{0}</b> will suppress printing of the exception.
                    </p>
                  </td>
                </tr>
                <tr>
                  <td align="center">
                    <b>%</b>
                  </td>
                  <td>The sequence %% outputs a single percent sign.
                  </td>
                </tr>
              </table>
              <p>By default the relevant information is output as is. However,
                with the aid of format modifiers it is possible to change the
                minimum field width, the maximum field width and justification.
              </p>
              <p>The optional format modifier is placed between the percent sign
                and the conversion character.
              </p>
              <p>The first optional format modifier is the
                <em>left justification
                  flag
                </em>
                which is just the minus (-) character. Then comes the
                optional
                <em>minimum field width</em>
                modifier. This is a decimal
                constant that represents the minimum number of characters to
                output. If the data item requires fewer characters, it is padded on
                either the left or the right until the minimum width is
                reached. The default is to pad on the left (right justify) but you
                can specify right padding with the left justification flag. The
                padding character is space. If the data item is larger than the
                minimum field width, the field is expanded to accommodate the
                data. The value is never truncated.
              </p>
              <p>This behavior can be changed using the
                <em>maximum field
                  width
                </em>
                modifier which is designated by a period followed by a
                decimal constant. If the data item is longer than the maximum
                field, then the extra characters are removed from the
                <em>beginning</em>
                of the data item and not from the end. For
                example, it the maximum field width is eight and the data item is
                ten characters long, then the first two characters of the data item
                are dropped. This behavior deviates from the printf function in C
                where truncation is done from the end.
              </p>
              <p>Truncation from the end is possible by appending a minus character
                right after the period. In that case, if the maximum field width
                is eight and the data item is ten characters long, then the last
                two characters of the data item are dropped.
              </p>
              <p>Below are various format modifier examples for the category
                conversion specifier.
              </p>
              <table>
                <tr>
                  <th>Format modifier</th>
                  <th>left justify</th>
                  <th>minimum width</th>
                  <th>maximum width</th>
                  <th>comment</th>
                </tr>
                <tr>
                  <td align="center">%20c</td>
                  <td align="center">false</td>
                  <td align="center">20</td>
                  <td align="center">none</td>
                  <td>Left pad with spaces if the category name is less than 20
                    characters long.
                  </td>
                </tr>
                <tr>
                  <td align="center">%-20c</td>
                  <td align="center">true</td>
                  <td align="center">20</td>
                  <td align="center">none</td>
                  <td>Right pad with
                    spaces if the category name is less than 20 characters long.
                  </td>
                </tr>
                <tr>
                  <td align="center">%.30c</td>
                  <td align="center">NA</td>
                  <td align="center">none</td>
                  <td align="center">30</td>
                  <td>Truncate from the beginning if the category name is longer than 30
                    characters.
                  </td>
                </tr>
                <tr>
                  <td align="center">%20.30c</td>
                  <td align="center">false</td>
                  <td align="center">20</td>
                  <td align="center">30</td>
                  <td>Left pad with spaces if the category name is shorter than 20
                    characters. However, if category name is longer than 30 characters,
                    then truncate from the beginning.
                  </td>
                </tr>
                <tr>
                  <td align="center">%-20.30c</td>
                  <td align="center">true</td>
                  <td align="center">20</td>
                  <td align="center">30</td>
                  <td>Right pad with spaces if the category name is shorter than 20
                    characters. However, if category name is longer than 30 characters,
                    then truncate from the beginning.
                  </td>
                </tr>
                <tr>
                  <td align="center">%-20.-30c</td>
                  <td align="center">true</td>
                  <td align="center">20</td>
                  <td align="center">30</td>
                  <td>Right pad with spaces if the category name is shorter than 20
                    characters. However, if category name is longer than 30 characters,
                    then truncate from the end.
                  </td>
                </tr>
                <caption align="top">Pattern Converters</caption>
              </table>
              <h4>ANSI Styling on Windows</h4>
              <p>ANSI escape sequences are supported natively on many platforms but are not by default on Windows. To
                enable ANSI support simply add the <a href="http://jansi.fusesource.org/">Jansi</a> jar to your
                application and Log4j will automatically make use of it when writing to the console.
              </p>
              <h4>Example Patterns</h4>
              <h5>Filtered Throwables</h5>
              <p>This example shows how to filter out classes from unimportant packages in stack traces.
              </p>
              <pre class="prettyprint linenums"><![CDATA[<properties>
      <property name="filters">org.junit,org.apache.maven,sun.reflect,java.lang.reflect</property>
    </properties>
    ...
    <PatternLayout pattern="%m%xEx{filters(${dollar}{filters})}%n"/>]]></pre>
              <p>The result printed to the console will appear similar to:
              </p>
     #if ($isPDF)
              <pre>Exception java.lang.IllegalArgumentException: IllegalArgument
             at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.
                  testException(ExtendedThrowableTest.java:72) [test-classes/:?]
             ... suppressed 26 lines
             at ${dollar}Proxy0.invoke(Unknown Source)} [?:?]
             ... suppressed 3 lines
             Caused by: java.lang.NullPointerException: null pointer
             at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.
                  testException(ExtendedThrowableTest.java:71) ~[test-classes/:?]
             ... 30 more</pre>
     #else
              <pre>Exception java.lang.IllegalArgumentException: IllegalArgument
    at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.testException(ExtendedThrowableTest.java:72) [test-classes/:?]
    ... suppressed 26 lines
    at ${dollar}Proxy0.invoke(Unknown Source)} [?:?]
    ... suppressed 3 lines
    Caused by: java.lang.NullPointerException: null pointer
    at org.apache.logging.log4j.core.pattern.ExtendedThrowableTest.testException(ExtendedThrowableTest.java:71) ~[test-classes/:?]
    ... 30 more</pre>
     #end
              <h5>ANSI Styled</h5>
              <p>The log level will be highlighted according to the event's log level. All the content that follows
                the level will be bright green.</p>
              <pre class="prettyprint linenums"><![CDATA[<PatternLayout>
      <pattern>%d %highlight{%p} %style{%C{1.} [%t] %m}{bold,green}%n</pattern>
    </PatternLayout>]]></pre>
            </subsection>
            <a name="RFC5424Layout"/>
            <subsection name="RFC5424Layout">
              <p>As the name implies, the RFC5424Layout formats LogEvents in accordance with
                <a href="http://tools.ietf.org/html/rfc5424">RFC 5424</a>, the enhanced Syslog specification. Although the specification
                is primarily directed at sending messages via Syslog, this format is quite useful for
                other purposes since items are passed in the message as self-describing key/value pairs.
              </p>
              <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>appName</td>
                  <td>String</td>
                  <td>The value to use as the APP-NAME in the RFC 5424 syslog record.</td>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the syslog String to a byte array. The String must be
                    a valid ${Charset}. If not specified, the default system Charset will be used.</td>
                </tr>
                <tr>
                  <td>enterpriseNumber</td>
                  <td>integer</td>
                  <td>The IANA enterprise number as described in
                    <a href="http://tools.ietf.org/html/rfc5424#section-7.2.2">RFC 5424</a></td>
                </tr>
                <tr>
                  <td>exceptionPattern</td>
                  <td>String</td>
                  <td>One of the conversion specifiers from PatternLayout that defines which ThrowablePatternConverter
                  to use to format exceptions. Any of the options that are valid for those specifiers may be included.
                  The default is to not include the Throwable from the event, if any, in the output.</td>
                </tr>
                <tr>
                  <td>facility</td>
                  <td>String</td>
                  <td>The facility is used to try to classify the message. The facility option must be set to one of
                    "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV",
                    "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5",
                    "LOCAL6", or "LOCAL7". These values may be specified as upper or lower case characters.</td>
                </tr>
                <tr>
                  <td>format</td>
                  <td>String</td>
                  <td>If set to "RFC5424" the data will be formatted in accordance with RFC 5424. Otherwise, it will
                    be formatted as a BSD Syslog record. Note that although BSD Syslog records are required to be
                    1024 bytes or shorter the SyslogLayout does not truncate them. The RFC5424Layout also does not
                    truncate records since the receiver must accept records of up to 2048 bytes and may accept records
                    that are longer.</td>
                </tr>
                <tr>
                  <td>id</td>
                  <td>String</td>
                  <td>The default structured data id to use when formatting according to RFC 5424. If the LogEvent contains
                    a StructuredDataMessage the id from the Message will be used instead of this value.</td>
                </tr>
                <tr>
                  <td>immediateFlush</td>
                  <td>boolean</td>
                  <td>When set to true, each write will be followed by a flush. This will guarantee the data is written
                    to disk but could impact performance.</td>
                </tr>
                <tr>
                  <td>includeMDC</td>
                  <td>boolean</td>
                  <td>Indicates whether data from the ThreadContextMap will be included in the RFC 5424 Syslog record.
                    Defaults to true.</td>
                </tr>
                <tr>
                  <td>loggerFields</td>
                  <td>List of KeyValuePairs</td>
                  <td>Allows arbitrary PatternLayout patterns to be included as specified ThreadContext fields; no default
                    specified. To use, include a &lt;LoggerFields&gt; nested element, containing one or more
                    &lt;KeyValuePair&gt; elements. Each &lt;KeyValuePair&gt; must have a key attribute, which
                    specifies the key name which will be used to identify the field within the MDC Structured Data element,
                    and a value attribute, which specifies the PatternLayout pattern to use as the value.</td>
                </tr>
                <tr>
                  <td>mdcExcludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be excluded from the LogEvent. This is mutually
                    exclusive with the mdcIncludes attribute. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcIncludes</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that should be included in the FlumeEvent. Any keys in the MDC
                    not found in the list will be excluded. This option is mutually exclusive with the mdcExcludes
                    attribute. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcRequired</td>
                  <td>String</td>
                  <td>A comma separated list of mdc keys that must be present in the MDC. If a key is not present a
                    LoggingException will be thrown. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcPrefix</td>
                  <td>String</td>
                  <td>A string that should be prepended to each MDC key in order to distinguish it from event attributes.
                    The default string is "mdc:". This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>mdcId</td>
                  <td>String</td>
                  <td>A required MDC ID. This attribute only applies to RFC 5424 syslog records.</td>
                </tr>
                <tr>
                  <td>messageId</td>
                  <td>String</td>
                  <td>The default value to be used in the MSGID field of RFC 5424 syslog records. </td>
                </tr>
                <tr>
                  <td>newLine</td>
                  <td>boolean</td>
                  <td>If true, a newline will be appended to the end of the syslog record. The default is false.</td>
                </tr>
                <tr>
                  <td>newLineEscape</td>
                  <td>String</td>
                  <td>String that should be used to replace newlines within the message text.</td>
                </tr>
                <caption align="top">RFC5424Layout Parameters</caption>
              </table>
            </subsection>
            <a name="SerializedLayout"/>
            <subsection name="SerializedLayout">
              <p>The SerializedLayout simply serializes the LogEvent into a byte array. This is useful when
                sending messages via JMS or via a Socket connection. The SerializedLayout accepts no parameters.
              </p>
            </subsection>
            <a name="SyslogLayout"/>
            <subsection name="SyslogLayout">
              <p>The SyslogLayout formats the LogEvent as BSD Syslog records matching the same format used by
                Log4j 1.2.
              </p>
               <table>
                <tr>
                  <th>Parameter Name</th>
                  <th>Type</th>
                  <th>Description</th>
                </tr>
                <tr>
                  <td>charset</td>
                  <td>String</td>
                  <td>The character set to use when converting the syslog String to a byte array. The String must be
                    a valid ${Charset}. If not specified, this layout uses UTF-8.</td>
                </tr>
                <tr>
                  <td>facility</td>
                  <td>String</td>
                  <td>The facility is used to try to classify the message. The facility option must be set to one of
                    "KERN", "USER", "MAIL", "DAEMON", "AUTH", "SYSLOG", "LPR", "NEWS", "UUCP", "CRON", "AUTHPRIV",
                    "FTP", "NTP", "AUDIT", "ALERT", "CLOCK", "LOCAL0", "LOCAL1", "LOCAL2", "LOCAL3", "LOCAL4", "LOCAL5",
                    "LOCAL6", or "LOCAL7". These values may be specified as upper or lower case characters.</td>
                </tr>
                <tr>
                  <td>newLine</td>
                  <td>boolean</td>
                  <td>If true, a newline will be appended to the end of the syslog record. The default is false.</td>
                </tr>
                 <tr>
                   <td>newLineEscape</td>
                   <td>String</td>
                   <td>String that should be used to replace newlines within the message text.</td>
                 </tr>
                 <caption align="top">SyslogLayout Parameters</caption>
              </table>
            </subsection>
            <a name="XMLLayout"/>
            <subsection name="XMLLayout">
              <!-- From Javadoc of org.apache.logging.log4j.core.layout.XMLLayout -->
              <p>
                <!-- FIXME: log4j.dtd link is broken -->
              Appends a series of <code>Event</code> elements as defined in the <a href="log4j.dtd">log4j.dtd</a>.
              </p>
              <h4>Complete well-formed XML vs. fragment XML</h4>
              <p>
              If you configure <code>complete="true"</code>, the appender outputs a well-formed XML document where the
              default namespace is the Log4j namespace <code>"http://logging.apache.org/log4j/2.0/events"</code>.  By default,
              with <code>complete="false"</code>, you should include the output as an <em>external entity</em> in a
              separate file to form a well-formed XML document, in which case the appender uses
              <code>namespacePrefix</code> with a default of <code>"log4j"</code>.
              </p>
              <p>
              A well-formed XML document follows this pattern:
              </p>
              <pre class="prettyprint linenums">&lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
    &lt;Events xmlns=&quot;http://logging.apache.org/log4j/2.0/events&quot;&gt;
      &lt;Event logger=&quot;com.foo.Bar&quot; timestamp=&quot;1373436580419&quot; level=&quot;INFO&quot; thread=&quot;main&quot;&gt;
        &lt;Message&gt;&lt;![CDATA[This is a log message 1]]&gt;&lt;/Message&gt;
        &lt;Marker parent=&quot;Parent Marker&quot;&gt;&lt;Child Marker&gt;&lt;/Marker&gt;
      &lt;/Event&gt;
      &lt;Event logger=&quot;com.foo.Baz&quot; timestamp=&quot;1373436580420&quot; level=&quot;INFO&quot; thread=&quot;main&quot;&gt;
        &lt;Message&gt;&lt;![CDATA[This is a log message 2]]&gt;&lt;/Message&gt;
        &lt;Marker&gt;&lt;The Marker Name&gt;&lt;/Marker&gt;
      &lt;/Event&gt;
    &lt;/Events&gt;</pre>
              <p>
              If <code>complete="false"</code>, the appender does not write the XML processing instruction and the root
              element.
              </p>
              <p>
              This approach enforces the independence of the XMLLayout and the appender where you embed it.
              </p>
              <h4>Marker</h4>
              <p>Markers are represented by a <code>Marker</code> element within the <code>Event</code> element.
              The <code>Marker</code> element appears only when a marker is used in the log message. The name of the marker's
              parent will be provided in the <code>parent</code> attribute of the <code>Marker</code> element.
              Only the leaf marker is included, not the full hierarchy.
              </p>
              <h4>Encoding</h4>
              <p>
              Appenders using this layout should have their <code>charset</code> set to <code>UTF-8</code> or
              <code>UTF-16</code>, otherwise events containing non ASCII characters could result in corrupted log files.
              If not specified, this layout uses UTF-8.
              </p>
              <h4>Pretty vs. compact XML</h4>
              <p>
              By default, the XML layout is not compact (a.k.a. not "pretty") with <code>compact="false"</code>, which
              means the appender uses end-of-line characters and indents lines to format the XML. If
              <code>compact="true"</code>,  then no end-of-line or indentation is used. Message content may contain,
              of course, end-of-lines.
              </p>
            </subsection>
            <a name="GELFLayout"/>
            <subsection name="GELF Layout">
              <!-- From Javadoc of org.apache.logging.log4j.core.layout.GELFLayout -->
              <p>
                Lays out events in the Graylog Extended Log Format (GELF) 1.1.
              </p>
              <p>
                This layout compresses JSON to GZIP or ZLIB (the <code>compressionType</code>) if log event data is larger than 1024 bytes
                (the <code>compressionThreshold</code>). This layout does not implement chunking.
              </p>
              <p>
                Configure as follows to send to a Graylog2 server:
              </p>
              <pre class="prettyprint linenums">[
      &lt;Appenders&gt;
        &lt;Socket name="Graylog" protocol="udp" host="graylog.domain.com" port="12201"&gt;
            &lt;GelfLayout host="someserver" compressionType="GZIP" compressionThreshold="1024"&gt;
                &lt;KeyValuePair key="additionalField1" value="additional value 1"/&gt;
                &lt;KeyValuePair key="additionalField2" value="additional value 2"/&gt;
            &lt;/GelfLayout&gt;
        &lt;/Socket&gt;
      &lt;/Appenders&gt;
    ]
    </pre>
               <p>
                 See also:
               </p>
               <ul>
                 <li>The <a href="http://graylog2.org/gelf">GELF home page</a></li>
                 <li>The <a href="http://graylog2.org/resources/gelf/specification">GELF specification</a></li>
               </ul>
            </subsection>
            <a name="LocationInformation"/>
            <subsection name="Location Information">
            <p>
    			If one of the layouts is
    			configured with a location-related attribute like
    			HTML <a href="#HtmlLocationInfo">locationInfo</a>,
    			or one of the patterns
    			<a href="#PatternClass">%C or $class</a>,
    			<a href="#PatternFile">%F or %file</a>,
    			<a href="#PatternLocation">%l or %location</a>,
    			<a href="#PatternLine">%L or %line</a>,
    			<a href="#PatternMethod">%M or %method</a>,
    			Log4j will take a snapshot of the
    			stack, and walk the stack trace to find the location information.
    			</p>
    			<p>
    			This is an expensive operation: 1.3 - 5 times slower for
    			synchronous loggers. Synchronous loggers wait as
    			long as possible before they take this stack snapshot. If no
    			location is required, the snapshot will never be taken.
    			</p><p>
    			However,
    			asynchronous loggers need to make this decision before passing the
    			log message to another thread; the location information will be
    			lost after that point.
    			The performance impact of taking a stack trace snapshot is even
    			higher for asynchronous loggers: logging with location is
    			4 - 20 times slower than without location.
    			For this reason, asynchronous loggers and asynchronous
    			appenders do not include location information by default.
    			</p><p>
    			You can override the default behaviour in your logger
    			or asynchronous appender configuration
    			by specifying
    			<tt>includeLocation="true"</tt>.
    			</p>
    			<p>
    			</p>
            </subsection>
          </section>
        </body>
    </document>
    �����������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/logsep.xml��������������������������������������������0000664�0000000�0000000�00000016650�12577562624�0023131�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Logging Separation</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
          <section name="Logging Separation">
            <p>
              There are many well known use cases where applications may share an environment with other applications
              and each has a need to have its own, separate logging environment. This purpose of this section is to
              discuss some of these cases and ways to accomplish this.
            </p>
            <subsection name="Use Cases">
              <a name="UseCases"/>
              <p>
                This section describes some of the use cases where Log4j could be used and what its desired behavior
                might be.
              </p>
              <h4>Standalone Application</h4>
                <p>
                  Standalone applications are usually relatively simple. They typically have one bundled executable
                  that requires only a single logging configuration.
                </p>
              <h4>Web Applications</h4>
                <p>
                  A typical web application will be packaged as a WAR file and will include all of its dependencies in
                  WEB-INF/lib and will have its configuration file located in the class path or in a location
                  configured in the web.xml. Be sure to follow the <a href="webapp.html">instructions to initialize Log4j 2
                  in a web application</a>.
                </p>
              <h4>Java EE Applications</h4>
                <p>
                  A Java EE application will consist of one or more WAR files and possible some EJBs, typically all
                  packaged in an EAR file. Usually, it is desirable to have a single configuration that applies to
                  all the components in the EAR. The logging classes will generally be placed in a location shared
                  across all the components and the configuration needs to also be shareable.  Be sure to follow the
                  <a href="webapp.html">instructions to initialize Log4j 2 in a web application</a>.
                </p>
              <h4>"Shared" Web Applications and REST Service Containers</h4>
                <p>
                  In this scenario there are multiple WAR files deployed into a single container. Each of the applications
                  should use the same logging configuration and share the same logging implementation across each of the
                  web applications. When writing to files and streams each of the applications should share them to avoid
                  the issues that can occur when multiple components try to write to the same file(s) through different
                  File objects, channels, etc.
                </p>
              <h4>OSGi Applications</h4>
                <p>
                  An OSGi container physically separates each JAR into its own ClassLoader, thus enforcing modularity of
                  JARs as well as providing standardized ways for JARs to share code based on version numbers. Suffice to
                  say, the OSGi framework is beyond the scope of this manual. There are some differences when using Log4j
                  in an OSGi container. By default, each JAR bundle is scanned for its own Log4j configuration file.
                  Similar to the web application paradigm, every bundle has its own LoggerContext. As this may be
                  undesirable when a global Log4j configuration is wanted, then the
                  <a href="extending.html#ContextSelector">ContextSelector</a> should be overridden with
                  <code>BasicContextSelector</code> or <code>JndiContextSelector</code>.
                </p>
            </subsection>
            <subsection name="Approaches">
              <a name="Approaches"/>
              <h4>The Simple Approach</h4>
                <p>
                  The simplest approach for separating logging within applications is to package each application with
                  its own copy of Log4j and to use the BasicContextSelector. While this works for standalone applications
                  and may work for web applications and possibly Java EE applications, it does not work at all in the
                  last case.  However, when this approach does work it should be used as it is ultimately the simplest
                  and most straightforward way of implementing logging.
                </p>
    
              <h4>Using Context Selectors</h4>
                <p>
                  There are a few patterns for achieving the desired state of logging separation using ContextSelectors:
                </p>
                  <ol>
                    <li>Place the logging jars in the container's classpath and set the system property
                      "Log4jContextSelector" to "org.apache.logging.log4j.core.selector.BasicContextSelector". This will
                      create a single LoggerContext using a single configuration that will be shared across all
                      applications.</li>
                    <li>
                      Place the logging jars in the container's classpath and use the default ClassLoaderContextSelector.
                      Follow the <a href="webapp.html">instructions to initialize Log4j 2 in a web application</a>. Each
                      application can be configured to share the same configuration used at the container or can be
                      individually configured. If status logging is set to debug in the configuration there will be output
                      from when logging is initialized in the container and then again in each web application.
                    </li>
                    <li>
                      Follow the <a href="webapp.html">instructions to initialize Log4j 2 in a web application</a> and set
                      the system property or servlet context parameter <code>Log4jContextSelector</code> to
                      <kbd>org.apache.logging.log4j.core.selector.JndiContextSelector</kbd>. This will cause the container
                      to use JNDI to locate each web application's <code>LoggerContext</code>. Be sure to set the
                      <code>isLog4jContextSelectorNamed</code> context parameter to <kbd>true</kbd> and also set the
                      <code>log4jContextName</code> and <code>log4jConfiguration</code> context parameters.
                    </li>
                  </ol>
                <p>
                  The exact method for setting system properties depends on the container. For Tomcat, edit
                  <code>$CATALINA_HOME/conf/catalina.properties</code>. Consult the documentation for other web containers.
                </p>
            </subsection>
          </section>
        </body>
    </document>
    ����������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/lookups.xml�������������������������������������������0000664�0000000�0000000�00000051057�12577562624�0023334�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>
            </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.</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>
            </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>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/markers.xml�������������������������������������������0000664�0000000�0000000�00000011526�12577562624�0023301�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 API</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
            <section name="Log4j 2 API">
              <subsection name="Markers">
                <a name="Markers"/>
                <p>
                  One of the primary purpose of a logging framework is to provide the means to generate debugging and
                  diagnostic information only when it is needed, and to allow filtering of that information so that it
                  does not overwhelm the system or the individuals who need to make use of it. As an example, an
                  application desires to log its entry, exit and other operations separately from SQL statements
                  being executed, and wishes to be able to log queries separate from updates. One way to accomplish
                  this is shown below:
                </p>
            <pre class="prettyprint linenums"><![CDATA[
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.LogManager;
    import java.util.Map;
    
    public class MyApp {
    
        private Logger logger = LogManager.getLogger(MyApp.class.getName());
        private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL");
        private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE").set(SQL_MARKER);
        private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY").set(SQL_MARKER);
    
        public String doQuery(String table) {
            logger.entry(param);
    
            logger.debug(QUERY_MARKER, "SELECT * FROM {}", table);
    
            return logger.exit();
        }
    
        public String doUpdate(String table, Map<String, String> params) {
            logger.entry(param);
    
            if (logger.isDebugEnabled()) {
              logger.debug(UPDATE_MARKER, "UPDATE {} SET {}", table, formatCols());
    
            return logger.exit();
        }
    
        private String formatCols(Map<String, String> cols) {
            StringBuilder sb = new StringBuilder();
            boolean first = true;
            for (Map.Entry<String, String> entry : cols.entrySet()) {
                if (!first) {
                    sb.append(", ");
                }
                sb.append(entry.getKey()).append("=").append(entry.getValue());
                first = false;
            }
            return sb.toString();
        }
    }]]></pre>
                <p>
                  In the example above it is now possible to add MarkerFilters to only allow SQL update operations
                  to be logged, all SQL updates to be logged or to log everything in MyApp.
                </p>
                <p>
                  Some important rules about Markers must be considered when using them.
                </p>
                  <ol>
                    <li>Markers must be unique. They are permanently registered by name so care should be taken
                      to insure that Markers used in your application are distinct from those in the application's
                      dependencies, unless that is what is desired.</li>
                    <li>Parent Markers can be added or removed dynamically. However, this is fairly expensive to do.
                      Instead, it is recommended that the parents be identified when obtaining the Marker the first time
                      as shown in the examples above. Specifically, the set method replaces all the markers in
                      a single operation while add and remove act on only a single Marker at a time.</li>
                    <li>Evaluating Markers with multiple ancestors is much more expensive than Markers with no parents.
                      For example, in one set of tests to evaluate whether a Marker matched its grandparent took 3
                      times longer than evaluating the Marker itself. Even then though, evaluating Markers is
                      inexpensive compared to resolving the callers class name or line number.</li>
                  </ol>
              </subsection>
            </section>
        </body>
    </document>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/messages.xml������������������������������������������0000664�0000000�0000000�00000031405�12577562624�0023442�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 API Messages</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
      </properties>
    
      <body>
        <section name="Log4j 2 API">
          <subsection name="Messages">
            <a name="Messages"/>
            <p>
              Although Log4j 2 provides Logger methods that accept Strings and Objects, all of these are ultimately
              captured in Message objects that are then associated with the log event. Applications are free to
              construct Messages of their own and pass them to the Logger. Although it may seem more expensive than
              passing the message format and parameters directly to the event, testing has shown that with modern
              JVMs the cost of creating and destroying events is minor, especially when complex tasks are encapsulated
              in the Message instead of the application. In addition, when using the methods that accept Strings and
              parameters, the underlying Message object will only be created if any configured global filters
              or the Logger's log level allow the message to be processed.
            </p>
            <p>
              Consider an application that has a Map object containing {"Name" = "John Doe", "Address" = "123 Main
              St.",
              "Phone" = "(999) 555-1212"} and a User object that has a getId method that returns "jdoe". The developer
              would like to add an informational message that returns "User John Doe has logged in using id jdoe". The
              way this could be accomplished is by doing:
            </p>
            <pre class="prettyprint">logger.info("User {} has logged in using id {}", map.get("Name"), user.getId());</pre>
            <p>
              While there is nothing inherently wrong with this, as the complexity of the objects and desired output
              increases this technique becomes harder to use. As an alternative, using Messages allows:
            </p>
            <pre class="prettyprint">logger.info(new LoggedInMessage(map, user));</pre>
            <p>
              In this alternative the formatting is delegated to the LoggedInMessage object's getFormattedMessage
              method.
              Although in this alternative a new object is created, none of the methods on the objects passed to the
              LoggedInMessage are invoked until the LoggedInMessage is formatted. This is especially useful when an
              Object's toString method does not produce the information you would like to appear in the log.
            </p>
            <p>
              Another advantage to Messages is that they simplify writing Layouts. In other logging frameworks the
              Layout must loop through the parameters individually and determine what to do based on what objects
              are encountered. With Messages the Layout has the option of delegating the formatting to the Message or
              performing its formatting based on the type of Message encountered.
            </p>
            <p>
              Borrowing from the earlier example illustrating Markers to identify SQL statements being logged, Messages
              can also be leveraged. First, the Message is defined.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
    public class SQLMessage implements Message {
      public enum SQLType {
          UPDATE,
          QUERY
      };
    
      private final SQLType type;
      private final String table;
      private final Map<String, String> cols;
    
      public SQLMessage(SQLType type, String table) {
          this(type, table, null);
      }
    
      public SQLMessage(SQLType type, String table, Map<String, String> cols) {
          this.type = type;
          this.table = table;
          this.cols = cols;
      }
    
      public String getFormattedMessage() {
          switch (type) {
              case UPDATE:
                return createUpdateString();
                break;
              case QUERY:
                return createQueryString();
                break;
              default;
          }
      }
    
      public String getMessageFormat() {
          return type + " " + table;
      }
    
      public Object getParameters() {
          return cols;
      }
    
      private String createUpdateString() {
      }
    
      private String createQueryString() {
      }
    
      private String formatCols(Map<String, String> cols) {
          StringBuilder sb = new StringBuilder();
          boolean first = true;
          for (Map.Entry<String, String> entry : cols.entrySet()) {
              if (!first) {
                  sb.append(", ");
              }
              sb.append(entry.getKey()).append("=").append(entry.getValue());
              first = false;
          }
          return sb.toString();
      }
    }]]></pre>
          <p>
            Next we can use the message in our application.
          </p>
            <pre class="prettyprint linenums"><![CDATA[
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.LogManager;
    import java.util.Map;
    
    public class MyApp {
    
        private Logger logger = LogManager.getLogger(MyApp.class.getName());
        private static final Marker SQL_MARKER = MarkerManager.getMarker("SQL");
        private static final Marker UPDATE_MARKER = MarkerManager.getMarker("SQL_UPDATE", SQL_MARKER);
        private static final Marker QUERY_MARKER = MarkerManager.getMarker("SQL_QUERY", SQL_MARKER);
    
        public String doQuery(String table) {
            logger.entry(param);
    
            logger.debug(QUERY_MARKER, new SQLMessage(SQLMessage.SQLType.QUERY, table));
    
            return logger.exit();
        }
    
        public String doUpdate(String table, Map<String, String> params) {
            logger.entry(param);
    
            logger.debug(UPDATE_MARKER, new SQLMessage(SQLMessage.SQLType.UPDATE, table, parmas);
    
            return logger.exit();
        }
    }]]></pre>
            <p>
              Notice that in contrast to the prior version of this example, the logger.debug in doUpdate no longer
              needs to be wrapped in an isDebugEnabled call as creation of the SQLMessage is on the same order of
              magnitude of performing that check. Furthermore, all the formatting of the SQL columns is now hidden
              in the SQLMessage instead of having to take place in the business logic. Finally, if desired, Filters
              and/or Layouts can be written to take special action when an SQLMessage is encountered.
            </p>
          <h4>FormattedMessage</h4>
            <a name="FormattedMessage"/>
            <p>
              The message pattern passed to a
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/FormattedMessage.html">FormattedMessage</a>
              is first checked to see if it is a valid java.text.MessageFormat pattern. If it is, a MessageFormatMessage is
              used to format it. If not it is next checked to see if it contains any tokens that are valid format
              specifiers for String.format(). If so, a StringFormattedMessage is used to format it. Finally, if the
              pattern doesn't match either of those then a ParameterizedMessage is used to format it.
            </p>
          <h4>LocalizedMessage</h4>
            <a name="LocalizedMessage"/>
            <p>
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/LocalizedMessage.html">LocalizedMessage</a>
              is provided primarily to provide compatibility with Log4j 1.x. Generally,
              the best approach to localization is to have the client UI render the events in the client's locale.
            </p>
            <p>
              LocalizedMessage incorporates a ResourceBundle and allows the message pattern parameter to be the key to
              the message pattern in the bundle. If no bundle is specified,
              LocalizedMessage will attempt to locate a bundle with the name of the Logger used to log the event. The
              message retrieved from the bundle will be formatted using a FormattedMessage.
            </p>
          <h4>LoggerNameAwareMessage</h4>
            <a name="LoggerNameAwareMessage"/>
            <p>
              LoggerNameAwareMessage is an interface with a setLoggerName method. This method will be called during
              event construction so that the Message has the name of the Logger used to log the event when the
              message is being formatted.
            </p>
          <h4>MapMessage</h4>
            <a name="MapMessage"/>
            <p>
              A MapMessage contains a Map of String keys and values. MapMessage implements FormattedMessage and accepts
              a format specifier of "XML", in which case the Map will be formatted as XML. Otherwise, the Map will be
              formatted as "key1=value1 key2=value2...".
            </p>
            <h4>MessageFormatMessage</h4>
            <a name="MessageFormatMessage"/>
            <p>
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/MessageFormatMessage.html">MessageFormatMessage</a>
              handles messages that use a <a href="http://docs.oracle.com/javase/6/docs/api/java/text/MessageFormat.html">conversion format</a>.
              While this Message has more flexibility than ParameterizedMessage, it is also about two times slower.
            </p>
          <h4>MultiformatMessage</h4>
            <a name="MultiformatMessage"/>
            <p>
              A MultiformatMessage will have a getFormats method and a getFormattedMessage method that accepts and array
              of format Strings. The getFormats method may be called by a Layout to provide it information on what
              formatting options the Message supports. The Layout may then call getFormattedMessage with one or more
              for the formats. If the Message doesn't recognize the format name it will simply format the data using its
              default format. An example of this is the StructuredDataMessage which accepts a format String of "XML"
              which will cause it to format the event data as XML instead of the RFC 5424 format.
            </p>
          <h4>ObjectMessage</h4>
            <a name="ObjectMessage"/>
            <p>
              Formats an Object by calling its toString method.
            </p>
          <h4>ParameterizedMessage</h4>
            <a name="ParameterizedMessage"/>
            <p>
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/ParameterizedMessage.html">ParameterizedMessage</a>
              handles messages that contain "{}" in the format to represent replaceable tokens and the replacement
              parameters.
            </p>
          <h4>SimpleMessage</h4>
            <a name="SimpleMessage"/>
            <p>
              SimpleMessage contains a String that requires no formatting.
            </p>
          <h4>StringFormattedMessage</h4>
            <a name="StringFormattedMessage"/>
            <p>
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/StringFormattedMessage.html">StringFormattedMessage</a>
              handles messages that use a <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Formatter.html#syntax">conversion format</a>
              that is compliant with <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#format(java.lang.String, java.lang.Object...)">java.lang.String.format()</a>.
              While this Message has more flexibility than ParameterizedMessage, it is also 5 to 10 times slower.
            </p>
          <h4>StructuredDataMessage</h4>
            <a name="StructuredDataMessage"/>
            <p>
              <a href="../log4j-api/apidocs/org/apache/logging/log4j/message/StructuredDataMessage.html">StructuredDataMessage</a>
              allows applications to add items to a Map as well as set the id to allow a message to be formatted as a
              Structured Data element in accordance with <a href="http://tools.ietf.org/html/rfc5424">RFC 5424</a>.
            </p>
          <h4>ThreadDumpMessage</h4>
            <a name="ThreadDumpMessage"/>
            <p>
              A ThreadDumpMessage, if logged, will generate stack traces for all threads. If running on Java 6+ the
              stack traces will include any locks that are held.
            </p>
          <h4>TimestampMessage</h4>
            <a name="TimestampMessage"/>
            <p>
              A TimestampMessage will provide a getTimestamp method that is called during event construction. The
              timestamp in the Message will be used in lieu of the current timestamp.
            </p>
          </subsection>
        </section>
      </body>
    </document>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/migration.xml�����������������������������������������0000664�0000000�0000000�00000033260�12577562624�0023625�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Migrating from Log4j 1.x</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
        </properties>
    
        <body>
            <section name="Migrating from Log4j 1.x">
              <a name="Log4j1.2Bridge"/>
              <subsection name="Using the Log4j 1.x bridge">
                <p>
                  Perhaps the simplest way to convert to using Log4j 2 is to replace the log4j 1.x jar file with
                  Log4j 2's <code>log4j-1.2-api.jar</code>. However, to use this successfully applications must meet the
                  following requirements:
                </p>
                  <ol>
                    <li>They must not access methods and classes internal to the Log4j 1.x implementation such
                      as <code>Appender</code>s, <code>LoggerRepository</code> or <code>Category</code>'s
                      <code>callAppenders</code> method.</li>
                    <li>They must not programmatically configure Log4j.</li>
                    <li>They must not configure by calling the classes <code>DOMConfigurator</code> or
                      <code>PropertyConfigurator</code>.</li>
                  </ol>
              </subsection>
              <subsection name="Converting to the Log4j 2 API">
                <p>For the most part, converting from the Log4j 1.x API to Log4j 2 should be fairly simple. Many
                  of the log statements will require no modification. However, where necessary the following changes must be
                  made.</p>
                  <ol>
                    <li>
                      The main package in version 1 is <code>org.apache.log4j</code>, in version 2 it is
                      <code>org.apache.logging.log4j</code>
                    </li>
                    <li>
                      Calls to <code>org.apache.log4j.Logger.getLogger()</code> must be modified to
                      <code>org.apache.logging.log4j.LogManager.getLogger()</code>.
                    </li>
                    <li>
                      Calls to <code>org.apache.log4j.Logger.getRootLogger()</code> or
                      <code>org.apache.log4j.LogManager.getRootLogger()</code> must be replaced with
                      <code>org.apache.logging.log4j.LogManager.getRootLogger()</code>.</li>
                    <li>
                      Calls to <code>org.apache.log4j.Logger.getLogger</code> that accept a <code>LoggerFactory</code> must
                      remove the <code>org.apache.log4j.spi.LoggerFactory</code> and use one of Log4j 2's other extension
                      mechanisms.
                    </li>
                    <li>
                      Replace calls to <code>org.apache.log4j.Logger.getEffectiveLevel()</code> with
                      <code>org.apache.logging.log4j.Logger.getLevel()</code>.
                    </li>
                    <li>
                      Remove calls to <code>org.apache.log4j.LogManager.shutdown()</code>, they are not needed in version 2
                      because the Log4j Core now automatically adds a JVM shutdown hook on start up to perform any Core
                      clean ups.
                    </li>
                    <li>
                      Calls to <code>org.apache.log4j.Logger.setLevel()</code> or similar methods are not supported in the API.
                      Applications should remove these. Equivalent functionality is provided in the Log4j 2 implementation
                      classes, see <code>org.apache.logging.log4j.core.config.Configurator.setLevel()</code>, but may leave 
                      the application susceptible to changes in Log4j 2 internals.                   
                    </li>
                    <li>
                      Where appropriate, applications should convert to use parameterized messages instead of String
                      concatenation.
                    </li>
                    <li>
                      <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/MDC.html"><code>org.apache.log4j.MDC</code></a> and
                      <a href="http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/NDC.html"><code>org.apache.log4j.NDC</code></a>
                      have been replaced by the <a href="thread-context.html">Thread Context</a>.
                    </li>
                  </ol>
              </subsection>
              <subsection name="Configuring Log4j 2">
                <p>
                  Although the Log4j 2 configuration syntax is different than that of Log4j 1.x, most, if not all, of
                  the same functionality is available. Below are the example configurations for Log4j 1.x and their
                  counterparts in Log4j 2.
                </p>
    
                <h4>Sample 1 - Simple configuration using a Console Appender</h4>
                <p>Log4j 1.x XML configuration</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
    <log4j:configuration xmlns:log4j='http://jakarta.apache.org/log4j/'>
      <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <category name="org.apache.log4j.xml">
        <priority value="info" />
      </category>
      <Root>
        <priority value ="debug" />
        <appender-ref ref="STDOUT" />
      </Root>
    </log4j:configuration>]]></pre>
                <p>Log4j 2 XML configuration</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
      <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="org.apache.log4j.xml" level="info"/>
        <Root level="debug">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <h4>Sample 2 - Simple configuration using a File Appender</h4>
                <p>Log4j 1.x XML configuration</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
      <appender name="A1" class="org.apache.log4j.FileAppender">
        <param name="File"   value="A1.log" />
        <param name="Append" value="false" />
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
        </layout>
      </appender>
      <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <category name="org.apache.log4j.xml">
        <priority value="debug" />
        <appender-ref ref="A1" />
      </category>
      <root>
        <priority value ="debug" />
        <appender-ref ref="STDOUT" />
      </Root>
    </log4j:configuration>]]></pre>
    
               <p>Log4j 2 XML configuration</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
      <Appenders>
        <File name="A1" fileName="A1.log" append="false">
          <PatternLayout pattern="%t %-5p %c{2} - %m%n"/>
        </File>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="org.apache.log4j.xml" level="debug">
          <AppenderRef ref="A1"/>
        </Logger>
        <Root level="debug">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <h4>Sample 3 - SocketAppender</h4>
                <p>Log4j 1.x XML configuration. This example from Log4j 1.x is misleading. The SocketAppender does not
                  actually use a Layout. Configuring one will have no effect.</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
      <appender name="A1" class="org.apache.log4j.net.SocketAppender">
        <param name="RemoteHost" value="localhost"/>
        <param name="Port" value="5000"/>
        <param name="LocationInfo" value="true"/>
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%t %-5p %c{2} - %m%n"/>
        </layout>
      </appender>
      <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <category name="org.apache.log4j.xml">
        <priority value="debug"/>
        <appender-ref ref="A1"/>
      </category>
      <root>
        <priority value="debug"/>
        <appender-ref ref="STDOUT"/>
      </Root>
    </log4j:configuration>]]></pre>
    
               <p>Log4j 2 XML configuration</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration>
      <Appenders>
        <Socket name="A1" host="localHost" port="5000">
          <SerializedLayout/>
        </Socket>
        <Console name="STDOUT" target="SYSTEM_OUT">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
      </Appenders>
      <Loggers>
        <Logger name="org.apache.log4j.xml" level="debug">
          <AppenderRef ref="A1"/>
        </Logger>
        <Root level="debug">
          <AppenderRef ref="STDOUT"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
                <h4>Sample 4 - AsyncAppender</h4>
                <p>Log4j 1.x XML configuration using the AsyncAppender.</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
      <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <appender-ref ref="TEMP"/>
      </appender>
      <appender name="TEMP" class="org.apache.log4j.FileAppender">
        <param name="File" value="temp"/>
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <root>
        <priority value="debug"/>
        <appender-ref ref="ASYNC"/>
      </Root>
    </log4j:configuration>]]></pre>
    
               <p>Log4j 2 XML configuration. </p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="debug">
      <Appenders>
        <File name="TEMP" fileName="temp">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </File>
        <Async name="ASYNC">
          <AppenderRef ref="TEMP"/>
        </Async>
      </Appenders>
      <Loggers>
        <Root level="debug">
          <AppenderRef ref="ASYNC"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
    
    
                <h4>Sample 5 - AsyncAppender with Console and File</h4>
                <p>Log4j 1.x XML configuration using the AsyncAppender.</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE log4j:configuration PUBLIC "-//APACHE//DTD LOG4J 1.2//EN" "log4j.dtd">
    <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/" configDebug="true">
      <appender name="ASYNC" class="org.apache.log4j.AsyncAppender">
        <appender-ref ref="TEMP"/>
        <appender-ref ref="CONSOLE"/>
      </appender>
      <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <appender name="TEMP" class="org.apache.log4j.FileAppender">
        <param name="File" value="temp"/>
        <layout class="org.apache.log4j.PatternLayout">
          <param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </layout>
      </appender>
      <root>
        <priority value="debug"/>
        <appender-ref ref="ASYNC"/>
      </Root>
    </log4j:configuration>]]></pre>
    
                <p>Log4j 2 XML configuration. Note that the Async Appender should be configured after the appenders it
                  references. This will allow it to shutdown properly.</p>
                <pre class="prettyprint linenums"><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="debug">
      <Appenders>
        <Console name="CONSOLE" target="SYSTEM_OUT">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </Console>
        <File name="TEMP" fileName="temp">
          <PatternLayout pattern="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
        </File>
        <Async name="ASYNC">
          <AppenderRef ref="TEMP"/>
          <AppenderRef ref="CONSOLE"/>
        </Async>
      </Appenders>
      <Loggers>
        <Root level="debug">
          <AppenderRef ref="ASYNC"/>
        </Root>
      </Loggers>
    </Configuration>]]></pre>
              </subsection>
            </section>
        </body>
    </document>
    ������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/plugins.xml�������������������������������������������0000664�0000000�0000000�00000035256�12577562624�0023324�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Plugins</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="mattsicker@apache.org">Matt Sicker</author>
        </properties>
    
        <body>
          <section name="Plugins">
            <subsection name="Introduction">
              <a name="Introduction"/>
              <p>
                Log4j 1.x allowed for extension by requiring class attributes on most of the configuration
                declarations. In the case of some elements, notably the PatternLayout, the only way to add
                new pattern converters was to extend the PatternLayout class and add them via code. One of
                goals of Log4j 2 is to make extending it extremely easy through the use of plugins.
              </p>
              <p>
                In Log4j 2 a plugin is declared by adding a
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/Plugin.html">@Plugin</a>
                annotation to the class declaration. During initialization the
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html">Configuration</a>
                will invoke the
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/util/PluginManager.html">PluginManager</a>
                to load the built-in Log4j plugins as well as any custom plugins. The <code>PluginManager</code> locates
                plugins by looking in four places:
              </p>
              <ul>
                <li>Serialized plugin listing files on the classpath. These files are generated automatically during
                  the build (more details below).</li>
                <li>(OSGi only) Serialized plugin listing files in each active OSGi bundle. A <code>BundleListener</code>
                  is added on activation to continue checking new bundles after <code>log4j-core</code> has started.</li>
                <li>A comma-separated list of packages specified by the <code>log4j.plugin.packages</code>
                  system property.</li>
                <li>Packages passed to the static <code>PluginManager.addPackages</code> method (before Log4j configuration
                  occurs).</li>
                <li>The <a href="./configuration.html#ConfigurationSyntax">packages</a> declared in your log4j2
                  configuration file.</li>
              </ul>
              <p>
                If multiple Plugins specify the same (case-insensitive) <code>name</code>, then the load order above
                determines which one will be used. For example, to override the <code>File</code> plugin which is provided
                by the built-in <code>FileAppender</code> class, you would need to place your plugin in a JAR file in the
                CLASSPATH ahead of<code>log4j-core.jar</code>. This is not recommended; plugin name collisions will cause a
                warning to be emitted. Note that in an OSGi environment, the order that bundles are scanned for plugins
                generally follows the same order that bundles were installed into the framework. See
                <a class="javadoc" href="http://www.osgi.org/javadoc/r5/core/org/osgi/framework/BundleContext.html#getBundles()">getBundles()</a>
                and
                <a class="javadoc" href="http://www.osgi.org/javadoc/r5/core/org/osgi/framework/SynchronousBundleListener.html">SynchronousBundleListener</a>.
                In short, name collisions are even more unpredictable in an OSGi environment.
                <!--
                TODO: in future, plugins will be able to be annotated with @Order which can override priorities
                -->
              </p>
              <p>
                Serialized plugin listing files are generated by an annotation processor contained in the
                log4j-core artifact which will automatically scan your code for Log4j 2 plugins and output a metadata
                file in your processed classes. There is nothing extra that needs to be done to enable this; the Java
                compiler will automatically pick up the annotation processor on the class path unless you explicitly
                disable it. In that case, it would be important to add another compiler pass to your build process that
                only handles annotation processing using the Log4j 2 annotation processor class,
                <code>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</code>. To do this using
                Apache Maven, add the following execution to your <i>maven-compiler-plugin</i> (version 2.2 or higher)
                build plugin:
              </p>
              <pre class="prettyprint linenums"><![CDATA[
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-compiler-plugin</artifactId>
      <version>3.1</version>
      <executions>
        <execution>
          <id>log4j-plugin-processor</id>
          <goals>
            <goal>compile</goal>
          </goals>
          <phase>process-classes</phase>
          <configuration>
            <proc>only</proc>
            <annotationProcessors>
              <annotationProcessor>org.apache.logging.log4j.core.config.plugins.processor.PluginProcessor</annotationProcessor>
            </annotationProcessors>
          </configuration>
        </execution>
      </executions>
    </plugin>
              ]]></pre>
              <p>
                As the configuration is processed the appropriate plugins will be automatically configured and
                initialized.  Log4j 2 utilizes a few different categories of plugins which are described in the following
                sections.
              </p>
            </subsection>
            <subsection name="Core">
              <a name="Core"/>
              <p>
                Core plugins are those that are directly represented by an element in a configuration file, such as an
                Appender, Logger or Filter. Custom plugins that conform to the rules laid out in the next paragraph
                may simply be referenced in the configuration, provided they are appropriate configured to be
                loaded by the PluginManager.
              </p>
              <p>
                Every Core plugin must declare a static method that is marked with a PluginFactory annotation. To
                allow the Configuration to pass the correct parameters to the method, every
                parameter to the method must be annotated as one of the following attribute types. Each
                attribute or element annotation must include the name that must be present in the configuration
                in order to match the configuration item to its respective parameter.
              </p>
              <h4>Attribute Types</h4>
                <dl>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginAttribute.html">PluginAttribute</a></dt>
                  <dd>The parameter must be convertible from a String using a <a href="#TypeConverters">TypeConverter</a>.
                  Most built-in types are already supported, but custom <code>TypeConverter</code> plugins may also be
                  provided for more type support.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginElement.html">PluginElement</a></dt>
                  <dd>The parameter may represent a complex object that itself has parameters that can be configured.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginConfiguration.html">PluginConfiguration</a></dt>
                  <dd>The current <code>Configuration</code> object will be passed to the plugin as a parameter.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/PluginNode.html">PluginNode</a></dt>
                  <dd>The current <code>Node</code> being parsed will be passed to the plugin as a parameter.</dd>
                  <dt><a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/validation/constraints/Required.html">Required</a></dt>
                  <dd>While not strictly an attribute, this annotation can be added to any plugin factory parameter to
                  make it automatically validated as non-<code>null</code> and non-empty.</dd>
                </dl>
            </subsection>
            <subsection name="Converters">
              <a name="Converters"/>
              <p>
                Converters are used by
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html">PatternLayout</a>
                to render the elements identified by the conversion pattern. Every converter must specify its type as
                "Converter" on the Plugin attribute, have a static newInstance method that accepts an array of Strings as
                its only parameter and returns an instance of the Converter, and must have a ConverterKeys annotation
                present that contains the array of converter patterns that will cause the Converter to be selected.
                Converters that are meant to handle LogEvents must extend the LogEventPatternConverter class and
                must implement a format method that accepts a LogEvent and a StringBuilder as arguments. The Converter
                should append the result of its operation to the StringBuilder.
              </p>
              <p>
                A second type of Converter is the FileConverter - which must have "FileConverter" specified in the
                type attribute of the Plugin annotation. While similar to a LogEventPatternConverter, instead
                of a single format method these Converters will have two variations; one that takes an Object and
                one that takes an array of Objects instead of the LogEvent. Both append to the provided StringBuilder
                in the same fashion as a LogEventPatternConverter. These Converters are typically used by the
                RollingFileAppender to construct the name of the file to log to.
              </p>
              <p>
                If multiple Converters specify the same <code>ConverterKeys</code>, then the load order above determines
                which one will be used. For example, to override the <code>%date</code> converter which is provided by the
                built-in <code>DatePatternConverter</code> class, you would need to place your plugin in a JAR file in the
                CLASSPATH ahead of<code>log4j-core.jar</code>. This is not recommended; pattern ConverterKeys collisions
                will cause a warning to be emitted. Try to use unique ConverterKeys for your custom pattern converters.
              </p>
            </subsection>
            <subsection name="KeyProviders">
              <a name="KeyProviders"/>
              <p>
              Some components within Log4j may provide the ability to perform data encryption. These components require
              a secret key to perform the encryption. Applications may provide the key by creating a class that
              implements the
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/util/SecretKeyProvider.html">SecretKeyProvider</a>
              interface.
              </p>
            </subsection>
            <subsection name="Lookups">
              <a name="Lookups"/>
              <p>
                Lookups are perhaps the simplest plugins of all. They must declare their type as "Lookup" on the
                plugin annotation and must implement the
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a>
                interface. They will have two methods; a
                lookup method that accepts a String key and returns a String value and a second lookup method that
                accepts both a LogEvent and a String key and returns a String. Lookups may be referenced by
                specifying ${<var>name</var>:key} where <var>name</var> is the name specified in the Plugin annotation and
                key is the name of the item to locate.
              </p>
            </subsection>
            <subsection name="TypeConverters">
              <a name="TypeConverters"/>
              <p>
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/convert/TypeConverter.html">TypeConverter</a>s
                are a sort of meta-plugin used for converting strings into other types in a plugin factory method
                parameter. Other plugins can already be injected via the <code>@PluginElement</code> annotation; now, any
                type supported by the type conversion system can be used in a <code>@PluginAttribute</code> parameter.
                Conversion of enum types are supported on demand and do not require custom <code>TypeConverter</code>
                classes. A large number of built-in Java classes are already supported; see
                <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/config/plugins/convert/TypeConverters.html">TypeConverters</a>
                for a more exhaustive listing.
              </p>
              <p>
                Unlike other plugins, the plugin name of a <code>TypeConverter</code> is purely cosmetic. Appropriate
                type converters are looked up via the <code>Type</code> interface rather than via <code>Class&lt;?&gt;</code>
                objects only. Do note that <code>TypeConverter</code> plugins must have a default constructor.
              </p>
            </subsection>
          </section>
          <section name="Developer Notes">
            <a name="DeveloperNotes"/>
            <p>
              If a plugin class implements
              <a class="javadoc" href="http://docs.oracle.com/javase/6/docs/api/java/util/Collection.html">Collection</a> or
              <a class="javadoc" href="http://docs.oracle.com/javase/6/docs/api/java/util/Map.html">Map</a>, then no
              factory method is used. Instead, the class is instantiated using the default constructor, and all child
              configuration nodes are added to the <code>Collection</code> or <code>Map</code>.
            </p>
          </section>
        </body>
    </document>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/thread-context.xml������������������������������������0000664�0000000�0000000�00000017423�12577562624�0024570�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Thread Context</title>
            <author email="rgoers@apache.org">Ralph Goers</author>
            <author email="ggregory@apache.org">Gary Gregory</author>
        </properties>
    
        <body>
          <section name="Log4j 2 API">
            <subsection name="Thread Context">
              <h4>Introduction</h4>
              <p>Log4j introduced the concept of the Mapped Diagnostic Context or MDC. It has been documented and
                discussed in numerous places including
                <a href="http://veerasundar.com/blog/2009/10/log4j-mdc-mapped-diagnostic-context-what-and-why/">Log4j MDC: What and Why</a> and
                <a href="http://blog.f12.no/wp/2004/12/09/log4j-and-the-mapped-diagnostic-context/">Log4j and the Mapped Diagnostic Context</a>.
                In addition, Log4j 1.x provides support for a Nested Diagnostic Context or NDC. It too has been documented
                and discussed in various places such as
                <a href="http://lstierneyltd.com/blog/development/log4j-nested-diagnostic-contexts-ndc/">Log4j NDC</a>.
                SLF4J/Logback followed with its own implementation of the MDC, which is documented very well at
                <a href="http://logback.qos.ch/manual/mdc.html">Mapped Diagnostic Context</a>.
              </p>
              <p>Log4j 2 continues with the idea of the MDC and the NDC but merges them into a single Thread Context.
                The Thread Context Map is the equivalent of the MDC and the Thread Context Stack is the equivalent of the
                NDC. Although these are frequently used for purposes other than diagnosing problems, they are still
                frequently referred to as the MDC and NDC in Log4j 2 since they are already well known by those acronyms.
              </p>
              <h4>Fish Tagging</h4>
              <p>Most real-world systems have to deal with multiple clients simultaneously. In a typical multithreaded
                implementation of such a system, different threads will handle different clients. Logging is
                especially well suited to trace and debug complex distributed applications. A common approach to
                differentiate the logging output of one client from another is to instantiate a new separate logger for
                each client. This promotes the proliferation of loggers and increases the management overhead of logging.
              </p>
              <p>A lighter technique is to uniquely stamp each log request initiated from the same client interaction.
                Neil Harrison described this method in the book "Patterns for Logging Diagnostic Messages," in <em>Pattern
                Languages of Program Design 3</em>, edited by R. Martin, D.  Riehle, and F. Buschmann
                (Addison-Wesley, 1997). Just as a fish can be tagged and have its movement tracked, stamping log
                events with a common tag or set of data elements allows the complete flow of a transaction or a request
                to be tracked. We call this <i>Fish Tagging</i>.
              </p>
              <p>Log4j provides two mechanisms for performing Fish Tagging; the Thread Context Map and the Thread
                Context Stack. The Thread Context Map allows any number of items to be added and be identified
                using key/value pairs. The Thread Context Stack allows one or more items to be pushed on the
                Stack and then be identified by their order in the Stack or by the data itself. Since key/value
                pairs are more flexible, the Thread Context Map is recommended when data items may be added during
                the processing of the request or when there are more than one or two items.
              </p>
               <p>To uniquely stamp each request using the Thread Context Stack, the user pushes contextual information
                 on to the Stack.
               </p>
                <pre class="prettyprint linenums">
    ThreadContext.push(UUID.randomUUID().toString()); // Add the fishtag;
    
    logger.debug("Message 1");
    .
    .
    .
    logger.debug("Message 2");
    .
    .
    ThreadContext.pop();</pre>
              <p>
                The alternative to the Thread Context Stack is the Thread Context Map. In this case, attributes
                associated with the request being processed are adding at the beginning and removed at the end
                as follows:
              </p>
              <pre class="prettyprint linenums">
    ThreadContext.put("id", UUID.randomUUID().toString(); // Add the fishtag;
    ThreadContext.put("ipAddress", request.getRemoteAddr());
    ThreadContext.put("loginId", session.getAttribute("loginId"));
    ThreadContext.put("hostName", request.getServerName());
    .
    logger.debug("Message 1");
    .
    .
    logger.debug("Message 2");
    .
    .
    ThreadContext.clear();</pre>
              <p>The Stack and the Map are managed per thread and are based on
                <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/ThreadLocal.html">ThreadLocal</a>
                by default. The Map can be configured to use an
                <a href="http://docs.oracle.com/javase/6/docs/api/java/lang/InheritableThreadLocal.html">InheritableThreadLocal</a>
                by setting system property <tt>isThreadContextMapInheritable</tt> to <tt>"true"</tt>.
                When configured this way, the contents of the Map will be passed to child threads. However, as
                discussed in the
                <a href="http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/Executors.html#privilegedThreadFactory()">Executors</a>
                class and in other cases where thread pooling is utilized, the ThreadContext may not always be
                automatically passed to worker threads. In those cases the pooling mechanism should provide a means for
                doing so. The getContext() and cloneStack() methods can be used to obtain copies of the Map and Stack
                respectively.
              </p>
              <p>
                Note that all methods of the
                <a href="../log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html">ThreadContext</a>
                class are static.
              </p>
              <h4>Including the ThreadContext when writing logs</h4>
              <p>
                The <a href="../log4j-api/apidocs/org/apache/logging/log4j/core/PatternLayout.html">PatternLayout</a>
                provides mechanisms to print the contents of the
                <a href="../log4j-api/apidocs/org/apache/logging/log4j/ThreadContext.html">ThreadContext</a>
                Map and Stack.
              </p>
              <ul>
                <li>
                  Use <code>%X</code> by itself to include the full contents of the Map.
                </li>
                <li>
                  Use <code>%X{key}</code> to include the specified key.
                </li>
                <li>
                  Use <code>%x</code> to include the full contents of the <a href="http://docs.oracle.com/javase/6/docs/api/java/util/Stack.html">Stack</a>.
                </li>
              </ul>
            </subsection>
          </section>
        </body>
    </document>
    ���������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/manual/webapp.xml��������������������������������������������0000664�0000000�0000000�00000060771�12577562624�0023121�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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 Web Applications</title>
        <author email="nickwilliams@apache.org">Nick Williams</author>
        <author email="mattsicker@apache.org">Matt Sicker</author>
      </properties>
    
      <body>
        <section name="Using Log4j 2 in Web Applications">
          <p>
            You must take particular care when using Log4j or any other logging framework within a Java EE web application.
            It's important for logging resources to be properly cleaned up (database connections closed, files closed, etc.)
            when the container shuts down or the web application is undeployed. Because of the nature of class loaders
            within web applications, Log4j resources cannot be cleaned up through normal means. Log4j must be "started" when
            the web application deploys and "shut down" when the web application undeploys. How this works varies depending
            on whether your application is a <a href="#Servlet-3.0">Servlet 3.0 or newer</a> or
            <a href="#Servlet-2.5">Servlet 2.5</a> web application.
          </p>
          <p>
            In either case, you'll need to add the <code>log4j-web</code> module to your deployment as detailed in the
            <a href="../maven-artifacts.html">Maven, Ivy, and Gradle Artifacts</a> manual page.
          </p>
          <p class="big-red">
            <i class="icon-exclamation-sign"/>
            To avoid problems the Log4j shutdown hook will automatically be disabled when the log4j-web jar is included.
          </p>
          <a name="Configuration"/>
          <subsection name="Configuration">
            <p>
              Log4j allows the configuration file to be specified in web.xml using the <code>log4jConfiguration</code>
              context parameter. Log4j will search for configuration files by:
            </p>
            <ol>
              <li>
                If a location is provided it will be searched for as a servlet context resource. For example, if
                <code>log4jConfiguration</code> contains "logging.xml" then Log4j will look for a file with that
                name in the root directory of the web application.
              </li>
              <li>
                If no location is defined Log4j will search for a file that starts with "log4j2" in the WEB-INF directory.
                If more than one file is found, and if a file that starts with "log4j2-<var>name</var>" is present, where
                <var>name</var> is the name of the web application, then it will be used. Otherwise the first file will be
                used.
              </li>
              <li>
                The "normal" search sequence using the classpath and file URLs will be used to locate the configuration file.
              </li>
            </ol>
          </subsection>
          <subsection name="Servlet 3.0 and Newer Web Applications">
            <a name="Servlet-3.0" />
            <p>
              A Servlet 3.0 or newer web application is any <code>&lt;web-app&gt;</code> whose <code>version</code>
              attribute has a value of "3.0" or higher. Of course, the application must also be running in a compatible
              web container. Some examples are: Tomcat 7.0 and higher, GlassFish 3.0 and higher, JBoss 7.0 and higher,
              Oracle WebLogic 12c and higher, and IBM WebSphere 8.0 and higher.
            </p>
            <h4>The Short Story</h4>
            <p>
              Log4j 2 "just works" in Servlet 3.0 and newer web applications. It is capable of automatically starting when
              the application deploys and shutting down when the application undeploys. Thanks to the
              <a class="javadoc" href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContainerInitializer.html">ServletContainerInitializer</a>
              API added to Servlet 3.0, the relevant <code>Filter</code> and <code>ServletContextListener</code> classes
              can be registered dynamically on web application startup.
            </p>
            <p>
              <strong class="text-warning"><i class="icon-exclamation-sign"/> Important Note!</strong>
              For performance reasons, containers often ignore certain JARs known not to
              contain TLDs or <code>ServletContainerInitializer</code>s and do not scan them for web-fragments and
              initializers. Importantly, Tomcat 7 &lt;7.0.43 ignores all JAR files named log4j*.jar, which prevents this
              feature from working. This has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 &lt;7.0.43 you
              will need to change <code>catalina.properties</code> and remove "log4j*.jar" from the <code>jarsToSkip</code>
              property. You may need to do something similar on other containers if they skip scanning Log4j JAR files.
            </p>
            <h4>The Long Story</h4>
            <p>
              The Log4j 2 Web JAR file is a web-fragment configured to order before any other web fragments in your
              application. It contains a <code>ServletContainerInitializer</code>
              (<a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletContainerInitializer.html"
                >Log4jServletContainerInitializer</a>) that the container automatically discovers and initializes. This adds
              the <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html"
                >Log4jServletContextListener</a> and
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html"
                >Log4jServletFilter</a> to the <code>ServletContext</code>. These classes properly initialize
              and deinitialize the Log4j configuration.
            </p>
            <p>
              For some users, automatically starting Log4j is problematic or undesirable. You can easily disable this
              feature using the <code>isLog4jAutoInitializationDisabled</code> context parameter. Simply add it to your
              deployment descriptor with the value "true" to disable auto-initialization. You <em>must</em> define the
              context parameter in <code>web.xml</code>. If you set in programmatically, it will be too late for Log4j
              to detect the setting.
            </p>
              <pre class="prettyprint linenums"><![CDATA[    <context-param>
            <param-name>isLog4jAutoInitializationDisabled</param-name>
            <param-value>true</param-value>
        </context-param>]]></pre>
            <p>
              Once you disable auto-initialization, you must initialize Log4j as you would a
              <a href="#Servlet-2.5">Servlet 2.5 web application</a>. You must do so in a way that this initialization
              happens before any other application code (such as Spring Framework startup code) executes.
            </p>
            <p>
              You can customize the behavior of the listener and filter using the <code>log4jContextName</code>,
              <code>log4jConfiguration</code>, and/or <code>isLog4jContextSelectorNamed</code> context parameters. Read more
              about this in the <a href="#ContextParams">Context Parameters</a> section below. You <em>must not</em>
              manually configure the <code>Log4jServletContextListener</code> or <code>Log4jServletFilter</code> in your
              deployment descriptor (<code>web.xml</code>) or in another initializer or listener in a Servlet 3.0 or newer
              application <em>unless you disable auto-initialization</em> with
              <code>isLog4jAutoInitializationDisabled</code>. Doing so will result in startup errors and unspecified
              erroneous behavior.
            </p>
          </subsection>
          <subsection name="Servlet 2.5 Web Applications">
            <a name="Servlet-2.5" />
            <p>
              A Servlet 2.5 web application is any <code>&lt;web-app&gt;</code> whose <code>version</code> attribute has a
              value of "2.5." The <code>version</code> attribute is the only thing that matters; even if the web application
              is running in a Servlet 3.0 or newer container, it is a Servlet 2.5 web application if the
              <code>version</code> attribute is "2.5." Note that Log4j 2 does not support Servlet 2.4 and older web
              applications.
            </p>
            <p>
              If you are using Log4j in a Servlet 2.5 web application, or if you have disabled auto-initialization with
              the <code>isLog4jAutoInitializationDisabled</code> context parameter, you <em>must</em> configure the
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletContextListener.html"
                >Log4jServletContextListener</a> and
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jServletFilter.html"
                >Log4jServletFilter</a> in the deployment descriptor or programmatically. The filter should match all
              requests of any type. The listener should be the very first listener defined in your application, and the
              filter should be the very first filter defined and mapped in your application. This is easily accomplished
              using the following <code>web.xml</code> code:
            </p>
              <pre class="prettyprint linenums"><![CDATA[    <listener>
            <listener-class>org.apache.logging.log4j.web.Log4jServletContextListener</listener-class>
        </listener>
    
        <filter>
            <filter-name>log4jServletFilter</filter-name>
            <filter-class>org.apache.logging.log4j.web.Log4jServletFilter</filter-class>
        </filter>
        <filter-mapping>
            <filter-name>log4jServletFilter</filter-name>
            <url-pattern>/*</url-pattern>
            <dispatcher>REQUEST</dispatcher>
            <dispatcher>FORWARD</dispatcher>
            <dispatcher>INCLUDE</dispatcher>
            <dispatcher>ERROR</dispatcher>
            <dispatcher>ASYNC</dispatcher><!-- Servlet 3.0 w/ disabled auto-initialization only; not supported in 2.5 -->
        </filter-mapping>]]></pre>
            <p>
              You can customize the behavior of the listener and filter using the <code>log4jContextName</code>,
              <code>log4jConfiguration</code>, and/or <code>isLog4jContextSelectorNamed</code> context parameters. Read more
              about this in the <a href="#ContextParams">Context Parameters</a> section below.
            </p>
          </subsection>
          <subsection name="Context Parameters">
            <a name="ContextParams" />
            <p>
              By default, Log4j 2 uses the <code>ServletContext</code>'s
              <a href="http://docs.oracle.com/javaee/6/api/javax/servlet/ServletContext.html#getServletContextName()">context name</a>
              as the <code>LoggerContext</code> name and uses the standard pattern for locating the Log4j configuration
              file. There are three context parameters that you can use to control this behavior. The first,
              <code>isLog4jContextSelectorNamed</code>, specifies whether the context should be selected using the
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/core/selector/JndiContextSelector.html"
                >JndiContextSelector</a>. If <code>isLog4jContextSelectorNamed</code> is not specified or is anything other
              than <code>true</code>, it is assumed to be <code>false</code>.
            </p>
            <p>
              If <code>isLog4jContextSelectorNamed</code> is <code>true</code>, <code>log4jContextName</code> must be
              specified or <code>display-name</code> must be specified in <code>web.xml</code>; otherwise, the application
              will fail to start with an exception. <code>log4jConfiguration</code>
              <em>should</em> also be specified in this case, and must be a valid URI for the configuration file; however,
              this parameter is not required.
            </p>
            <p>
              If <code>isLog4jContextSelectorNamed</code> is not <code>true</code>, <code>log4jConfiguration</code> may
              optionally be specified and must be a valid URI or path to a configuration file or start with "classpath:" to
              denote a configuration file that can be found on the classpath. Without this parameter, Log4j will use the
              standard mechanisms for locating the configuration file.
            </p>
            <p>
              When specifying these context parameters, you must specify them in the deployment descriptor
              (<code>web.xml</code>) even in a Servlet 3.0 or never application. If you add them to the
              <code>ServletContext</code> within a listener, Log4j will initialize before the context parameters are
              available and they will have no effect. Here are some sample uses of these context parameters.
            </p>
            <h4>Set the Logging Context Name to "myApplication"</h4>
            <pre class="prettyprint linenums"><![CDATA[    <context-param>
            <param-name>log4jContextName</param-name>
            <param-value>myApplication</param-value>
        </context-param>]]></pre>
            <h4>Set the Configuration Path/File/URI to "/etc/myApp/myLogging.xml"</h4>
            <pre class="prettyprint linenums"><![CDATA[    <context-param>
            <param-name>log4jConfiguration</param-name>
            <param-value>file:///etc/myApp/myLogging.xml</param-value>
        </context-param>]]></pre>
            <h4>Use the <code>JndiContextSelector</code></h4>
            <pre class="prettyprint linenums"><![CDATA[    <context-param>
            <param-name>isLog4jContextSelectorNamed</param-name>
            <param-value>true</param-value>
        </context-param>
        <context-param>
            <param-name>log4jContextName</param-name>
            <param-value>appWithJndiSelector</param-value>
        </context-param>
        <context-param>
            <param-name>log4jConfiguration</param-name>
            <param-value>file:///D:/conf/myLogging.xml</param-value>
        </context-param>]]></pre>
            <p>
              Note that in this case you must also set the "Log4jContextSelector" system property to
              "<kbd>org.apache.logging.log4j.core.selector.JndiContextSelector</kbd>".
            </p>
          </subsection>
          <subsection name="Using Web Application Information During the Configuration">
            <a name="WebLookup" />
            <p>
              You may want to use information about the web application during configuration. For example, you could embed
              the web application's context path in the name of a Rolling File Appender. See WebLookup in
              <a href="./lookups.html#WebLookup">Lookups</a> for more information.
            </p>
          </subsection>
          <subsection name="JavaServer Pages Logging">
            <a name="JspLogging" />
            <p>
              You may use Log4j 2 within JSPs just as you would within any other Java code. Simple obtain a
              <code>Logger</code> and call its methods to log events. However, this requires you to use Java code within
              your JSPs, and some development teams rightly are not comfortable with doing this. If you have a dedicated
              user interface development team that is not familiar with using Java, you may even have Java code disabled in
              your JSPs.
            </p>
            <p>
              For this reason, Log4j 2 provides a JSP Tag Library that enables you to log events without using any Java
              code. To read more about using this tag library, <a href="../log4j-taglib/index.html">read the Log4j Tag
              Library documentation.</a>
            </p>
            <p>
              <strong class="text-warning"><i class="icon-exclamation-sign"/> Important Note!</strong>
              As noted above, containers often ignore certain JARs known not to
              contain TLDs and do not scan them for TLD files. Importantly, Tomcat 7 &lt;7.0.43 ignores all JAR files named
              log4j*.jar, which prevents the JSP tag library from being automatically discovered. This does not affect
              Tomcat 6.x and has been fixed in Tomcat 7.0.43, Tomcat 8, and later. In Tomcat 7 &lt;7.0.43 you
              will need to change <code>catalina.properties</code> and remove "log4j*.jar" from the <code>jarsToSkip</code>
              property. You may need to do something similar on other containers if they skip scanning Log4j JAR files.
            </p>
          </subsection>
          <subsection name="Asynchronous Requests and Threads">
            <a name="Async" />
            <p>
              The handling of asynchronous requests is tricky, and regardless of Servlet container version or configuration
              Log4j cannot handle everything automatically. When standard requests, forwards, includes, and error resources
              are processed, the <code>Log4jServletFilter</code> binds the <code>LoggerContext</code> to the thread handling
              the request. After request processing completes, the filter unbinds the <code>LoggerContext</code> from the
              thread.
            </p>
            <p>
              Similarly, when an internal request is dispatched using a <code>javax.servlet.AsyncContext</code>, the
              <code>Log4jServletFilter</code> also binds the <code>LoggerContext</code> to the thread handling the request
              and unbinds it when request processing completes. However, this only happens for requests <em>dispatched</em>
              through the <code>AsyncContext</code>. There are other asynchronous activities that can take place other than
              internal dispatched requests.
            </p>
            <p>
              For example, after starting an <code>AsyncContext</code> you could start up a separate thread to process the
              request in the background, possibly writing the response with the <code>ServletOutputStream</code>. Filters
              cannot intercept the execution of this thread. Filters also cannot intercept threads that you start in
              the background during non-asynchronous requests. This is true whether you use a brand new thread or a thread
              borrowed from a thread pool. So what can you do for these special threads?
            </p>
            <p>
              You may not need to do anything. If you didn't use the <code>isLog4jContextSelectorNamed</code> context
              parameter, there is no need to bind the <code>LoggerContext</code> to the thread. Log4j can safely locate the
              <code>LoggerContext</code> on its own. In these cases, the filter provides only very modest performance
              gains, and only when creating new <code>Logger</code>s. However, if you <em>did</em> specify the
              <code>isLog4jContextSelectorNamed</code> context parameter with the value "true", you will need to manually
              bind the <code>LoggerContext</code> to asynchronous threads. Otherwise, Log4j will not be able to locate it.
            </p>
            <p>
              Thankfully, Log4j provides a simple mechanism for binding the <code>LoggerContext</code> to asynchronous
              threads in these special circumstances. The simplest way to do this is to wrap the <code>Runnable</code>
              instance that is passed to the <code>AsyncContext.start()</code> method.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
    import java.io.IOException;
    import javax.servlet.AsyncContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.web.WebLoggerContextUtils;
    
    public class TestAsyncServlet extends HttpServlet {
    
        @Override
        protected void doGet(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
            final AsyncContext asyncContext = req.startAsync();
            asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), new Runnable() {
                @Override
                public void run() {
                    final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
                    logger.info("Hello, servlet!");
                }
            }));
        }
    
        @Override
        protected void doPost(final HttpServletRequest req, final HttpServletResponse resp) throws ServletException, IOException {
            final AsyncContext asyncContext = req.startAsync();
            asyncContext.start(new Runnable() {
                @Override
                public void run() {
                    final Log4jWebSupport webSupport =
                        WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
                    webSupport.setLoggerContext();
                    // do stuff
                    webSupport.clearLoggerContext();
                }
            });
        }
    }
            ]]></pre>
            <p>
              This can be slightly more convenient when using Java 1.8 and lambda functions as demonstrated below.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
    import java.io.IOException;
    import javax.servlet.AsyncContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.web.WebLoggerContextUtils;
    
    public class TestAsyncServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
            final AsyncContext asyncContext = req.startAsync();
            asyncContext.start(WebLoggerContextUtils.wrapExecutionContext(this.getServletContext(), () -> {
                final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
                logger.info("Hello, servlet!");
            }));
        }
    }
            ]]></pre>
            <p>
              Alternatively, you can obtain the
              <a class="javadoc" href="../log4j-core/apidocs/org/apache/logging/log4j/web/Log4jWebLifeCycle.html">Log4jWebLifeCycle</a>
              instance from the <code>ServletContext</code> attributes, call its <code>setLoggerContext</code> method as
              the very first line of code in your asynchronous thread, and call its <code>clearLoggerContext</code> method
              as the very last line of code in your asynchronous thread. The following code demonstrates this. It uses the
              container thread pool to execute asynchronous request processing, passing an anonymous inner
              <code>Runnable</code> to the <code>start</code> method.
            </p>
            <pre class="prettyprint linenums"><![CDATA[
    import java.io.IOException;
    import javax.servlet.AsyncContext;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    import org.apache.logging.log4j.web.Log4jWebLifeCycle;
    import org.apache.logging.log4j.web.WebLoggerContextUtils;
    
    public class TestAsyncServlet extends HttpServlet {
        @Override
        protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
             final AsyncContext asyncContext = req.startAsync();
            asyncContext.start(new Runnable() {
                @Override
                public void run() {
                    final Log4jWebLifeCycle webLifeCycle =
                        WebLoggerContextUtils.getWebLifeCycle(TestAsyncServlet.this.getServletContext());
                    webLifeCycle.setLoggerContext();
                    try {
                        final Logger logger = LogManager.getLogger(TestAsyncServlet.class);
                        logger.info("Hello, servlet!");
                    } finally {
                        webLifeCycle.clearLoggerContext();
                    }
                }
            });
       }
    }
            ]]></pre>
            <p>
              Note that you <em>must</em> call <code>clearLoggerContext</code> once your thread is finished
              processing. Failing to do so will result in memory leaks. If using a thread pool, it can even disrupt the
              logging of other web applications in your container. For that reason, the example here shows clearing the
              context in a <code>finally</code> block, which will always execute.
            </p>
          </subsection>
        </section>
      </body>
    
    </document>
    �������logging-log4j2-log4j-2.4/src/site/xdoc/maven-artifacts.xml.vm���������������������������������������0000664�0000000�0000000�00000034505�12577562624�0024067�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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>Maven, Ivy, and Gradle Artifacts</title>
      </properties>
    
      <body>
        <section name="Maven, Ivy, and Gradle Artifacts">
          <p>
            Log4j 2 is broken up in an API and an implementation (core), where the API
            provides the interface that applications should code to.
            Strictly speaking Log4j core is only needed at runtime and not at compile time.
          </p><p>
            However, below we list Log4j core as a compile time dependency
            to improve the startup time for <a href="manual/plugins.html">custom plugins</a>.
          </p>
    
          <subsection name="Using Log4j in your Apache Maven build">
            <p>
              To build with <a href="http://maven.apache.org/">Apache Maven</a>, add the dependencies listed below to your
              <code>pom.xml</code> file.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-api</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-core</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
          </subsection>
          <subsection name="Using Log4j in your Apache Ivy build">
            <p>
              To build with <a href="https://ant.apache.org/ivy/">Apache Ivy</a>, add the dependencies listed below to your
              <code>ivy.xml</code> file.
            </p>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-api" rev="${Log4jReleaseVersion}" />
      <dependency org="org.apache.logging.log4j" name="log4j-core" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
          </subsection>
          <subsection name="Using Log4j in your Gradle build">
            <p>
              To build with <a href="http://www.gradle.org/">Gradle</a>, add the dependencies listed below to your
              <code>build.gradle</code> file.
            </p>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-api', version: '${Log4jReleaseVersion}'
      compile group: 'org.apache.logging.log4j', name: 'log4j-core', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
          </subsection>
          <subsection name="Bill of Material">
            <p>
              To keep your Log4j module versions in sync with each other, a
              <abbr id="Bill of Material">BOM</abbr>
              pom.xml file is provided for your convenience. To use this with
              <a href="http://maven.apache.org/">Maven</a>, add the dependency listed below to your
              <code>pom.xml</code>
              file. When you specify the version identifier in this section, you don't have to specify the version in your
              <code><![CDATA[<dependencies/>]]></code>
              section.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencyManagement>
      <dependencies>
        <dependency>
          <groupId>org.apache.logging.log4j</groupId>
          <artifactId>log4j-bom</artifactId>
          <version>${Log4jReleaseVersion}</version>
          <scope>import</scope>
          <type>pom</type>
        </dependency>
      </dependencies>
    </dependencyManagement>
    ]]></pre>
          </subsection>
          <subsection name="Optional Components">
            <p>
              Log4j 2.x contains several optional components that can be included in an application.
            </p>
            <h4>Log4j 1.x API Bridge</h4>
            <p>If existing components use Log4j 1.x and you want to have this logging routed to Log4j 2,
              then remove any log4j 1.x dependencies and add the following.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-1.2-api</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-1.2-api" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-1.2-api', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>Apache Commons Logging Bridge</h4>
            <p>If existing components use Apache Commons Logging 1.x and you want to have this logging routed to Log4j 2,
              then add the following but do not remove any Commons Logging 1.x dependencies.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jcl</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-jcl" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-jcl', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>SLF4J Bridge</h4>
            <p>If existing components use SLF4J and you want to have this logging routed to Log4j 2, then add the
              following but do not remove any SLF4J dependencies.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-slf4j-impl</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-slf4j-impl" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>JUL Adapter</h4>
            <p>If existing components use Java Util Logging and you want to have this logging routed to Log4j 2,
            then add the following.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-jul</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-jul" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
              <h4>Web Servlet Support</h4>
              <p>
                In order to properly support and handle the ClassLoader environment and container lifecycle of a web
                application, an additional module is required. This module is only required at runtime. In addition, if
                you're using servlets in an OSGi environment, make sure your preferred version of the servlet API is
                already available (e.g., if you want to use 3.0, but you've also got 2.5 loaded, make sure both are
                loaded).
              </p>
              <code>pom.xml</code>
              <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-web</artifactId>
        <version>${Log4jReleaseVersion}</version>
        <scope>runtime</scope>
      </dependency>
    </dependencies>
              ]]></pre>
              <code>ivy.xml</code>
              <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-web" rev="${Log4jReleaseVersion}" />
    </dependencies>
              ]]></pre>
              <code>build.gradle</code>
              <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-web', version: '${Log4jReleaseVersion}'
    }
              ]]></pre>
            <h4>Tag Library</h4>
            <p>The Log4j Log Tag Library creates the capability of inserting log statements in JSPs without
              the use of Java scripting. It uses the standard Log4j 2 API to log messages according to
              your Log4j configuration.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-taglib</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-taglib" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-taglib', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>Apache Flume Appender</h4>
            <p>The Flume Appender allows applications to send events to Flume Agents.</p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-flume-ng</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-flume-ng" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-flume-ng', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>Log4j to SLF4J Adapter</h4>
            <p>The Log4j 2 to SLF4J Adapter allows applications coded to the Log4j 2 API to be routed to SLF4J. Use of this
              adapter may cause some loss of performance as the Log4j 2 Messages must be formatted before they can be passed
              to SLF4J. The SLF4J Bridge must NOT be on the class path when this is in use.</p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-to-slf4j</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-to-slf4j" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-to-slf4j', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>NoSQL Appenders</h4>
            <p>If your configuration uses one of the NoSQL Appenders, then add the following.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-nosql</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-nosql" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-nosql', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
            <h4>IO Streams</h4>
            <p>Log4j IO Streams allow applications to have data that is written to an OutputStream
              or a Writer be redirected to a Logger, or have data that is read from an InputStream or
              a Reader be wiretapped by a Logger.
              To use IO Streams, add the following.
            </p>
            <code>pom.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency>
        <groupId>org.apache.logging.log4j</groupId>
        <artifactId>log4j-iostreams</artifactId>
        <version>${Log4jReleaseVersion}</version>
      </dependency>
    </dependencies>
    ]]></pre>
            <code>ivy.xml</code>
            <pre class="prettyprint linenums"><![CDATA[
    <dependencies>
      <dependency org="org.apache.logging.log4j" name="log4j-iostreams" rev="${Log4jReleaseVersion}" />
    </dependencies>
    ]]></pre>
            <code>build.gradle</code>
            <pre class="prettyprint linenums"><![CDATA[
    dependencies {
      compile group: 'org.apache.logging.log4j', name: 'log4j-iostreams', version: '${Log4jReleaseVersion}'
    }
    ]]></pre>
          </subsection>
        </section>
      </body>
    </document>
    �������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/performance.xml����������������������������������������������0000664�0000000�0000000�00000030234�12577562624�0022656�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?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>Performance</title>
        <author email="rgoers@apache.org">Ralph Goers</author>
      </properties>
    
      <body>
        <section name="Performance">
          <p>One of the often-cited arguments against logging is its
            computational cost. This is a legitimate concern as even moderately
            sized applications can generate thousands of log requests. Much
            effort was spent measuring and tweaking logging performance. Log4j
            claims to be fast and flexible: speed first, flexibility second.
          </p>
          <p>The user should be aware of the following performance issues.</p>
          <ol>
            <li>
              <h3>Logging performance when logging is turned off.</h3>
              <p>When logging is turned off entirely or just for a set of Levels, the cost of a log request consists of
                two method invocations plus an integer comparison. On a 2.53 GHz Intel Core 2 Duo MacBook Pro
                calling isDebugEnabled 10 million times produces an average result in nanoseconds of:</p>
                <pre>
                Log4j: 4
                Logback: 5
                Log4j 2: 3
                </pre>
              <p>
                The numbers above will vary slightly from run to run so the only conclusion that should be
                drawn is that all 3 frameworks perform similarly on this task.
              </p>
              <p>However, The method invocation involves the "hidden" cost of parameter construction.
              </p>
              <p>For example,
              </p>
                <pre>
                  logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
                </pre>
              <p>
                incurs the cost of constructing the message parameter, i.e. converting both integer
                <code>i</code> and <code>entry[i]</code> to a String, and concatenating intermediate strings,
                regardless of whether the message will be logged or not.
    
                This cost of parameter construction can be quite high and it
                depends on the size of the parameters involved.
    
                A comparison run on the same hardware as above yields:
              </p>
                <pre>
                Log4j: 188
                Logback: 183
                Log4j 2: 188
                </pre>
              <p>
                Again, no conclusion should be drawn regarding relative differences between the frameworks on
                this task, but it should be obvious that it is considerably more expensive than simply testing
                the level.
              </p>
              <p>
                The best approach to avoid the cost of parameter construction is to use Log4j 2's formatting
                capabilities. For example, instead of the above write:
              </p>
                <pre>
                logger.debug("Entry number: {} is {}", i, entry[i]);
                </pre>
              <p>
                Using this approach, a comparison run again on the same hardware produces:
              </p>
                <pre>
                Log4j: Not supported
                Logback: 9
                Log4j 2: 4
                </pre>
              <p>
                These results show that the difference in performance between the call to isDebugEnabled and
                logger.debug is barely discernible.
              </p>
              <p>In some circumstances one of the parameters to logger.debug will be a costly method call that
                should be avoided if debugging is disabled. In those cases write:
              </p>
                <pre>
                if(logger.isDebugEnabled() {
                    logger.debug("Entry number: " + i + " is " + entry[i].toString());
                }
                </pre>
              <p>This will not incur the cost of whatever the toString() method needs to do if debugging is disabled.
                On the other hand, if the logger is enabled for the debug level, it will incur twice the cost of
                evaluating whether the logger is enabled or not: once
                in <code>isDebugEnabled</code> and once in <code>debug</code>. This is an insignificant
                overhead because evaluating a logger takes about 1% of the time it takes to actually log.
              </p>
              <p>Certain users resort to pre-processing or compile-time
                techniques to compile out all log statements. This leads to perfect
                performance efficiency with respect to logging. However, since the
                resulting application binary does not contain any log statements,
                logging cannot be turned on for that binary. This seems to be
                a disproportionate price to pay in exchange for a small performance
                gain.
              </p>
            </li>
            <li>
              <h3>The performance of deciding whether to log or not to log when logging is turned on.</h3>
              <p>
                Unlike Log4j, Log4j 2 Loggers don't "walk a hierarchy". Loggers point directly to the
                Logger configuration that best matches the Logger's name. This incurs extra overhead when the Logger
                is first created but reduces the overhead every time the Logger is used.
              </p>
            </li>
            <li>
              <h3>Actually outputting log messages</h3>
              <p>This is the cost of formatting the log output and sending it to its target destination. Here again,
                a serious effort was made to make layouts (formatters) perform as quickly as possible. The same
                is true for appenders. One of the fundamental tenets of Log4j 2 is to use immutable objects whenever
                possible and to lock at the lowest granularity possible. However, the cost of actually formatting and
                delivering log events will never be insignificant. For example, the results of writing to a simple log
                file using the same format using Log4j, Logback and Log4j 2 are:
              </p>
              <pre>
                  Log4j: 1651
                  Logback: 1419
                  Log4j 2.0: 1542
              </pre>
              <p>
                As with many of the other results on this page the differences between the frameworks above should be
                considered insignificant. The values will change somewhat on each execution and changing the order the
                frameworks are tested or adding calls to System.gc() between the tests can cause a variation in the
                reported times. However, these results show that actually writing out the events can be at least 1000
                times more expensive than when they are disabled, so it is always recommended to take advantage of
                Log4j 2's fine-grained filtering capabilities.
              </p>
            </li>
            <li>
              <h3>Advanced Filtering</h3>
              <p>
                Both Logback and Log4j 2 support advanced filtering. Logback calls them TurboFilters while
                Log4j 2 has a single Filter object. Advanced filtering provides the capability to filter
                LogEvents using more than just the Level before the events are passed to Appenders.
                However, this flexibility does come with some cost. Since multi-threading can also have an impact on the
                performance of advanced filtering, the table below shows the difference in performance in two different
                sets of context-wide filters running on the same hardware as the previous tests using
                various numbers of threads.
              </p>
              <table>
                <tr>
                  <th>Test</th>
                  <th>1 thread</th>
                  <th>2 threads</th>
                  <th>5 threads</th>
                  <th>10 threads</th>
                  <th>20 threads</th>
                  <th>50 threads</th>
                </tr>
                <tr>
                  <td>Logback MDCFilter</td>
                  <td>37</td>
                  <td>50</td>
                  <td>145</td>
                  <td>316</td>
                  <td>606</td>
                  <td>1670</td>
                </tr>
                <tr>
                  <td>Log4j 2 ThreadContextMapFilter</td>
                  <td>30</td>
                  <td>35</td>
                  <td>85</td>
                  <td>165</td>
                  <td>341</td>
                  <td>864</td>
                </tr>
                <tr>
                  <td>Logback MarkerFilter</td>
                  <td>17</td>
                  <td>24</td>
                  <td>59</td>
                  <td>115</td>
                  <td>234</td>
                  <td>547</td>
                </tr>
                 <tr>
                  <td>Log4j 2 MarkerFilter</td>
                  <td>4</td>
                  <td>5</td>
                  <td>7</td>
                  <td>20</td>
                  <td>35</td>
                  <td>92</td>
                </tr>
              </table>
            </li>
            <li>
              <h3>Client vs Server</h3>
              <p>
                Java supports a "client" and a "server" mode of operation. By default, applications that are
                run in Java 5 on machines with 2 CPUs or more and 2GB of memory or more on operating systems
                other than Windows or are run in a 64-bit JVM are automatically configured to run in "server" mode.
                Testing has shown that Log4j 2 benefits greatly from running in server mode and user's are
                strongly encouraged to configure their applications to run in server mode when using Log4j 2.
              </p>
            </li>
    		<li>
    		<h3>Asynchronous Logging Performance Improvements</h3>
    		<p>
    		Log4j 2 offers Asynchronous Loggers for high throughput and low latency logging.
    		Asynchronous Loggers are implemented using the
    		<a href="http://lmax-exchange.github.com/disruptor/">LMAX Disruptor</a>
    		inter-thread messaging library instead of the ArrayBlockingQueue used by Asynchronous Appenders.
    		</p><p>
    		Asynchronous Appenders already offered about 5 - 10 times more throughput than
    		synchronous loggers, but this advantage remained more or less constant
    		when more threads are logging. That is, if you double the number of threads
    		that are logging you would expect your total throughput to increase, but
    		this is not the case: the throughput per thread is roughly halved so your
    		total throughput remains more or less the same.
    		(Note that this happens even if the appender queue size is large enough to hold
    		all messages logged during the test, so this is not caused by disk I/O.)
    		</p><p>
    		Asynchronous Loggers have significantly higher throughput than the legacy Asynchronous Appenders,
    		especially in multi-threaded scenarios. In one test with 64 threads,
    		Asynchronous Loggers were 12 times faster than the fastest Asynchronous Appender,
    		and 68 times faster than the fastest synchronous logger.
    		In addition to throughput, Asynchronous Loggers have attractive latency characteristics.
    		Not only is average latency lower compared to Asynchronous Appenders,
    		but when increasing the number of application threads that do logging,
    		worst-case latency remained almost constant (10 - 20 microseconds)
    		where Asynchronous Appenders start experiencing worst-case
    		latency spikes in the 100 millisecond range, a difference of four orders of magnitude.
    		See <a href="manual/async.html#Performance">Asynchronous Logging Performance</a> for details.
    		</p>
    		</li>
          </ol>
          <p>
            The performance results above were all derived from running the DebugDisabledPerformanceComparison,
            FilterPerformanceComparison, and PerformanceComparison junit tests which can be found in the
            Log4j 2 unit test source directory.
          </p>
        </section>
      </body>
    </document>
    ��������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������logging-log4j2-log4j-2.4/src/site/xdoc/runtime-dependencies.xml�������������������������������������0000664�0000000�0000000�00000022357�12577562624�0024473�0����������������������������������������������������������������������������������������������������ustar�00root����������������������������root����������������������������0000000�0000000������������������������������������������������������������������������������������������������������������������������������������������������������������������������<?xml version="1.0" encoding="UTF-8"?>
    <!--
     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 Runtime Dependencies</title>
      </properties>
    
      <body>
        <section name="Log4j Runtime Dependencies">
          <p>
            Some Log4J features depend on external libraries. This page lists the required and optional
            dependencies.
          </p>
          <p>
            As of version 2.4, Log4J requires Java 7. Versions 2.3 and earlier require Java 6.
          </p>
    
          <a name="log4j-api" />
          <h4>log4j-api</h4>
          <p>
            The Log4J <a href="log4j-api/index.html">API</a> module has no external dependencies.
          </p>
    
          <a name="log4j-core" />
          <h4>log4j-core</h4>
          <p>
            The Log4J <a href="log4j-core/index.html">Implementation</a> has several optional
            <a href="log4j-core/dependencies.html">dependencies</a>.
            See the <a href="log4j-core/dependencies.html#Dependency_Tree">Dependency Tree</a> for the
            exact list of JAR files needed for these features.
          </p>
          <table>
            <caption align="top">Optional Dependencies per Feature in Log4J Implementation</caption>
            <tr>
              <th>Feature</th>
              <th>Requirements</th>
            </tr>
            <tr>
              <td>CSV Layout</td>
              <td><a href="https://commons.apache.org/proper/commons-csv/">Apache Commons CSV</a></td>
            </tr>        
            <tr>
              <td>XML configuration</td>
              <td>-</td>
            </tr>
            <tr>
              <td>JSON configuration</td>
              <td><a href="https://github.com/FasterXML/jackson">Jackson Data Processor</a></td>
            </tr>
            <tr>
              <td>YAML configuration</td>
              <td><a href="https://github.com/FasterXML/jackson-dataformat-yaml">Jackson YAML data format</a></td>
            </tr>
            <tr>
              <td>Async Loggers</td>
              <td><a href="http://lmax-exchange.github.io/disruptor/">LMAX Disruptor</a></td>
            </tr>
            <tr>
              <td>SMTP Appender</td>
              <td>an implementation of <code>javax.mail</code></td>
            </tr>
            <tr>
              <td>JMS Appender</td>
              <td>a JMS broker like <a href="http://activemq.apache.org/">Apache ActiveMQ</a></td>
            </tr>
            <tr>
              <td>Windows color support</td>
              <td><a href="http://jansi.fusesource.org/">Jansi</a></td>
            </tr>
            <tr>
              <td>JDBC Appender</td>
              <td>a JDBC driver for the database you choose to write events to</td>
            </tr>
            <tr>
              <td>JPA Appender</td>
              <td>the Java Persistence API classes, a JPA provider implementation, and a decorated
                entity that the user implements. It also requires an appropriate JDBC driver
              </td>
            </tr>
            <tr>
              <td>bzip2, Deflate, Pack200, and XZ compression on rollover</td>
              <td><a href="http://commons.apache.org/proper/commons-compress/">Apache Commons Compress</a>.
                In addition, XZ requires <a href="http://tukaani.org/xz/java.html">XZ for Java</a>.
              </td>
            </tr>
            <tr>
              <td>ZeroMQ Appender</td>
              <td>
                The ZeroMQ appender uses the <a href="https://github.com/zeromq/jeromq">JeroMQ</a> library which is 
                licensed under the terms of the GNU Lesser General Public License (LGPL). For details see the 
                files <code>COPYING</code> and <code>COPYING.LESSER</code> included with the JeroMQ distribution.  
              </td>
            </tr>
          </table>
    
          <a name="log4j-jcl" />
          <h4>log4j-jcl</h4>
          <p>
            The <a href="log4j-jcl/index.html">Commons Logging Bridge</a> requires
            <a href="http://commons.apache.org/proper/commons-logging/">Commons Logging</a>. See the
            <a href="log4j-jcl/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact
            list of JAR files needed.
          </p>
    
          <a name="log4j-1.2-api" />
          <h4>log4j-1.2-api</h4>
          <p>
            The <a href="log4j-1.2-api/index.html">Log4j 1.2 Bridge</a> has no external dependencies.
            This only requires the Log4j API and Log4j Core.
          </p>
    
          <a name="log4j-slf4j-impl" />
          <h4>log4j-slf4j-impl</h4>
          <p>
            The Log4j 2 <a href="log4j-slf4j-impl/index.html">SLF4J Binding</a> depends on the
            <a href="http://www.slf4j.org/">SLF4J</a> API. See the
            <a href="log4j-slf4j-impl/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact
            list of JAR files needed.
          </p>
          <p class="text-warning">
            <i class="icon-exclamation-sign"/>
            Do not use this with the <a href="#log4j-to-slf4j">log4j-to-slf4j</a> module.
          </p>
    
          <a name="log4j-jul" />
          <h4>log4j-jul</h4>
          <p>
            The Log4j 2 <a href="log4j-jul/index.html">Java Util Logging Adapter</a> has no external dependencies.
            It optionally depends on the <a href="log4j-api/index.html">Log4j Core</a> library. The only required module
            is the Log4j API.
          </p>
    
          <a name="log4j-to-slf4j" />
          <h4>log4j-to-slf4j</h4>
          <p>
            The <a href="log4j-to-slf4j/index.html">Log4j 2 to SLF4J Adapter</a> requires the
            <a href="http://www.slf4j.org/">SLF4J</a> API and an SLF4J implementation. See the
            <a href="log4j-to-slf4j/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact list of JAR files needed.
          </p>
          <p class="text-warning">
            <i class="icon-exclamation-sign"/>
            Do not use this with the <a href="#log4j-slf4j-impl">log4j-slf4j-impl</a> module.
          </p>
    
          <a name="log4j-flume-ng" />
          <h4>log4j-flume-ng</h4>
          <p>
            The <a href="log4j-flume-ng/index.html">Flume Appender</a> requires
            <a href="http://flume.apache.org/">Apache Flume</a> and <a href="http://avro.apache.org/">Apache Avro</a>.
            The persistent agent uses Berkeley DB. See the
            <a href="log4j-flume-ng/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact list of JAR files needed.
          </p>
    
          <a name="log4j-taglib" />
          <h4>log4j-taglib</h4>
          <p>
            The Log4j <a href="log4j-taglib/index.html">Log Tag Library</a> requires the
            <a href="http://jakarta.apache.org/taglibs/log/">Jakarta Commons Log Taglib</a> and the Servlet API. See the
            <a href="log4j-taglib/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact list of JAR files needed.
          </p>
    
          <a name="log4j-jmx-gui" />
          <h4>log4j-jmx-gui</h4>
          <p>
            The Log4j <a href="log4j-jmx-gui/index.html">JMX GUI</a> requires the JConsole jar when run as a JConsole plugin.
            Otherwise it has no external dependencies. See the
            <a href="log4j-jmx-gui/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact list of JAR files needed.
          </p>
    
          <a name="log4j-web" />
          <h4>log4j-web</h4>
          <p>
            The Log4j <a href="log4j-web/index.html">Web</a> module requires the Servlet API. See the
            <a href="log4j-web/dependencies.html#Dependency_Tree">Dependency Tree</a> for the exact list of JAR files needed.
            Note that this works with the Servlet 2.5 API as well as the Servlet 3.x API.
          </p>
    
          <a name="log4j-nosql" />
          <h4>log4j-nosql</h4>
          <p>
            The Log4J <a href="log4j-nosql/index.html">NoSQL Appenders</a> module has several optional
            <a href="log4j-nosql/dependencies.html">dependencies</a>.
            See the <a href="log4j-nosql/dependencies.html#Dependency_Tree">Dependency Tree</a> for the
            exact list of JAR files needed for these features.
          </p>
          <table>
            <caption align="top">Optional Dependencies per Feature in Log4J NoSQL Appenders</caption>
            <tr>
              <td>NoSQL Appender with <a href="http://www.mongodb.org/">MongoDB</a> provider</td>
              <td>the <a href="http://docs.mongodb.org/ecosystem/drivers/java/">MongoDB Java Client driver</a></td>
            </tr>
            <tr>
              <td>NoSQL Appender with <a href="https://couchdb.apache.org/">Apache CouchDB</a> provider</td>
              <td>the <a href="http://www.lightcouch.org/">LightCouch</a> CouchDB client library</td>
            </tr>
          </table>
    
          <a name="log4j-iostreams" />
          <h4>log4j-iostreams</h4>
          <p>
            The Log4j <a href="log4j-iostreams/index.html">IO Streams</a> module has no external dependencies.
            This only requires the Log4j API.
          </p>
    
        </section>
      </body>
    </document>
    �����������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������������