`

Log4j2架构及概念简介

 
阅读更多

log4j——Log for java。

此文为读log4j2 user guaid时的翻译及笔记。log4j2与log4j在Logger的继承关系和配置方式上都做出了修改。个人感觉比较有意思的是Logger对象与LoggerConfig解耦的设计,以及Filter中的传递机制,有点像网络包分发,不过多了很多可调控性。

前言

log4j2可以按照开发人员预先的设定,在指定的位置和情况下打印log语句,并且可以酌情关闭某些log语句,如开发阶段debug类型的语句等。并且,可以使用layout来定义输出语句的格式,像C语言的printf函数一样。如:

要实现这样标准化的日志输出,只需要在工程中引入log4j2的相关jar包,并向LogManager对象申请一个Logger对象的引用,然后调用该对象的相应方法即可,如:

在log4j2中,一共有五种log level,分别为TRACE, DEBUG,INFO, WARN, ERROR 以及FATAL

 

  • FATAL:用在极端的情形中,即必须马上获得注意的情况。这个程度的错误通常需要触发运维工程师的寻呼机。
  • ERROR:显示一个错误,或一个通用的错误情况,但还不至于会将系统挂起。这种程度的错误一般会触发邮件的发送,将消息发送到alert list中,运维人员可以在文档中记录这个bug并提交。
  • WARN:不一定是一个bug,但是有人可能会想要知道这一情况。如果有人在读log文件,他们通常会希望读到系统出现的任何警告。
  • INFO用于基本的、高层次的诊断信息。在长时间运行的代码段开始运行及结束运行时应该产生消息,以便知道现在系统在干什么。但是这样的信息不宜太过频繁。
  • DEBUG:用于协助低层次的调试。
  • TRACE:用于展现程序执行的轨迹。

 

Log4j2类图

 

通过类图可用看到:

每一个log上下文对应一个configuration,configuration中详细描述了log系统的各个LoggerConfig、Appender(输出目的地)、EventLog过滤器等。每一个Logger又与一个LoggerConfig相关联。另外,可以看到Filter的种类很多,有聚合在Configuration中的filter、有聚合在LoggerConfig中的filter也有聚合在Appender中的filter。不同的filter在过滤LogEvent时的行为和判断依据是不同的,具体可参加本文后面给出的文档。

应用程序通过调用log4j2API并传入一个特定的名称来向LogManager请求一个Logger实例。LogManager会定位到适当的 LoggerContext 然后通过它获得一个Logger。如果LogManager不得不新建一个Logger,那么这个被新建的Logger将与LoggerConfig相关联,这个LoggerConfig的名称中包含如下信息中的一种:①与Logger名称相同的②父logger的名称③ root 。当一个LoggerConfig的名称与一个Logger的名称可以完全匹配时,Logger将会选择这个LoggerConfig作为自己的配置。如果不能完全匹配,那么Logger将按照最长匹配串来选择自己所对应的LoggerConfigLoggerConfig对象是根据配置文件来创建的。LoggerConfig会与Appenders相关联,Appenders用来决定一个log request将被打印到那个目的地中,可选的打印目的地很多,如console、文件、远程socket server等。。LogEvent是由Appenders来实际传递到最终输出目的地的,而在EvenLog到达最终被处理之前,还需要经过若干filter的过滤,用来判断该EventLog应该在何处被转发、何处被驳回、何处被执行。

Log4j中各个概念的简要介绍

Logger间的层次关系

相比于纯粹的System.out.println方式,使用logging API的最首要以及最重要的优势是可以在禁用一些log语句块的同时允许其他的语句块的输出。这一能力建立在一种假设之上,即所有在应用中可能出现的logging语句可以按照开发者定义的标准分成不同的类型。

在 Log4j 1.x版本时,Logger的层次是靠Logger类之间的关系来维护的。但在Log4j2中, Logger的层次则是靠LoggerConfig对象之间的关系来维护的。

LoggerLoggerConfig均是有名称的实体。Logger的命名是大小写敏感的,并且服从如下的分层命名规则。(与java包的层级关系类似)。例如:com.foocom.foo.Bar的父级;javajava.util的父级,是java.util.vector的祖先。

 root LoggerConfig位于LoggerConfig层级关系的最顶层。它将永远存在与任何LoggerConfig层次中。任何一个希望与root LoggerConfig相关联的Logger可以通过如下方式获得:

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

其他的Logger实例可以调用LogManager.getLogger 静态方法并传入想要得到的Logger的名称来获得。

 

LoggerContext

LoggerContextLogging System中扮演了锚点的角色。根据情况的不同,一个应用可能同时存在于多个有效的LoggerContext中。在同一LoggerContext下,log system是互通的。如:Standalone ApplicationWeb ApplicationsJava EE Applications"Shared" Web Applications REST Service Containers,就是不同广度范围的log上下文环境。

 

Configuration

每一个LoggerContext都有一个有效的ConfigurationConfiguration包含了所有的Appenders、上下文范围内的过滤器、LoggerConfigs以及StrSubstitutor.的引用。在重配置期间,新与旧的Configuration将同时存在。当所有的Logger对象都被重定向到新的Configuration对象后,旧的Configuration对象将被停用和丢弃。

 

Logger

如前面所述, Loggers 是通过调用LogManager.getLogger方法获得的。Logger对象本身并不实行任何实际的动作。它只是拥有一个name 以及与一个LoggerConfig相关联。它继承了AbstractLogger类并实现了所需的方法。当Configuration改变时,Logger将会与另外的LoggerConfig相关联,从而改变这个Logger的行为。

获得Logger

使用相同的名称参数来调用getLogger方法将获得来自同一个Logger的引用。如:

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

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

xy指向的是同一个Logger对象。

log4j环境的配置是在应用的启动阶段完成的。优先进行的方式是通过读取配置文件来完成。

log4j使采用类名(包括完整路径)来定义Logger 名变得很容易。这是一个很有用且很直接的Logger命名方式。使用这种方式命名可以很容易的定位这个log message产生的类的位置。当然,log4j也支持任意string的命名方式以满足开发者的需要。不过,使用类名来定义Logger名仍然是最为推崇的一种Logger命名方式。

 

LoggerConfig

Loggerconfiguration中被描述时,LoggerConfig对象将被创建。LoggerConfig包含了一组过滤器。LogEvent在被传往Appender之前将先经过这些过滤器。过滤器中包含了一组Appender的引用。Appender则是用来处理这些LogEvent的。

Log层次:

每一个LoggerConfig会被指定一个Log层次。可用的Log层次包括TRACE, DEBUG,INFO, WARN, ERROR 以及FATAL。需要注意的是,在log4j2中,Log的层次是一个Enum型变量,是不能继承或者修改的。如果希望获得跟多的分割粒度,可用考虑使用Markers来替代。

Log4j 1.x Logback 中都有“层次继承”这么个概念。但是在log4j2中,由于LoggerLoggerConfig是两种不同的对象,因此“层次继承”的概念实现起来跟Log4j 1.x Logback不同。具体情况下面的五个例子。

例子一:

可用看到,应用中的LoggerConfig只有root这一种。因此,对于所有的Logger而言,都只能与该LoggerConfig相关联而没有别的选择。

例子二:

在例子二中可以看到,有5种不同的LoggerConfig存在于应用中,而每一个Logger都被与最匹配的LoggerConfig相关联着,并且拥有不同的Log Level

例子三:

可以看到Logger rootXX.Y.Z都找到了与各种名称相同的LoggerConfig。而LoggerX.Y没有与其名称相完全相同的LoggerConfig。怎么办呢?它最后选择了X作为它的LoggerConfig,因为X LoggerConfig拥有与其最长的匹配度。

例子四:

可以看到,现在应用中有两个配置好的LoggerConfigrootX。而Logger有四个:rootXX.YX.Y.Z。其中,rootX都能找到完全匹配的LoggerConfig,而X.YX.Y.Z则没有完全匹配的LoggerConfig,那么它们将选择哪个LoggerConfig作为自己的LoggerConfig呢?由图上可知,它们都选择了X而不是root作为自己的LoggerConfig,因为在名称上,X拥有最长的匹配度。

例子五

可以看到,现在应用中有三个配置好的LoggerConfig,分别为:rootXX.Y。同时,有四个Logger,分别为:rootXX.Y以及X.YZ。其中,名字能完全匹配的是rootXX.Y。那么剩下的X.YZ应该匹配X还是匹配X.Y呢?答案是X。因为匹配是按照标记点(即“.”)来进行的,只有两个标记点之间的字串完全匹配才算,否则将取上一段完全匹配的字串的长度作为最终匹配长度。

 

Filter

与防火墙过滤的规则相似,log4j2的过滤器也将返回三类状态:Accept(接受), Deny(拒绝) 或Neutral(中立)。其中,Accept意味着不用再调用其他过滤器了,这个LogEvent将被执行;Deny意味着马上忽略这个event,并将此event的控制权交还给过滤器的调用者;Neutral则意味着这个event应该传递给别的过滤器,如果再没有别的过滤器可以传递了,那么就由现在这个过滤器来处理。

 

Appender

logger的不同来决定一个logging request是被禁用还是启用只是log4j2的情景之一。log4j2还允许将logging requestlog信息打印到不同的目的地中。在log4j2的世界里,不同的输出位置被称为Appender。目前,Appender可以是console、文件、远程socket服务器、Apache FlumeJMS以及远程 UNIX 系统日志守护进程。一个Logger可以绑定多个不同的Appender

可以调用当前ConfigurationaddLoggerAppender函数来为一个Logger增加。如果不存在一个与Logger名称相对应的LoggerConfig,那么相应的LoggerConfig将被创建,并且新增加的Appender将被添加到此新建的LoggerConfig中。尔后,所有的Loggers将会被通知更新自己的LoggerConfig引用(PS:一个LoggerLoggerConfig引用是根据名称的匹配长度来决定的,当新的LoggerConfig被创建后,会引发一轮配对洗牌)。

在某一个Logger中被启用的logging request将被转发到该Logger相关联的的所有Appenders上,并且还会被转发到LoggerConfig的父级的Appenders上。

这样会产生一连串的遗传效应。例如,对LoggerConfig B来说,它的父级为AA的父级为root。如果在root中定义了一个Appenderconsole,那么所有启用了的logging request都会在console中打印出来。另外,如果LoggerConfig A定义了一个文件作为Appender,那么使用LoggerConfig ALoggerConfig Blogger logging request都会在该文件中打印,并且同时在console中打印。

如果想避免这种遗传效应的话,可以在configuration文件中做如下设置:

additivity="false"

这样,就可以关闭Appender的遗传效应了。具体解释见:

 

Layout

通常,用户不止希望能定义log输出的位置,还希望可以定义输出的格式。这就可以通过将Appender与一个layout相关联来实现。Log4j中定义了一种类似C语言printf函数的打印格式,如"%r [%t] %-5p %c - %m%n" 格式在真实环境下会打印类似如下的信息:

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

其中,各个字段的含义分别是:

%r 指的是程序运行至输出这句话所经过的时间(以毫秒为单位);

%t 指的是发起这一log request的线程;

%c 指的是loglevel

%m 指的是log request语句携带的message

%n 为换行符。

 

 Reference

log4j user guide

分享到:
评论

相关推荐

    apache-log4j-2.4.1-bin.zip

    在本文中,我们将深入探讨Log4j 2的核心概念和主要功能。 **1. 性能优化** Log4j 2通过引入新的日志事件处理机制和Async Appenders,极大地提高了日志记录的性能。Async Appenders利用Java的并发库,实现了非阻塞的...

    Log4j2效率测试源码

    - **异步日志记录**:Log4j2引入了异步日志记录的概念,通过使用Apache的LMAX Disruptor库,实现了零锁并发模型,大大提高了多线程环境下的性能。 - **动态配置**:Log4j2允许在运行时动态更改日志级别和配置,...

    log4j-1.2.13-src

    本文将围绕log4j的核心概念、设计模式、主要组件以及其实现细节进行详细的探讨。 一、Log4j概述 Log4j是一个开源的日志记录库,旨在为应用程序提供灵活且高效的日志记录功能。它允许开发者调整日志级别,控制日志...

    apache-log4j-2.8.2-bin.tar

    5. **异步日志记录**:Log4j 2引入了异步日志记录的概念,通过使用LMAX Disruptor库实现无锁数据结构,提高了日志处理的速度,减少了系统资源的消耗。在2.8.2版本中,这部分可能进行了优化,提供更好的性能。 6. **...

    log4j api log4j

    Log4j架构** Log4j由三个主要组件构成:Logger(日志器)、Layout(布局)和Appender(输出端)。Logger负责生成日志事件,Layout负责格式化这些事件,而Appender则负责将格式化的日志输出到目标位置,如控制台、...

    Log4j工程官方源码

    Log4j是Apache组织开发的一款广泛使用的Java日志框架,它的全名是Apache Log4j 2。这个压缩包文件包含的是Log4j的官方源码,对于开发者来说,能够直接导入到Eclipse中进行学习和研究,或者进行二次开发,具有很高的...

    log4j-user-guide

    2. 架构(Architecture):这一部分可能会深入探讨Log4j的内部组件和工作原理,例如解释它是如何将日志消息从应用程序代码中分离出来,并通过配置的Appenders将日志消息发送到不同的目的地。 3. Log4j 1.x迁移(Log...

    Log4J 2 和 Log4j 的jar 包

    除了基本的日志记录功能,Log4j 2 还支持插件架构,这意味着可以添加额外的功能,如日志过滤、布局模板、Appender(日志输出目的地)等。例如,你可以将日志输出到控制台、文件、数据库、甚至是远程服务器。其中,...

    纯struts2开发带log4j的用户登录demo

    在本示例中,"纯struts2开发带log4j的用户登录demo"是教你如何利用Struts2框架来实现一个简单的用户登录功能,并结合log4j进行日志记录。Log4j是一个广泛使用的日志记录工具,它提供了灵活的日志配置,有助于调试、...

    Log4j学习资料大全

    这份文档通常会详细介绍Log4j的基本概念、架构以及其在项目中的重要性。Log4j的核心组件包括Logger、Appender和Layout。Logger负责生成日志事件,Appender则负责将这些事件输出到指定的目标,如控制台、文件或远程...

    写的ssh+log4j的Simple

    在IT行业中,SSH和Log4j是两个非常重要的概念,特别是在Java后端开发领域。SSH通常指的是Spring、Struts和Hibernate这三个开源框架的首字母缩写,它们是Java Web开发中的三大支柱,提供了模型-视图-控制器(MVC)...

    log4j相关文档

    这个压缩包包含了关于Log4j的三个学习资料,分别是"Log4j入门与详解.pdf"、"Log4j使用方法.pdf"和"如何使用Log4j.txt",这些文档将帮助我们深入了解和掌握Log4j的核心概念和实际应用。 首先,"Log4j入门"这份文档...

    log4j完全参考手册

    #### 二、log4j的架构概览 **log4j**的核心组件主要包括Logger、Appender、Layout三个部分: - **Logger**:负责接收应用程序中的日志消息,并将其传递给相应的Appender进行处理。 - **Appender**:定义了日志消息...

    apache-log4j-2.12.4-bin.zip

    此外,Log4j 2引入了插件架构,这使得扩展和定制变得更加简单。通过添加新的Appenders、Filters、Layouts或其他组件,开发者可以实现自定义的日志行为。例如,如果你需要将日志信息发送到云存储服务或监控工具,可以...

    纯净版SpringMVC+Ibatis+log4j环境

    在这个“纯净版SpringMVC+Ibatis+log4j环境”中,我们将深入探讨这三个组件的核心概念、功能以及它们如何协同工作。 **SpringMVC** 是Spring框架的一部分,它是一个Model-View-Controller(MVC)框架,用于处理Web...

    log4j 教程

    开发者应充分理解log4j的架构和配置原理,以便在实际项目中有效地利用log4j提升应用的监控和调试能力。 以上是对log4j核心概念和使用技巧的详细介绍,希望能帮助读者深入掌握log4j,为日常的开发工作带来便利。

    Flume + kafka + log4j构建日志采集系统

    **步骤2:配置log4j** - 配置log4j.properties:在应用中配置log4j,指定日志级别、格式,并创建一个自定义Appender,该Appender与Flume agent通信,将日志发送到Flume。 **步骤3:搭建Kafka** - 安装和启动Kafka...

    深入学习LOG4J

    2. **LOG4J架构** LOG4J主要由三个核心组件构成:Logger(日志器)、Appender(输出器)和Layout(布局)。Logger负责创建和管理日志事件,Appender决定日志信息的输出目的地,如控制台、文件、数据库等,而Layout...

    log4j2.0教程(英文版)

    ### Log4j 2.0 教程及使用手册知识点概览 #### 1.1 欢迎使用 Log4j 2! ##### 1.1.1 引言 几乎每一个大型应用都有其自己的日志或跟踪API。遵循这一规则,E.U.SEMPER项目在1996年初决定编写其自己的跟踪API。经过...

    log4j-users-guide.pdf

    Apache Log4j 2 用户指南是一份详细的中文文档,涵盖了从基本概念到高级特性的全面介绍,旨在帮助用户理解和使用这个流行的Java日志框架。以下是该文档中的关键知识点概述: 1. **简介**:Log4j是Apache软件基金会...

Global site tag (gtag.js) - Google Analytics