Log4j 2架构

Posted 小杨Vita

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Log4j 2架构相关的知识,希望对你有一定的参考价值。

本文译自:
http://logging.apache.org/log4j/2.x/maven-artifacts.html

详细目录
Apache Log4j 2 中文文档

主要组件

Log4j 使用到了下图中的类。

使用 Log4j 2 API 时,应用需要从 LogManager 处获取一个有特定名字的 Logger。而 LogManager 则是查找出一个合理的 LoggerContext,并从中获取到Logger。当 Logger 被创建时它将与 LoggerConfig 关联,LoggerConfig 包含了要么是当前 Logger 类路径,要么是母包路径,要么就是根LoggerConfig 。LoggerConfig 对象由 Logger 基于配置文件中的声明来创建,它所关联的 Appender 则用于传递 LogEvent 。

Logger 层次

相比于普通的System.out.println,日志API最重要的优势在于它可以在打印某些级别日志的同时还能禁用某些级别的打印。这种能力使得开发者可以依照自己的标准来对日志进行归类。

在 Log4j 1.x 中 Logger 层次由 Logger 之间的关系来维持。然而在 Log4j 2 里,这种关系已不复存在,取而代之的是由 LoggerConfig 对象来维护这一关系。

Logger 和 LoggerConfig 都被称之为实体,Logger 名大小写敏感,并遵循层次命名规则:

命名层次
当我们说 LoggerConfig A 是 LoggerConfig B 的祖先时,这意味着A的名字加上“.”是B的名字的前缀。
当A与B之前没有其他东西时,那么A为父LoggerConfig ,B为子LoggerConfig 。

比如名为 “com.foo”的 LoggerConfig 是名为 “com.foo.Bar” 的 LoggerConfig 的父亲。类似的, “java”是 “java.util” 的父亲,是”java.util.Vector”的祖先。

根LoggerConfig 位于 LoggerConfig 层次的顶部,它始终存在。一个 Logger 可以通过以下方式与根LoggerConfig关联:

Logger logger = LogManager.getLogger(LogManager.ROOT_LOGGER_NAME);

或者更简单地:

Logger logger = LogManager.getRootLogger();

我们可通过为静态方法 LogManager.getLogger传递一个名字来获得想要的 Logger。

LoggerContext

LoggerContext 在日志系统中扮演着锚点的角色,然而依据不同的应用环境可能存在多个有效的LoggerContext,更多细节可查看 日志隔离 章节。

Configuration

每一个 LoggerContext 都有一个有效的 Configuration, Configuration 包含所有的Appender 、Filter、LoggerConfig 以及StrSubstitutor引用。在修改配置后两个 Configuration 对象会同时存在,一旦所有的 Logger 都已重定向到新的 Configuration上时,老的Configuration就会被停止并弃用。

Logger

Logger 继承自 AbstractLogger 并实现了所需的方法。当配置被修改后,它将与不同的 LoggerConfig 相关联,这导致其行为也被改变。

获取Logger

使用相同的名字调用 LogManager.getLogger方法将会的到相同的Logger。例如

Logger x = LogManager.getLogger("wombat");
Logger y = LogManager.getLogger("wombat");

其中x和y是同一个对象。

通常Logger名为定义时的类限定名,这样方便定位问题,但开发者仍可以按需自由定义所要的名字。鉴于前者为人们约定俗成的规则,不带参数调用LogManager.getLogger()将自动使用当前类的全限定名。

LoggerConfig

LoggerConfig 对象在 Logger 被声明时创建,它包含了一组用于处理事件的Appender引用,以及一组用于过滤传递给Appender事件的Filter。

日志级别

LoggerConfig会被分配一个日志级别,内建的级别包含TRACE, DEBUG, INFO, WARN, ERROR 和 FATAL。Log4j 2 还支持自定义日志级别,此外另一种可获得更多粒度的方式便是使用Marker。

Log4j 1.x 和Logback 都使用了“级别继承”的概念。在Log4j 2中Logger和LoggerConfig是两个不同的对象,所以这种概念实现起来也有所不同。每个 Logger 引用到的 LoggerConfig 都带有父辈的引用,这样便可以达到相似的效果。

