| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
| <!-- |
| | (Unfortunately) copied from the Fluido skin to allow the footer to be centered. |
| --> |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
| <head> |
| <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <title> |
| Log4j 2 Architecture</title> |
| <link rel="stylesheet" href="../css/apache-maven-fluido.min.css" /> |
| <link rel="stylesheet" href="../css/site.css" /> |
| <link rel="stylesheet" href="../css/print.css" media="print" /> |
| |
| |
| <script type="text/javascript" src="../js/apache-maven-fluido.min.js"></script> |
| |
| |
| <meta name="author" content="Ralph Goers" /> |
| <meta name="Date-Revision-yyyymmdd" content="20120729" /> |
| <meta http-equiv="Content-Language" content="en" /> |
| </head> |
| <body class="topBarDisabled"> |
| |
| |
| |
| |
| <div class="container-fluid"> |
| <div id="banner"> |
| <div class="pull-left"> |
| <a href="../../../" id="bannerLeft"> |
| <img src="../images/ls-logo.jpg" alt="Apache Logging Services™"/> |
| </a> |
| </div> |
| <div class="pull-right"> <div id="bannerRight"> |
| <img src="../images/logo.jpg" /> |
| </div> |
| </div> |
| <div class="clear"><hr/></div> |
| </div> |
| |
| <div id="breadcrumbs"> |
| <ul class="breadcrumb"> |
| |
| |
| <li id="publishDate">Last Published: 2012-07-29</li> |
| <li class="divider">|</li> <li id="projectVersion">Version: 2.0-alpha1</li> |
| |
| |
| |
| |
| |
| <li class="pull-right"> <a href="../../../" title="Logging Services">Logging Services</a> |
| </li> |
| |
| <li class="divider pull-right">|</li> |
| |
| <li class="pull-right"> <a href="http://www.apache.org/" class="externalLink" title="Apache">Apache</a> |
| </li> |
| |
| <li class="divider pull-right">|</li> |
| |
| <li class="pull-right"> <a href="http://wiki.apache.org/logging" class="externalLink" title="Logging Wiki">Logging Wiki</a> |
| </li> |
| |
| </ul> |
| </div> |
| |
| <div class="row-fluid"> |
| <div id="leftColumn" class="span2"> |
| <div class="well sidebar-nav"> |
| |
| |
| <h3>Apache Log4j™ 2</h3> |
| <ul> |
| <li class="none"> |
| <a href="../index.html" title="About">About</a> |
| </li> |
| <li class="none"> |
| <a href="../download.html" title="Download">Download</a> |
| </li> |
| <li class="none"> |
| <a href="../build.html" title="Build and Install">Build and Install</a> |
| </li> |
| <li class="none"> |
| <a href="../changelog.html" title="Changelog">Changelog</a> |
| </li> |
| </ul> |
| <h3>Manual</h3> |
| <ul> |
| <li class="none"> |
| <a href="../manual/index.html" title="Introduction">Introduction</a> |
| </li> |
| <li class="none"> |
| <strong>Architecture</strong> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/api.html" title="API">API</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/configuration.html" title="Configuration">Configuration</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/plugins.html" title="Plugins">Plugins</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/lookups.html" title="Lookups">Lookups</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/appenders.html" title="Appenders">Appenders</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/layouts.html" title="Layouts">Layouts</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/filters.html" title="Filters">Filters</a> |
| </li> |
| <li class="none"> |
| <a href="../manual/jmx.html" title="JMX">JMX</a> |
| </li> |
| <li class="none"> |
| <a href="../manual/logsep.html" title="Logging Separation">Logging Separation</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../manual/extending.html" title="Extending Log4j">Extending Log4j</a> |
| </li> |
| </ul> |
| <h3>Logging Adapters</h3> |
| <ul> |
| <li class="none"> |
| <a href="../log4j12-api/api.html" title="Log4j 1.x API">Log4j 1.x API</a> |
| </li> |
| <li class="none"> |
| <a href="../log4j2-jcl/api.html" title="Commons Logging">Commons Logging</a> |
| </li> |
| <li class="none"> |
| <a href="../slf4j-impl/api.html" title="SLF4J">SLF4J</a> |
| </li> |
| </ul> |
| <h3>Components</h3> |
| <ul> |
| <li class="none"> |
| <a href="../log4j-api/index.html" title="API">API</a> |
| </li> |
| <li class="none"> |
| <a href="../log4j-core/index.html" title="Impl">Impl</a> |
| </li> |
| <li class="none"> |
| <a href="../log4j12-api/index.html" title="Log4J 1.2 API">Log4J 1.2 API</a> |
| </li> |
| <li class="none"> |
| <a href="../log4j-jcl/index.html" title="Commons Logging Bridge">Commons Logging Bridge</a> |
| </li> |
| <li class="none"> |
| <a href="../slf4j-impl/index.html" title="SLF4J Binding">SLF4J Binding</a> |
| </li> |
| <li class="none"> |
| <a href="../log4j-flume-ng/index.html" title="Apache Flume">Apache Flume</a> |
| </li> |
| </ul> |
| <h3>Site Documentation</h3> |
| <ul> |
| <li class="collapsed"> |
| <a href="../project-info.html" title="Project Information">Project Information</a> |
| </li> |
| <li class="collapsed"> |
| <a href="../project-reports.html" title="Project Reports">Project Reports</a> |
| </li> |
| </ul> |
| |
| |
| |
| <hr class="divider" /> |
| |
| <div id="poweredBy"> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <div class="clear"></div> |
| <a href="http://maven.apache.org/" title="Built by Maven" class="poweredBy"> |
| <img class="poweredBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /> |
| </a> |
| </div> |
| </div> |
| </div> |
| |
| <div id="bodyColumn" class="span10" > |
| |
| <!-- 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. --> |
| |
| <div class="section"><h2>Architecture<a name="Architecture"></a></h2> |
| <div class="section"><h3>Main Components<a name="Main_Components"></a></h3> |
| <p>Log4j uses the classes shown in the diagram below.</p> |
| <img src="../images/Log4jClasses.jpg" title="Log4j 2 Class Relationships" alt="" /> |
| <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> |
| <div class="section"><h4>Logger Hierarchy<a name="Logger_Hierarchy"></a></h4> |
| <p>The first and foremost advantage of any logging API over plain |
| <tt>System.out.println</tt> |
| 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> |
| </p><table border="0" class="table table-striped" bgcolor="#EEEE99"> |
| <tr class="a"> |
| <td> |
| <dl> |
| <dt> |
| <b>Named Hierarchy</b> |
| </dt> |
| |
| <dd>A LoggerConfig is said to be an |
| <i>ancestor</i> |
| of another |
| LoggerConfig if its name followed by a dot is a prefix of the |
| <i>descendant</i> |
| logger name. A LoggerConfig is said to be a |
| <i>parent</i> |
| of a |
| <i>child</i> |
| LoggerConfig if there are no |
| ancestors between itself and the descendant LoggerConfig. |
| </dd> |
| </dl> |
| </td> |
| </tr> |
| </table> |
| |
| <p>For example, the LoggerConfig named |
| <tt>"com.foo"</tt> |
| is a parent |
| of the LoggerConfig named<tt>"com.foo.Bar"</tt>. Similarly, |
| <tt>"java"</tt> |
| is a parent of |
| <tt>"java.util"</tt> |
| and an |
| ancestor of<tt>"java.util.Vector"</tt>. 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><div class="source"><pre class="prettyprint">Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);</pre></div> |
| All other Loggers can be retrieved using the |
| <a href="../log4j2-api/apidocs/org/apache/logging/log4j/LogManager.html#getLoggerjava.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>. |
| |
| </div><div class="section"><h4>LoggerContext<a name="LoggerContext"></a></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> |
| </div><div class="section"><h4>Configuration<a name="Configuration"></a></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> |
| </div><div class="section"><h4>Logger<a name="Logger"></a></h4> |
| <p>As stated previously, Loggers are created by calling |
| <a href="../log4j2-api/apidocs/org/apache/logging/log4j/LogManager.html#getLoggerjava.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 class="externalLink" 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 border="0" class="table table-striped" bgcolor="#EEEE99"> |
| <tr class="a"> |
| <td>Retrieving Loggers</td> |
| </tr> |
| </table> |
| <p>Calling the |
| <tt>getLogger</tt> |
| method with the same name will |
| always return a reference to the exact same Logger object. |
| </p> |
| |
| <p>For example, in |
| </p><div class="source"><pre class="prettyprint"> |
| Logger x = Logger.getLogger("wombat"); |
| Logger y = Logger.getLogger("wombat"); |
| </pre></div> |
| <tt>x</tt> and <tt>y</tt> refer to <i>exactly</i> the same Logger object. |
| |
| |
| <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 <i>software component</i>. 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> |
| </div><div class="section"><h4>LoggerConfig<a name="LoggerConfig"></a></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 border="0" class="table table-striped" bgcolor="#EEEE99"> |
| <tr class="a"> |
| <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 class="externalLink" href="http://logging.apache.org/log4j/1.2/manual.html">Log4j 1.x</a> |
| and |
| <a class="externalLink" 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 class="table table-striped" border="1" width="40%"><caption align="bottom">Example 1</caption> |
| <tr class="a"> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr class="b" align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="b" align="left"> |
| <td>X.Y</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X.Y.Z</td> |
| <td>root</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 class="table table-striped" border="1" width="40%"><caption align="bottom">Example 2</caption> |
| <tr class="a"> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr class="b" align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="b" align="left"> |
| <td>X.Y</td> |
| <td>X.Y</td> |
| <td>INFO</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X.Y.Z</td> |
| <td>X.Y.Z</td> |
| <td>WARN</td> |
| </tr> |
| |
| </table> |
| |
| <p>In example 2, all loggers have a configured LoggerConfig and obtain their Level |
| from it. |
| </p> |
| |
| <table class="table table-striped" border="1" width="40%"><caption align="bottom">Example 3</caption> |
| <tr class="a"> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr class="b" align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="b" align="left"> |
| <td>X.Y</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X.Y.Z</td> |
| <td>X.Y.Z</td> |
| <td>WARN</td> |
| </tr> |
| |
| </table> |
| |
| <p>In example 3, the loggers<tt>root</tt>, |
| <tt>X</tt> |
| and |
| <tt>X.Y.Z</tt> |
| each have a configured LoggerConfig with the same name. The Logger |
| <tt>X.Y</tt> |
| does not have a configured LoggerConfig with a matching name so uses |
| the configuration of LoggerConfig |
| <tt>X</tt> |
| since that is the LoggerConfig whose |
| name has the longest match to the start of the Logger's name. |
| </p> |
| |
| <table class="table table-striped" border="1" width="40%"><caption align="bottom">Example 4</caption> |
| <tr class="a"> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr class="b" align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="b" align="left"> |
| <td>X.Y</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X.Y.Z</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| |
| </table> |
| |
| <p>In example 4, the loggers |
| <tt>root</tt> |
| and |
| <tt>X</tt> |
| each have a Configured |
| LoggerConfig with the same name. The loggers |
| <tt>X.Y</tt> |
| and |
| <tt>X.Y.Z</tt> |
| do not have configured LoggerConfigs and so get their Level from the LoggerConfig |
| assigned to them,<tt>X</tt>, since it is the LoggerCofnig whose name has the |
| longest match to the start of the Logger's name. |
| </p> |
| |
| <table class="table table-striped" border="1" width="40%"><caption align="bottom">Example 5</caption> |
| <tr class="a"> |
| <th>Logger Name</th> |
| <th>Assigned LoggerConfig</th> |
| <th>level</th> |
| </tr> |
| <tr class="b" align="left"> |
| <td>root</td> |
| <td>root</td> |
| <td>DEBUG</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| <tr class="b" align="left"> |
| <td>X.Y</td> |
| <td>X.Y</td> |
| <td>INFO</td> |
| </tr> |
| <tr class="a" align="left"> |
| <td>X.YZ</td> |
| <td>X</td> |
| <td>ERROR</td> |
| </tr> |
| |
| </table> |
| |
| <p>In example 5, the loggers<tt>root</tt>.<tt>X</tt>, and |
| <tt>X.Y</tt> |
| each |
| have a Configured LoggerConfig with the same name. The logger |
| <tt>X.YZ</tt> |
| does not have configured LoggerConfig and so gets its Level from the LoggerConfig |
| assigned to it,<tt>X</tt>, 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 |
| <tt>X.Y</tt> |
| 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 border="0" class="table table-striped" width="100%"> |
| <tr class="a"> |
| <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 class="b" 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 class="a" 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 class="b" 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 class="a" 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 class="b" 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 class="a" 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 class="b" 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 class="a" 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 class="b" 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> |
| |
| </div><div class="section"><h4>Filter<a name="Filter"></a></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 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, 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> |
| </div><div class="section"><h4>Appender<a name="Appender"></a></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#addLoggerAppenderorg.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 |
| <i>C</i>, then enabled logging requests for <i>C</i> and <i>C</i>'s children will print |
| in a file <i>and</i> on the console. It is possible to override this default behavior so that |
| Appender accumulation is no longer additive by setting <tt>additivity="false"</tt> on the |
| Logger declaration in the configuration file. |
| </p> |
| <p>The rules governing appender additivity are summarized below.</p> |
| |
| <p> |
| <a name="additivity"></a> |
| </p><table border="0" class="table table-striped" bgcolor="#EEEE99"> |
| <tr class="a"> |
| <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 <tt>false</tt>, 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 <tt>true</tt> by default.</p> |
| </dd> |
| </dl> |
| </td> |
| </tr> |
| </table> |
| |
| |
| <p>The table below shows an example:</p> |
| |
| <p> |
| </p><table class="table table-striped" align="center" border="3" cellpadding="10"> |
| <tr class="a"> |
| <th>Logger<br />Name </th> |
| <th>Added<br />Appenders</th> |
| <th>Additivity<br />Flag</th> |
| <th>Output Targets</th> |
| <th>Comment</th> |
| </tr> |
| <tr class="b"> |
| <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 class="a"> |
| <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 class="b"> |
| <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 class="a"> |
| <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 class="b"> |
| <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 <tt>false</tt>.</td> |
| </tr> |
| <tr class="a"> |
| <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 <tt>false</tt>. |
| </td> |
| </tr> |
| </table> |
| |
| </div><div class="section"><h4>Layout<a name="Layout"></a></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 <tt>printf</tt> function. |
| </p> |
| |
| <p>For example, the PatternLayout with the conversion pattern "%r [%t] |
| %-5p %c - %m%n" will output something akin to:<br /> |
| </p><div class="source"><pre class="prettyprint"> |
| 176 [main] INFO org.foo.Bar - Located nearest gas station. |
| </pre></div> |
| |
| |
| <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 <tt>Oranges</tt>, 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> |
| |
| </div><div class="section"><h4>StrSubstitutor and StrLookup<a name="StrSubstitutor_and_StrLookup"></a></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> |
| |
| </div></div> |
| |
| </div> |
| |
| |
| </div> |
| </div> |
| |
| <hr/> |
| |
| <footer> |
| <div class="container-fluid"> |
| <div class="row footer">Copyright © 1999-2012 <a href="http://www.apache.org">Apache Software Foundation</a>. All Rights Reserved.</br /> |
| Apache Logging, Apache Log4j, Log4j, Apache, the Apache feather logo, and the Apache Logging project logo are trademarks of The Apache Software Foundation.</div> |
| </div> |
| </footer> |
| </body> |
| </html> |