This is an automated email from the ASF dual-hosted git repository.
grobmeier pushed a commit to branch ms12_restructure_website_2x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
The following commit(s) were added to refs/heads/ms12_restructure_website_2x by
this push:
new 874418dbe1 migrated architecture to asciidoc
874418dbe1 is described below
commit 874418dbe1b1f67466b0b15d6f9adc611782a3c6
Author: Christian Grobmeier <[email protected]>
AuthorDate: Mon Mar 11 10:35:53 2024 +0100
migrated architecture to asciidoc
---
src/site/asciidoc/manual/architecture.adoc | 481 +++++++++++++++++++
src/site/xdoc/manual/architecture.xml | 741 -----------------------------
2 files changed, 481 insertions(+), 741 deletions(-)
diff --git a/src/site/asciidoc/manual/architecture.adoc
b/src/site/asciidoc/manual/architecture.adoc
new file mode 100644
index 0000000000..e6ab20f2f3
--- /dev/null
+++ b/src/site/asciidoc/manual/architecture.adoc
@@ -0,0 +1,481 @@
+////
+ 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.
+////
+= Architecture
+Ralph Goers <[email protected]>
+
+== Main Components
+
+Log4j uses the classes shown in the diagram below.
+
+image:../images/Log4jClasses.jpg[Log4j 2 Class Relationships,title="Log4j 2
Class Relationships"]
+
+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.
+
+=== Logger Hierarchy
+
+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.
+
+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.
+
+Loggers and LoggerConfigs are named entities. Logger names are
+case-sensitive and they follow the hierarchical naming rule:
+
+Named Hierarchy::
+A LoggerConfig is said to be an _ancestor_ of another LoggerConfig if
+its name followed by a dot is a prefix of the _descendant_ logger
+name. A LoggerConfig is said to be a _parent_ of a _child_
+LoggerConfig if there are no ancestors between itself and the
+descendant LoggerConfig.
+
+For example, the LoggerConfig named `"com.foo"` is a parent of the
+LoggerConfig named `"com.foo.Bar"`. Similarly, `"java"` is a parent of
+`"java.util"` and an ancestor of `"java.util.Vector"`. This naming
+scheme should be familiar to most developers.
+
+The root LoggerConfig resides at the top of the LoggerConfig hierarchy.
+It is exceptional in that it always exists and it is part of every
+hierarchy. A Logger that is directly linked to the root LoggerConfig can
+be obtained as follows:
+
+[source,java]
+----
+Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);
+----
+
+Alternatively, and more simply:
+
+[source,java]
+----
+Logger logger = LogManager.getRootLogger();
+----
+
+All other Loggers can be retrieved using the
+link:../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.String)[`LogManager.getLogger`]
+static method by passing the name of the desired Logger. Further
+information on the Logging API can be found in the
+link:../log4j-api/api.html[Log4j 2 API].
+
+=== LoggerContext
+
+The
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/LoggerContext.html[`LoggerContext`]
+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
+link:logsep.html[Log Separation] section.
+
+=== Configuration
+
+Every LoggerContext has an active
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/config/Configuration.html[`Configuration`].
+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.
+
+=== Logger
+
+As stated previously, Loggers are created by calling
+link:../log4j-api/apidocs/org/apache/logging/log4j/LogManager.html#getLogger(java.lang.String)[`LogManager.getLogger`].
+The Logger itself performs no direct actions. It simply has a name and
+is associated with a LoggerConfig. It extends
+link:../log4j-api/apidocs/org/apache/logging/log4j/spi/AbstractLogger.html[`AbstractLogger`]
+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.
+
+Retrieving Loggers
+
+Calling the `LogManager.getLogger` method with the same name will always
+return a reference to the exact same Logger object.
+
+For example, in
+
+[source,java]
+----
+Logger x = LogManager.getLogger("wombat");
+Logger y = LogManager.getLogger("wombat");
+----
+
+`x` and `y` refer to _exactly_ the same Logger object.
+
+Configuration of the log4j environment is typically done at application
+initialization. The preferred way is by reading a configuration file.
+This is discussed in link:configuration.html[Configuration].
+
+Log4j makes it easy to name Loggers by _software component_. 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.
+
+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.
+
+Nevertheless, naming loggers after the class where they are located
+seems to be the best strategy known so far.
+
+=== LoggerConfig
+
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/config/LoggerConfig.html[`LoggerConfig`]
+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.
+
+==== Log Levels
+
+LoggerConfigs will be assigned a Log
+link:../log4j-api/apidocs/org/apache/logging/log4j/Level.html[`Level`].
+The set of built-in levels includes ALL, TRACE, DEBUG, INFO, WARN, ERROR,
+FATAL, and OFF. Log4j 2 also supports link:customloglevels.html[custom log
+levels]. Another mechanism for getting more granularity is to use
+link:../log4j-api/api.html#Markers[Markers] instead. The OFF and ALL
+levels are not intended to be used on calls to the logging API.
+Specifying OFF in the configuration implies no logging events should
+match while specifying ALL would mean all events match, including custom
+events. However, OFF can be used on logging API calls in special cases
+where the event should always be logged regardless of the configuration.
+However, it is generally recommended that a Marker with a corresponding
+global Marker Filter be used instead.
+
+http://logging.apache.org/log4j/1.2/manual.html[Log4j 1.x] and
+http://logback.qos.ch/manual/architecture.html#effectiveLevel[Logback]
+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.
+
+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.
+
+.Example 1
+[cols=",,,",options="header",]
+|====================================================================
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |Logger Level
+|root |root |DEBUG |DEBUG
+|X |root |DEBUG |DEBUG
+|X.Y |root |DEBUG |DEBUG
+|X.Y.Z |root |DEBUG |DEBUG
+|====================================================================
+
+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.
+
+.Example 2
+[cols=",,,",options="header",]
+|=============================================================
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |Level
+|root |root |DEBUG |DEBUG
+|X |X |ERROR |ERROR
+|X.Y |X.Y |INFO |INFO
+|X.Y.Z |X.Y.Z |WARN |WARN
+|=============================================================
+
+In example 2, all loggers have a configured LoggerConfig and obtain
+their Level from it.
+
+.Example 3
+[cols=",,,",options="header",]
+|=============================================================
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |Level
+|root |root |DEBUG |DEBUG
+|X |X |ERROR |ERROR
+|X.Y |X |ERROR |ERROR
+|X.Y.Z |X.Y.Z |WARN |WARN
+|=============================================================
+
+In example 3, the loggers`root`, `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.
+
+.Example 4
+[cols=",,,",options="header",]
+|=============================================================
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |level
+|root |root |DEBUG |DEBUG
+|X |X |ERROR |ERROR
+|X.Y |X |ERROR |ERROR
+|X.Y.Z |X |ERROR |ERROR
+|=============================================================
+
+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.
+
+.Example 5
+[cols=",,,",options="header",]
+|=============================================================
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |level
+|root |root |DEBUG |DEBUG
+|X |X |ERROR |ERROR
+|X.Y |X.Y |INFO |INFO
+|X.YZ |X |ERROR |ERROR
+|=============================================================
+
+In example 5, the loggers`root`.`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.
+
+.Example 6
+[cols=4*,options="header"]
+|===
+|Logger Name |Assigned LoggerConfig |LoggerConfig Level |Level
+|root |root |DEBUG |DEBUG
+|X |X |ERROR |ERROR
+|X.Y |X.Y | |ERROR
+|X.Y.Z |X.Y | |ERROR
+|===
+
+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.
+
+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).
+
+[cols=8*,options="header"]
+|===
+|Event Level
+7+|LoggerConfig Level
+
+| |`TRACE` |`DEBUG` |`INFO` |`WARN` |`ERROR` |`FATAL` |`OFF`
+
+|`ALL` |❌ |❌ |❌ |❌ |❌ |❌ |❌
+
+|`TRACE` |✅ |❌ |❌ |❌ |❌ |❌ |❌
+
+|`DEBUG` |✅ |✅ |❌ |❌ |❌ |❌ |❌
+
+|`INFO` |✅ |✅ |✅ |❌ |❌ |❌ |❌
+
+|`WARN` |✅ |✅ |✅ |✅ |❌ |❌ |❌
+
+|`ERROR` |✅ |✅ |✅ |✅ |✅ |❌ |❌
+
+|`FATAL` |✅ |✅ |✅ |✅ |✅ |✅ |❌
+
+|`OFF` |✅ |✅ |✅ |✅ |✅ |✅ |✅
+|===
+
+=== Filter
+
+In addition to the automatic log Level filtering that takes place as
+described in the previous section, Log4j provides
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/Filter.html[`Filter`]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.
+
+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.
+
+=== Appender
+
+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
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/Appender.html[`Appender`].
+Currently, appenders exist for the console, files, remote socket
+servers, Apache Flume, remote UNIX Syslog daemons, and various
+database APIs. See the section on link:appenders.html[Appenders] for
+more details on the various types available. More than one Appender can
+be attached to a Logger.
+
+An Appender can be added to a Logger by calling the
+link:../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`]
+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.
+
+*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.* 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 _C_, then enabled logging requests for _C_
+and _C_'s children will print in a file _and_ on the console. It is
+possible to override this default behavior so that Appender accumulation
+is no longer additive by setting `additivity="false"` on the Logger
+declaration in the configuration file.
+
+The rules governing appender additivity are summarized below.
+
+Appender Additivity::
+The output of a log statement of Logger _L_ will go to all the
+Appenders in the LoggerConfig associated with _L_ and the ancestors of
+that LoggerConfig. This is the meaning of the term "appender
+additivity".
++
+However, if an ancestor of the LoggerConfig associated with Logger
+_L_, say _P_, has the additivity flag set to `false`, then _L_'s
+output will be directed to all the appenders in _L_'s LoggerConfig and
+it's ancestors up to and including _P_ but not the Appenders in any of
+the ancestors of _P_.
++
+Loggers have their additivity flag set to `true` by default.
+
+The table below shows an example:
+
+|===
+|Logger Name |Added Appenders |Additivity Flag |Output Targets |Comment
+
+|root
+|A1
+|not applicable
+|A1
+|The root logger has no parent so additivity does not apply to it.
+
+|x
+|A-x1, A-x2
+|true
+|A1, A-x1, A-x2
+|Appenders of "x" and root.
+
+|x.y
+|none
+|true
+|A1, A-x1, A-x2
+|Appenders of "x" and root. It would not be typical to configure a Logger with
no Appenders.
+
+|x.y.z
+|A-xyz1
+|true
+|A1, A-x1, A-x2, A-xyz1
+|Appenders in "x.y.z", "x" and root.
+
+|security
+|A-sec
+|false
+|A-sec
+|No appender accumulation since the additivity flag is set to `false`.
+
+|security.access
+|none
+|true
+|A-sec
+|Only appenders of "security" because the additivity flag in "security" is set
to `false`.
+|===
+
+=== Layout
+
+More often than not, users wish to customize not only the output
+destination but also the output format. This is accomplished by
+associating a
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/Layout.html[`Layout`]
+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
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/layout/PatternLayout.html[`PatternLayout`],
+part of the standard log4j distribution, lets the user specify the
+output format according to conversion patterns similar to the C language
+`printf` function.
+
+For example, the PatternLayout with the conversion pattern "%r [%t] %-5p
+%c - %m%n" will output something akin to:
+
+....
+176 [main] INFO org.foo.Bar - Located nearest gas station.
+....
+
+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.
+
+Log4j comes with many different link:layouts.html[Layouts] 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.
+
+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.
+
+=== StrSubstitutor and StrLookup
+
+The
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrSubstitutor.html[`StrSubstitutor`]
+class and
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/StrLookup.html[`StrLookup`]
+interface were borrowed from
+https://commons.apache.org/proper/commons-lang/[Apache Commons Lang] and
+then modified to support evaluating LogEvents. In addition the
+link:../log4j-core/apidocs/org/apache/logging/log4j/core/lookup/Interpolator.html[`Interpolator`]
+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 link:lookups.html[Lookups]
+for more information.
diff --git a/src/site/xdoc/manual/architecture.xml
b/src/site/xdoc/manual/architecture.xml
deleted file mode 100644
index 807bac20f1..0000000000
--- a/src/site/xdoc/manual/architecture.xml
+++ /dev/null
@@ -1,741 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Licensed to the Apache Software Foundation (ASF) under one or more
- ~ contributor license agreements. See the NOTICE file distributed with
- ~ this work for additional information regarding copyright ownership.
- ~ The ASF licenses this file to you under the Apache License, Version 2.0
- ~ (the "License"); you may not use this file except in compliance with
- ~ the License. You may obtain a copy of the License at
- ~
- ~ http://www.apache.org/licenses/LICENSE-2.0
- ~
- ~ Unless required by applicable law or agreed to in writing, software
- ~ distributed under the License is distributed on an "AS IS" BASIS,
- ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- ~ See the License for the specific language governing permissions and
- ~ limitations under the License.
- -->
-<document xmlns="http://maven.apache.org/XDOC/2.0"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/XDOC/2.0
http://maven.apache.org/xsd/xdoc-2.0.xsd">
- <properties>
- <title>Log4j 2 Architecture</title>
- <author email="[email protected]">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 ALL, TRACE, DEBUG, INFO, WARN, ERROR, FATAL, and
OFF. 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.
- The OFF and ALL levels are not intended to be used on calls to the
logging API. Specifying OFF in the
- configuration implies no logging events should match while
specifying ALL would mean all events match,
- including custom events. However, OFF can be used on logging API
calls in special cases where the event
- should always be logged regardless of the configuration. However, it
is generally recommended that a Marker
- with a corresponding global Marker Filter be used instead.
- </p>
- <p>
- <a href="https://logging.apache.org/log4j/1.2/manual.html">Log4j
1.x</a>
- and
- <a
href="https://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">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>
- <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">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">YES</td>
- </tr>
- </table>
-
- <h4>Filter</h4>
- <p>In addition to the automatic log Level filtering that takes place
as described in the previous
- section, Log4j provides
- <a
href="../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>