下图是Log4j官网给出的类图:
我们先依次看一下每个类的定义是什么。
LoggerContext
// todo 不太理解
Configuration
Configuration
类对应的是正在使用的配置文件,例如 log4j2.xml
。它包含了所有可用的 Appender
、 LoggerConfig
、以及 Filter
的定义。
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.
在重新配置时(即配置文件有改动时),可能会并存两个 Configuration
对象。一旦所有的 Logger
都被重定向到新的配置,旧配置对应的 Configuration
对象就会被废弃。
Logger
Logger
对象通过 LogManager.getLogger
方式获得,一般每个类都有各自的 Logger
对象,名称与该类的全量名一致。 Logger
应该只是一个接口,本身不执行任何直接操作。,拥有名字并与一个 LoggerConfig
相关联。
The Logger itself performs no direct actions. It simply has a name and is associated with a LoggerConfig.
Logger
的行为由与其关联的 LoggerConfig
控制,当其与其他的 LoggerConfig
相关联时,它的行为也会作相应的改变。
LoggerConfig
LoggerConfig
对象对应着配置文件(例如 log4j2.xml
)中的 <Logger>
。它包含了一系列 Filter
定义以及对一系列 Appender
的引用。
LoggerConfig objects are created when Loggers are declared in the logging configuration.
Log4j 1.x与Log4j 2.x的不同在于,日志的层次结构发生了变化。在1.x中,日志的层次结构是通过 Logger
之间的关系维护的,而在2.x中,是用 LoggerConfig
对象之间的关系维护的。
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.
在Log4j 2.x中, Logger
和 LoggerConfig
会根据名称进行关联,而且它们的命名都满足如下的层次关系:
名为 java
的 LoggerConfig
是名为 java.util
的 LoggerConfig
父 配置,是名为 java.util.Vector
的 LoggerConfig
的 祖先 配置。
反过来,名为 java.util.Vector
的 LoggerConfig
是名为 java.util
的 LoggerConfig
的 子 配置,是名为 java
的 LoggerConfig
的 子孙 配置。
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.
Root LoggerConfig
在整个 LoggerConfig
体系的最顶层,它没有任何祖先配置。可以通过 LogManager.getLogger(LogManager.ROOT_LOGGER_NAME)
或 LogManager.getRootLogger()
的方式获得与 Root LoggerConfig
相关联的 Logger
。
在Log4j 2.x中,每个 LoggerConfig
都会被分配一个 Log level
。Log4j 2.x内建支持的 Log level
为:TRACE < DEBUG < INFO < WARN < ERROR < FATAL。除了这些内建等级,Log4j 2.x也允许用户去自定义等级(不过官方并不推荐这么做)。
除了等级机制,可以使用 Marker
机制来实现更细粒度的控制,更多信息请参考[]()。
接下来,我们用下面5组实例来介绍一下Log4j 2.x中的 Level Inheritance
(等级继承)机制。
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 |
上表中,只有名为root的 Logger
被赋予了名为root的 LoggerConfig
且 LoggerConfig
的等级为DEBUG,所以名为root的 Logger
的等级也为DEBUG。其它的 Logger
都没有特别分配 LoggerConfig
,因此会继承它们的祖先配置root。
Logger Name | Assigned LoggerConfig | LoggerConfig Level | Logger Level |
---|---|---|---|
root | root | DEBUG | DEBUG |
X | X | ERROR | ERROR |
X.Y | X.Y | INFO | INFO |
X.Y.Z | X.Y.Z | WARN | WARN |
上表中,每个 Logger
都与各自同名的 LoggerCongfig
所关联,因此它们的等级都与相关联的 LoggerConfig
的等级保持一致。
Logger Name | Assigned LoggerConfig | LoggerConfig Level | Logger Level |
---|---|---|---|
root | root | DEBUG | DEBUG |
X | X | ERROR | ERROR |
X.Y | X | ERROR | ERROR |
X.Y.Z | X.Y.Z | WARN | WARN |
上表中,唯独没有为名为X.Y的 Logger
分配同名的 LoggerConfig
,因此它将与名为X的 LoggerConfig
相关联(父配置,而非是祖先配置root)。
Logger Name | Assigned LoggerConfig | LoggerConfig Level | Logger Level |
---|---|---|---|
root | root | DEBUG | DEBUG |
X | X | ERROR | ERROR |
X.Y | X.Y | INFO | INFO |
X.YZ | X | ERROR | ERROR |
从上表中可以看出,层次结构是以 .
作为分割的,而不是最长的名称匹配长度。所以X.YZ的父配置为X,而不是X.Y。
Logger Name | Assigned LoggerConfig | LoggerConfig Level | Logger Level |
---|---|---|---|
root | root | DEBUG | DEBUG |
X | X | ERROR | ERROR |
X.Y | X.Y | ERROR | |
X.Y.Z | X.Y | ERROR |
上表中,虽然名为X.Y的 Logger
与其同名 LoggerCongfig
相关联,但未被赋予等级,将继承名为X的 LoggerConfig
的等级ERROR。
下标展示了根据等级的过滤规则:
Event Level | LoggerConfig Level | |||||||
---|---|---|---|---|---|---|---|---|
- | TRACE | DEBUG | INFO | WARN | ERROR | FATAL | OFF | |
ALL | YES | YES | YES | YES | YES | YES | YES | |
TRACE | YES | NO | NO | NO | NO | NO | NO | |
DEBUG | YES | YES | NO | NO | NO | NO | NO | |
INFO | YES | YES | YES | NO | NO | NO | NO | |
WARN | YES | YES | YES | YES | NO | NO | NO | |
ERROR | YES | YES | YES | YES | YES | NO | NO | |
FATAL | YES | YES | YES | YES | YES | YES | NO | |
OFF | NO | NO | NO | NO | NO | NO | NO |
Appender
Appender
指日志输出的目的地。Log4j 2.x支持控制台、文件、远程socket服务器、Apache Flume、JMS、远程Unix Syslog守护进程和数据库API等作为日志输出的目的地。关于这些类型的详细信息,请参考 Appenders 。
In log4j speak, an output destination is called an Appender.
Layout
Filter
StrSubsitutor
和 StrLookup