`

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

分享到:
评论

相关推荐

    log4j-1.2.13-src

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

    log4j api log4j

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

    Log4j工程官方源码

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

    Log4j学习资料大全

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

    写的ssh+log4j的Simple

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

    纯净版SpringMVC+Ibatis+log4j环境

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

    深入学习LOG4J

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

    log4j-users-guide.pdf

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

    三大框架+log4j+dom4j

    `log4`可能是log4j的一个版本或者配置文件。`dom4j`是处理XML文档的库,它提供了强大的DOM、SAX和DOM4J的API,用于读写XML文件。 `ognl-2.7.3.jar`是Object-Graph Navigation Language的缩写,是一个表达式语言,常...

    struts+spring+hibernate+log4j+dom4j等源码

    Struts、Spring、Hibernate、Log4j和Dom4j是Java开发中常用的一系列框架和技术,它们在构建大型企业级应用时发挥着至关重要的作用。接下来,我们将详细探讨这些技术的核心概念、功能以及它们如何协同工作。 1. ...

    [课堂课件讲解]Java微服务实践-Spring Boot 日志.pptx

    本资源是关于Java微服务实践的Spring Boot日志的讲解,主要介绍了日志框架Log4j的概念、架构、API和使用方法。 知识点: 1. 日志框架的概念:日志框架是一种记录和跟踪应用程序执行过程中的日志信息的系统组件。...

    C++log4cxx新手入门

    Log4cxx是Apache软件基金会开发的一个用于C++的日志框架,它是Log4j的C++版本,提供了一套高效、灵活的日志记录解决方案。本文将详细讲解如何对C++新手入门Log4cxx,帮助初学者快速掌握这一工具。 首先,我们需要...

    Asp.net Log4Net 日志实例下载

    首先,我们需要理解Log4Net的基本概念和架构。Log4Net提供了一个灵活的框架,可以方便地在代码中插入日志语句,而无需关注具体的日志实现。其主要组件包括Appenders(输出日志信息的目标)、Layouts(控制日志信息的...

    log4cplus-1.0.2-docs.tar.gz

    本文将围绕"log4cplus-1.0.2-docs.tar.gz"文档包,详细阐述log4cplus的核心概念、配置方法及实际应用。 一、log4cplus概述 log4cplus是基于C++的日志框架,它提供了灵活的配置机制、多种输出方式(如文件、控制台...

    dom4j、common-fileupload、hibernate、jdom、log4j、proxool、spring、struts、webwork等工具、框架源码

    5. **Log4j**: Log4j是Apache的一个项目,是一个广泛使用的日志记录框架。它提供了灵活的日志配置,可以输出到控制台、文件、数据库等多种目的地,同时支持多种日志级别,便于调试和性能分析。 6. **Proxool**: ...

    j2ee高级软件架构师培训资料内部资料-架构物理设计

    资料可能会讲解如何集成日志框架,如Log4j,以及如何使用JMX(Java Management Extensions)进行系统监控。 9. **部署与运维**:资料也会涵盖应用的部署策略,包括热更新、蓝绿部署、滚动更新等,以及自动化运维...

    jbpm架构简介 概念 详细介 绍了jPDL语言的相关知识

    在解压的jBPM文件夹中,还有其他重要目录,如/config包含默认配置文件,例如hibernate.cfg.xml、Jbpm.cfg.xml、jBpm.mail.templates.xml和log4j.properties。/db目录下有针对不同数据库的初始化SQL文件,/examples...

    日志技术笔记总结.pdf

    在JAVA领域,有多种日志框架可供选择,如JUL(Java Util Logging)、Logback、log4j和log4j2,以及日志门面JCL(Java Commons Logging)和SLF4J(Simple Logging Facade For Java)。这些框架提供了控制日志输出的内容、...

    淘宝程序架构实例

    11. **异常处理与日志管理**:完善的异常处理机制和日志管理系统,如Log4j或ELK栈,有助于排查问题和优化系统。 12. **自动化运维**:Docker容器化部署和持续集成/持续部署(CI/CD)工具,如Jenkins,实现快速部署...

Global site tag (gtag.js) - Google Analytics