日志级别的继承就不细说了,大意就是如果X.Y.Z的级别未定义,那么默认使用X.Y的LoggerConfig 的级别,如果X.Y也没定义,那么使用X的,一直到使用root的,根LoggerConfig的默认级别为DEBUG。

Filter

Log4j 提供了Filter 来过滤消息事件,它可被应用于事件传递给LoggerConfig之前,及传递给LoggerConfig之后但在调用任一/特定Appender之前。类似于防火墙,Filter将返回三种结果: Accept, DenyNeutral。“接受”意味该事件不必再经过其他Filter,可直接被处理;“拒绝”意味着事件将立即被忽略,控制权返回给调用者;“中立”意味着事件应由其他Filter来处理。如果未配置任何Filter,那么事件将直接被处理。

当事件被前置LoggerConfig Filter通过后,仍有可能被LoggerConfig Filter或Appender拒绝。

Appender

选择性地启用或禁用记录请求的能力只是Log4j 的一部分功能,Log4j 还允许将记录请求输出到多个目标中,而这种输出目标被称为Appender。目前appender的类型有控制台、文件、远程套接字服务器、Apache Flume、JMS、远程UNIX 系统日志守护进程以及各种数据库API。更多细节可查看Appenders章节。此外,一个Logger可以关联多个Appender。

通过addLoggerAppender方法可以为Logger添加上Appender。如果符合Logger名字的LoggerConfig 还未被创建,那么它将被自动创建,并关联上Appender,然后所有的Logger(通常为子类)都会被通知升级它们的LoggerConfig引用。

logger的每一个记录请求都将被发送到其所有appender中,同样也会发送到父LoggerConfig的appender中。换句话说,Appender是依照LoggerConfig的层级关系附加继承的。比如一个控制台appender如果被加到了根logger中,那么所有的记录请求都会打印到控制台。当然我们可以在配置文件中使用additivity="false"来禁用这种默认功能。

Layout

用户往往不仅希望自定义输出目标,还希望自定义输出格式。这一功能由与Appender关联的Layout来实现。Layout 负责对日志事件进行格式化,而Appender 则负责将格式化后的输出发送到指定位置。其中 PatternLayout 可以让用户使用类似C语言中printf的方式来进行格式化输出。

比如,格式为”%r [%t] %-5p %c - %m%n” 的 PatternLayout 将输出:

176 [main] INFO  org.foo.Bar - Located nearest gas station.

Log4j 具有多种不同的Layout来满足例如JSON、XML、html和Syslog等用户场景。而其他的appender(如数据库连接)需要填充特定的字段,而非特殊的文本结构。

同样重要的是 log4j 可以根据用户指定的规则来呈现日志信息的内容。比如若你需要频繁打印项目中的自定义对象,如Orange,那么你可以创建一个OrangeMessage 来接收传递到 log4j 的 Orange 对象,它将被按要求格式化为合适的字节数组。

StrSubstitutor 和 StrLookup

StrSubstitutor 类和 StrLookup 接口来自于 Apache Commons Lang,并被修改为支持LogEvent的赋值。此外,来自 Apache Commons Configuration 的Interpolator类允许StrSubstitutor从多个 StrLookup中进行变量赋值。同时它们还提供了从系统属性、配置文件、ThreadContext Map、LogEvent中的StructuredData 中读取引用变量的机制。这些变量解析既可以发生在配置被处理时,也可以发生在事件被处理时。详情请看LookUp

转载请注明出处:http://blog.csdn.net/yangcheng33/article/details/78172526

以上是关于Log4j 2架构的主要内容,如果未能解决你的问题,请参考以下文章

Log4j 2架构

集成log4jlog4j2logback与elk

转转架构统一日志配置文件log4j2.xml的实践

日志架构log4j基本使用

Log4J2.xml 配置文件详解

Log4j爆核弹级漏洞,大厂中招公司炸锅了...