| <?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> </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,%20org.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> |