| <?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 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.0 Class Relationships" |
| caption="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 longers 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> |
| |
| <p> |
| <table bgcolor="#EEEE99"> |
| <tr> |
| <td> |
| <dl> |
| <dt> |
| <b>Named Hierarchy</b> |
| </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> |
| </td> |
| </tr> |
| </table> |
| </p> |
| <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: |
| <source>Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);</source> |
| All other Loggers can be retrieved using the |
| <a href="../log4j2-api/apidocs/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.String)"> |
| LogManager.getLogger |
| </a> |
| static method and passing the name of the desired Logger. Further informaiton on the Logging |
| API can be found at<a href="../log4j2-api/api.html">Log4j 2 API</a>. |
| </p> |
| <h4>LoggerContext</h4> |
| <p> |
| The |
| <a href="../log4j2-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 at<a href="logsep.html">Log Separation</a>. |
| </p> |
| <h4>Configuration</h4> |
| <p>Every LoggerContext has an active |
| <a href="../log4j/log4j2-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html"> |
| Configuration</a>. |
| The Configuration contains all the Appenders, |
| context-wide Filtes, 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="../log4j2-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="file:///Users/rgoers/log4j/log4j2-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> |
| <table bgcolor="#EEEE99"> |
| <tr> |
| <td>Retrieving Loggers</td> |
| </tr> |
| </table> |
| <p>Calling the |
| <code>getLogger</code> |
| method with the same name will |
| always return a reference to the exact same Logger object. |
| </p> |
| |
| <p>For example, in |
| <source> |
| Logger x = Logger.getLogger("wombat"); |
| Logger y = Logger.getLogger("wombat"); |
| </source> |
| <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>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="../log4j2-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> |
| <table bgcolor="#EEEE99"> |
| <tr> |
| <td>Log Levels</td> |
| </tr> |
| </table> |
| <p>LoggerConfigs will be assigned a Log |
| <a href="../log4j2-api/apidocs/org/apache/logging/log4j/Level.html">Level</a>. The set of possible |
| levels includes (TRACE, DEBUG, INFO, WARN, ERROR and FATAL). Note that in Log4j 2, the Level is |
| an Enum and cannot be sub-classed. Users who desire more granularity are encouraged to use |
| <a href="../log4j2-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 border="1" width="40%"> |
| <tr> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y.Z</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <caption align="bottom">Example 1</caption> |
| </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 border="1" width="40%"> |
| <tr> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y</td> |
| <td>X.Y</td> |
| <td>INFO</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y.Z</td> |
| <td>X.Y.Z</td> |
| <td>WARN</td> |
| </tr> |
| <caption align="bottom">Example 2</caption> |
| </table> |
| |
| <p>In example 2, all loggers have a configured LoggerConfig and obtain their Level |
| from it. |
| </p> |
| |
| <table border="1" width="40%"> |
| <tr> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y.Z</td> |
| <td>X.Y.Z</td> |
| <td>WARN</td> |
| </tr> |
| <caption align="bottom">Example 3</caption> |
| </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 border="1" width="40%"> |
| <tr> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y.Z</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <caption align="bottom">Example 4</caption> |
| </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 LoggerCofnig whose name has the |
| longest match to the start of the Logger's name. |
| </p> |
| |
| <table border="1" width="40%"> |
| <tr> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr align="left"> |
| <td>X.Y</td> |
| <td>X.Y</td> |
| <td>INFO</td> |
| </tr> |
| <tr align="left"> |
| <td>X.YZ</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <caption align="bottom">Example 5</caption> |
| </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 LoggerCofnig 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> |
| <p>The table below provides illustrates how Level filtering works. Im the table, the vertical |
| header shows the Level of the LogEvent, while the horizontal header shows the Level associated |
| with the appopriate LoggerConfig. The intersection identifies whether the LogEvent would |
| be allowed to pass for further processing (Yes) or discarded (No). |
| </p> |
| <table width="100%"> |
| <tr> |
| <th style="background-color:cyan; color:black" rowspan="2">Event Level</th> |
| <th style="background-color:cyan; color:black; border-top: 1px solid #DDDDDD;" |
| align="center" colspan="6">LoggerConfig Level |
| </th> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">TRACE</th> |
| <th style="background-color:cyan; color:black">DEBUG</th> |
| <th style="background-color:cyan; color:black">INFO</th> |
| <th style="background-color:cyan; color:black">WARN</th> |
| <th style="background-color:cyan; color:black">ERROR</th> |
| <th style="background-color:cyan; color:black">FATAL</th> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">ALL</th> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">TRACE</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">DEBUG</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">INFO</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">WARN</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">ERROR</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:red;font-weight:bold">NO</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">FATAL</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| </tr> |
| <tr align="left"> |
| <th style="background-color:cyan; color:black">OFF</th> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</td> |
| <td style="color:green;font-weight:bold">YES</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="../log4j2-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 pased to a LoggerConfig |
| but before calling any Appenders, and on each Appender. In a manner very similar to firewall filters, |
| each Filter can return one of three results, Accept, Deny or Neutral. A response of Accept means |
| that no other Filters should be called and the event should progress. A response of Deny means |
| the event should be immediately ignored and control should be returned to the caller. A response |
| of Neutral indicates the event should be passed to other Filters. If there are no other Fitlers 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="../log4j2-core/apidocs/org/apache/logging/log4j/core/Appender.html">Appender</a>. |
| Currently, appenders exist for the console, files, remote socket servers, Apache Flume, |
| JMS, and remote UNIX Syslog daemons. 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="../log4j2-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> |
| |
| <p> |
| <a name="additivity"/> |
| <table bgcolor="#EEEE99"> |
| <tr> |
| <td> |
| <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> |
| </td> |
| </tr> |
| </table> |
| </p> |
| |
| <p>The table below shows an example:</p> |
| |
| <p> |
| <table align="center" border="3" cellpadding="10"> |
| <tr rowspan="2"> |
| <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> |
| </p> |
| <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="../log4j2-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="../log4j2-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:<br /> |
| <source> |
| 176 [main] INFO org.foo.Bar - Located nearest gas station. |
| </source> |
| </p> |
| |
| <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>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/log4j2-core/apidocs/org/apache/logging/log4j/core/lookup/StrSubstitutor.html"> |
| StrSubstitutor |
| </a> |
| class and |
| <a href="../log4j/log4j2-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html">StrLookup</a> |
| interface were borrowed from Apache Commons Lang and then modified to support evaluating LogEvents. In |
| addition the |
| <a href="../log4j/log4j2-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> |