blob: 4b25e7a7991671d2c434cb391027b3dc7b22a4e1 [file] [log] [blame]
<!DOCTYPE html>
<!--
| Generated by Apache Maven Doxia Site Renderer 1.9.1 from src/site/xdoc/manual/architecture.xml at 2020-02-25
| Rendered using Apache Maven Fluido Skin 1.8
-->
<html xmlns="http://www.w3.org/1999/xhtml" lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="generator" content="Apache Maven Doxia Site Renderer 1.9.1" />
<meta name="author" content="Ralph Goers" />
<title>Log4j &#x2013; Log4j 2 Architecture</title>
<link rel="stylesheet" href="../css/apache-maven-fluido-1.8.min.css" />
<link rel="stylesheet" href="../css/site.css" />
<link rel="stylesheet" href="../css/print.css" media="print" />
<script src="../js/apache-maven-fluido-1.8.min.js"></script>
</head>
<body class="topBarDisabled">
<div class="container-fluid">
<header>
<div id="banner">
<div class="pull-left"><a href="http://logging.apache.org" id="bannerLeft"><img src="../images/ls-logo.jpg" alt=""/></a></div>
<div class="pull-right"><a href="http://logging.apache.org/log4j/2.x" id="bannerRight"><img src="../images/logo.png" alt=""/></a></div>
<div class="clear"><hr/></div>
</div>
<div id="breadcrumbs">
<ul class="breadcrumb">
<li id="publishDate">Last Published: 2020-02-25<span class="divider">|</span>
</li>
<li id="projectVersion">Version: 2.13.1</li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://github.com/apache/logging-log4j2" class="externalLink" title="GitHub">GitHub</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://analysis.apache.org/dashboard/index/org.apache.logging.log4j:log4j" class="externalLink" title="Sonar">Sonar</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="../../../" title="Logging Services">Logging Services</a></li>
<li class="pull-right"><span class="divider">|</span>
<a href="https://www.apache.org/" class="externalLink" title="Apache">Apache</a></li>
<li class="pull-right"><a href="https://cwiki.apache.org/confluence/display/LOGGING/Log4j" class="externalLink" title="Logging Wiki">Logging Wiki</a></li>
</ul>
</div>
</header>
<div class="row-fluid">
<header id="leftColumn" class="span2">
<nav class="well sidebar-nav">
<ul class="nav nav-list">
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/home.png" alt="Apache Log4j™ 2" border="0"/> Apache Log4j™ 2</li>
<li><a href="../index.html" title="About"><span class="none"></span>About</a></li>
<li><a href="../download.html" title="Download"><span class="none"></span>Download</a></li>
<li><a href="../javadoc.html" title="Javadoc"><span class="icon-chevron-right"></span>Javadoc</a></li>
<li><a href="../maven-artifacts.html" title="Maven, Ivy, Gradle Artifacts"><span class="icon-chevron-right"></span>Maven, Ivy, Gradle Artifacts</a></li>
<li><a href="../runtime-dependencies.html" title="Runtime Dependencies"><span class="none"></span>Runtime Dependencies</a></li>
<li><a href="../changelog.html" title="Changelog"><span class="none"></span>Changelog</a></li>
<li><a href="../faq.html" title="FAQ"><span class="none"></span>FAQ</a></li>
<li><a href="../performance.html" title="Performance"><span class="icon-chevron-right"></span>Performance</a></li>
<li><a href="../articles.html" title="Articles and Tutorials"><span class="none"></span>Articles and Tutorials</a></li>
<li><a href="../support.html" title="Support"><span class="none"></span>Support</a></li>
<li><a href="../thanks.html" title="Thanks"><span class="none"></span>Thanks</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/pencil.png" alt="For Contributors" border="0"/> For Contributors</li>
<li><a href="../build.html" title="Building Log4j from Source"><span class="none"></span>Building Log4j from Source</a></li>
<li><a href="../guidelines.html" title="Guidelines"><span class="none"></span>Guidelines</a></li>
<li><a href="../javastyle.html" title="Style Guide"><span class="none"></span>Style Guide</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/book.png" alt="Manual" border="0"/> Manual</li>
<li><a href="../manual/index.html" title="Introduction"><span class="none"></span>Introduction</a></li>
<li class="active"><a href="#"><span class="none"></span>Architecture</a></li>
<li><a href="../manual/compatibility.html" title="Log4j 1.x Compatibility"><span class="none"></span>Log4j 1.x Compatibility</a></li>
<li><a href="../manual/migration.html" title="Log4j 1.x Migration"><span class="none"></span>Log4j 1.x Migration</a></li>
<li><a href="../manual/api.html" title="Java API"><span class="icon-chevron-right"></span>Java API</a></li>
<li><a href="../manual/scala-api.html" title="Scala API"><span class="none"></span>Scala API</a></li>
<li><a href="../manual/configuration.html" title="Configuration"><span class="icon-chevron-right"></span>Configuration</a></li>
<li><a href="../manual/usage.html" title="Usage"><span class="icon-chevron-right"></span>Usage</a></li>
<li><a href="../manual/webapp.html" title="Web Applications and JSPs"><span class="icon-chevron-right"></span>Web Applications and JSPs</a></li>
<li><a href="../manual/lookups.html" title="Lookups"><span class="icon-chevron-right"></span>Lookups</a></li>
<li><a href="../manual/appenders.html" title="Appenders"><span class="icon-chevron-right"></span>Appenders</a></li>
<li><a href="../manual/layouts.html" title="Layouts"><span class="icon-chevron-right"></span>Layouts</a></li>
<li><a href="../manual/filters.html" title="Filters"><span class="icon-chevron-right"></span>Filters</a></li>
<li><a href="../manual/async.html" title="Async Loggers"><span class="icon-chevron-right"></span>Async Loggers</a></li>
<li><a href="../manual/garbagefree.html" title="Garbage-free Logging"><span class="icon-chevron-right"></span>Garbage-free Logging</a></li>
<li><a href="../manual/jmx.html" title="JMX"><span class="none"></span>JMX</a></li>
<li><a href="../manual/logsep.html" title="Logging Separation"><span class="none"></span>Logging Separation</a></li>
<li><a href="../manual/extending.html" title="Extending Log4j"><span class="icon-chevron-right"></span>Extending Log4j</a></li>
<li><a href="../manual/plugins.html" title="Plugins"><span class="icon-chevron-right"></span>Plugins</a></li>
<li><a href="../manual/customconfig.html" title="Programmatic Log4j Configuration"><span class="icon-chevron-right"></span>Programmatic Log4j Configuration</a></li>
<li><a href="../manual/customloglevels.html" title="Custom Log Levels"><span class="icon-chevron-right"></span>Custom Log Levels</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/tag.png" alt="Related Projects" border="0"/> Related Projects</li>
<li><a href="http://logging.apache.org/log4j/scala/index.html" class="externalLink" title="Log4j-Scala"><span class="none"></span>Log4j-Scala</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/link.png" alt="Legacy Sites" border="0"/> Legacy Sites</li>
<li><a href="http://logging.apache.org/log4j/1.2/" class="externalLink" title="Log4j 1.2 - End of Life"><span class="none"></span>Log4j 1.2 - End of Life</a></li>
<li><a href="http://logging.apache.org/log4j/log4j-2.3/" class="externalLink" title="Log4j 2.3 - Java 6"><span class="none"></span>Log4j 2.3 - Java 6</a></li>
<li><a href="http://logging.apache.org/log4j/log4j-2.12.1" class="externalLink" title="Log4j 2.12.1 - Java 7"><span class="none"></span>Log4j 2.12.1 - Java 7</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/cog.png" alt="Components" border="0"/> Components</li>
<li><a href="../log4j-api/index.html" title="API"><span class="none"></span>API</a></li>
<li><a href="../log4j-core/index.html" title="Implementation"><span class="none"></span>Implementation</a></li>
<li><a href="../log4j-jcl/index.html" title="Commons Logging Bridge"><span class="none"></span>Commons Logging Bridge</a></li>
<li><a href="../log4j-1.2-api/index.html" title="Log4j 1.2 API"><span class="none"></span>Log4j 1.2 API</a></li>
<li><a href="../log4j-slf4j-impl/index.html" title="SLF4J Binding"><span class="none"></span>SLF4J Binding</a></li>
<li><a href="../log4j-jul/index.html" title="JUL Adapter"><span class="none"></span>JUL Adapter</a></li>
<li><a href="../log4j-to-slf4j/index.html" title="Log4j 2 to SLF4J Adapter"><span class="none"></span>Log4j 2 to SLF4J Adapter</a></li>
<li><a href="../log4j-flume-ng/index.html" title="Apache Flume Appender"><span class="none"></span>Apache Flume Appender</a></li>
<li><a href="../log4j-taglib/index.html" title="Log4j Tag Library"><span class="none"></span>Log4j Tag Library</a></li>
<li><a href="../log4j-jmx-gui/index.html" title="Log4j JMX GUI"><span class="none"></span>Log4j JMX GUI</a></li>
<li><a href="../log4j-web/index.html" title="Log4j Web Application Support"><span class="none"></span>Log4j Web Application Support</a></li>
<li><a href="../log4j-appserver/index.html" title="Log4j Application Server Integration"><span class="none"></span>Log4j Application Server Integration</a></li>
<li><a href="../log4j-couchdb/index.html" title="Log4j CouchDB appender"><span class="none"></span>Log4j CouchDB appender</a></li>
<li><a href="../log4j-mongodb2/index.html" title="Log4j MongoDB2 appender"><span class="none"></span>Log4j MongoDB2 appender</a></li>
<li><a href="../log4j-mongodb3/index.html" title="Log4j MongoDB3 appender"><span class="none"></span>Log4j MongoDB3 appender</a></li>
<li><a href="../log4j-cassandra/index.html" title="Log4j Cassandra appender"><span class="none"></span>Log4j Cassandra appender</a></li>
<li><a href="../log4j-iostreams/index.html" title="Log4j IO Streams"><span class="none"></span>Log4j IO Streams</a></li>
<li><a href="../log4j-liquibase/index.html" title="Log4j Liquibase Binding"><span class="none"></span>Log4j Liquibase Binding</a></li>
<li><a href="../log4j-docker/index.html" title="Log4j Docker Support"><span class="none"></span>Log4j Docker Support</a></li>
<li><a href="../log4j-spring-cloud-config/log4j-spring-cloud-config-client/index.html" title="Log4j Spring Cloud Config Client"><span class="none"></span>Log4j Spring Cloud Config Client</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/info.png" alt="Project Information" border="0"/> Project Information</li>
<li><a href="../dependency-convergence.html" title="Dependency Convergence"><span class="none"></span>Dependency Convergence</a></li>
<li><a href="../dependency-management.html" title="Dependency Management"><span class="none"></span>Dependency Management</a></li>
<li><a href="../team-list.html" title="Project Team"><span class="none"></span>Project Team</a></li>
<li><a href="../mail-lists.html" title="Mailing Lists"><span class="none"></span>Mailing Lists</a></li>
<li><a href="../issue-tracking.html" title="Issue Tracking"><span class="none"></span>Issue Tracking</a></li>
<li><a href="../license.html" title="Project License"><span class="none"></span>Project License</a></li>
<li><a href="../source-repository.html" title="Source Repository"><span class="none"></span>Source Repository</a></li>
<li><a href="../project-summary.html" title="Project Summary"><span class="none"></span>Project Summary</a></li>
<li class="nav-header"><img class="imageLink" src="../img/glyphicons/layers.png" alt="Project Reports" border="0"/> Project Reports</li>
<li><a href="../changes-report.html" title="Changes Report"><span class="none"></span>Changes Report</a></li>
<li><a href="../jira-report.html" title="JIRA Report"><span class="none"></span>JIRA Report</a></li>
<li><a href="../rat-report.html" title="RAT Report"><span class="none"></span>RAT Report</a></li>
</ul>
</nav>
<div class="well sidebar-nav">
<hr />
<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="builtBy" alt="Built by Maven" src="../images/logos/maven-feather.png" /></a>
</div>
</div>
</header>
<main id="bodyColumn" class="span10" >
<section>
<h2><a name="Architecture"></a>Architecture</h2>
<section>
<h3><a name="Main_Components"></a>Main Components</h3>
<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>
<section>
<h4><a name="Logger_Hierarchy"></a>Logger Hierarchy</h4>
<p>The first and foremost advantage of any logging API over plain
System.out.println
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 <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>
</div>
<p>For example, the LoggerConfig named
&quot;com.foo&quot;
is a parent
of the LoggerConfig named&quot;com.foo.Bar&quot;. Similarly,
&quot;java&quot;
is a parent of
&quot;java.util&quot;
and an
ancestor of &quot;java.util.Vector&quot;. 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>
<pre class="prettyprint">Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);</pre></div>
<p>
Alternatively, and more simply:
</p>
<div>
<pre class="prettyprint">Logger logger = LogManager.getRootLogger();</pre></div>
<p>
All other Loggers can be retrieved using the
<a href="../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getLoggerjava.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>
</section><section>
<h4><a name="LoggerContext"></a>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>
</section><section>
<h4><a name="Configuration"></a>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>
</section><section>
<h4><a name="Logger"></a>Logger</h4>
<p>As stated previously, Loggers are created by calling
<a href="../log4j-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 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>
<section>
<h5><a name="Retrieving_Loggers"></a>Retrieving Loggers</h5>
<p>
Calling the LogManager.getLogger method with the same name will always return a reference to the
exact same Logger object.
</p>
<p>For example, in
</p>
<div>
<pre class="prettyprint">
Logger x = LogManager.getLogger(&quot;wombat&quot;);
Logger y = LogManager.getLogger(&quot;wombat&quot;);
</pre></div>
<p>
x and y refer to <i>exactly</i> 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 <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>Since naming Loggers after their owning class is such a common idiom, the convenience method
LogManager.getLogger() 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>
</section></section><section>
<h4><a name="LoggerConfig"></a>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>
<section>
<h5><a name="Log_Levels"></a>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 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 &quot;Level Inheritance&quot;. 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="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 1</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>Logger Level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<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 border="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 2</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>Level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>X.Y</td>
<td>INFO</td>
<td>INFO</td>
</tr>
<tr class="a">
<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 border="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 3</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>Level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="a">
<td>X.Y.Z</td>
<td>X.Y.Z</td>
<td>WARN</td>
<td>WARN</td>
</tr>
</table>
<p>In example 3, the loggersroot,
X
and
X.Y.Z
each have a configured LoggerConfig with the same name. The Logger
X.Y
does not have a configured LoggerConfig with a matching name so uses
the configuration of LoggerConfig
X
since that is the LoggerConfig whose
name has the longest match to the start of the Logger's name.
</p>
<table border="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 4</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="a">
<td>X.Y.Z</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
</table>
<p>In example 4, the loggers
root
and
X
each have a Configured
LoggerConfig with the same name. The loggers
X.Y
and
X.Y.Z
do not have configured LoggerConfigs and so get their Level from the LoggerConfig
assigned to them,X, since it is the LoggerConfig whose name has the
longest match to the start of the Logger's name.
</p>
<table border="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 5</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>X.Y</td>
<td>INFO</td>
<td>INFO</td>
</tr>
<tr class="a">
<td>X.YZ</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
</table>
<p>In example 5, the loggersroot.X, and
X.Y
each
have a Configured LoggerConfig with the same name. The logger
X.YZ
does not have configured LoggerConfig and so gets its Level from the LoggerConfig
assigned to it,X, 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
X.Y
since tokens after periods must match exactly.
</p>
<table border="0" class="table table-striped" style="width: 40%"><caption align="bottom">Example 6</caption>
<tr class="a">
<th>Logger Name</th>
<th>Assigned LoggerConfig</th>
<th>LoggerConfig Level</th>
<th>Level</th>
</tr>
<tr class="b">
<td>root</td>
<td>root</td>
<td>DEBUG</td>
<td>DEBUG</td>
</tr>
<tr class="a">
<td>X</td>
<td>X</td>
<td>ERROR</td>
<td>ERROR</td>
</tr>
<tr class="b">
<td>X.Y</td>
<td>X.Y</td>
<td></td>
<td>ERROR</td>
</tr>
<tr class="a">
<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 border="0" class="table table-striped">
<tr class="a">
<th>Event Level</th>
<th style="text-align: center" colspan="6">LoggerConfig Level</th>
</tr>
<tr class="b">
<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 class="a">
<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 class="b">
<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 class="a">
<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 class="b">
<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 class="a">
<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 class="b">
<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 class="a">
<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 class="b">
<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>
</section></section><section>
<h4><a name="Filter"></a>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, 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 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>
</section><section>
<h4><a name="Appender"></a>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#addLoggerAppenderorg.apache.logging.log4j.core.Logger20org.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 additivity=&quot;false&quot; 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
&quot;appender additivity&quot;.
</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 false, 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 true by default.</p>
</dd>
</dl>
</div>
<p>The table below shows an example:</p>
<table border="0" class="table table-striped">
<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 &quot;x&quot; 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 &quot;x&quot; 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 &quot;x.y.z&quot;, &quot;x&quot; 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 false.</td>
</tr>
<tr class="a">
<td>security.access</td>
<td>none</td>
<td>true</td>
<td>A-sec</td>
<td>Only appenders of &quot;security&quot; because the additivity flag in &quot;security&quot; is
set to false.
</td>
</tr>
</table>
</section><section>
<h4><a name="Layout"></a>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 printf function.
</p>
<p>For example, the PatternLayout with the conversion pattern &quot;%r [%t]
%-5p %c - %m%n&quot; will output something akin to:
</p>
<div>
<pre>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>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 Oranges, 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>
</section><section>
<h4><a name="StrSubstitutor_and_StrLookup"></a>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 class="externalLink" 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>
</section></section>
</section>
</main>
</div>
</div>
<hr/>
<footer>
<div class="container-fluid">
<div class="row-fluid">
<p align="center">Copyright &copy; 1999-2020 <a class="external" href="http://www.apache.org">The 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.</p>
</div>
</div>
</footer>
</body>
</html>