Log4net源码分析(一)

来源:互联网 发布:mac阿里旺旺验证码出错 编辑:程序博客网 时间:2024/04/29 17:04

 

1     Log4net简介... 2

2     Log4net结构分析... 2

2.1     结构划分... 2

2.2     结构总图... 2

2.3     日志的记录过程分析... 3

3     Log4net重点对象介绍... 8

3.1     ILogger日志实体:... 8

3.2     日志结构ILoggerRespository... 8

3.3     LogManager 9

3.4     ILoggerWrapper日志包装类:... 9

3.5     LoggerManager 工具类... 10

3.6     IRepositorySelector 10

3.7     输出方式IAppender... 10

3.8     IFilter 11

3.9     ILayout 11

3.10       PatternLayout 11

3.11       ParttenConverter 11

3.12       OptionConverter 11

3.13       IObjectRenderer 12

3.14       IPlugin. 12

3.15    TextWriterAdapter... 12

3.16       ContextPropertiesBase. 13

3.17       SecurityContext 14

3.18       IErrorHandler 14

3.19       Log4net目前支持的输出方式包括:... 14

3.20       日志等级:... 15

4     Log4net关注点... 15

4.1     Log4net的习惯用法... 15

5     总结... 16

  

 

1         Log4net简介

              Log4net是基于.net开发的一款非常著名的记录日志开源组件。最早是20017月由NeoWorks Limited启动的项目,基本的框架源于另外的一个非常著名的姐妹组件-log4j。现由Apache组织开发与维护。此日志架构是可灵活扩展,且通过配置文件来设置日志的属性及输出,不同修改代码即可实现程序的灵活跟踪。可以将日志分不同的等级,通过不同的过滤条件,以不同的样式,将日志输出到不同的媒介。可以从http://logging.apache.org/log4net/downloads.html网站下载最新版本的Log4net源码。

 

2          Log4net结构分析

2.1      结构划分

       log4net 有五种主要的组件:Logger(记录器)、Repository(库)、Appender(附着器)、Layout(布局)以及 Filter(过滤器)。虽然它们的职责各有不同,但它们通过有机组合,最终构成Log4net的大体框架和功能。

 

2.2      结构总图


1Log4net框架的结构图

 

       如上图所示,Utils命名空间里的类为Log4net的基础工具类,它提供对一些基本功能和服务。它为整个Log4net框架提供基础功能和服务。这里的类不参与Log4net中类的架构层次,却是为了使Log4net架构更清晰明了,把一些零散的基础的功能和服务集合在一起,形成了此命名空间。

       Log系列对象属于最外层命名控件log4net中的核心,它提供了用户使用的接口,公用户使用来记录日志,主要是便于用户理解和使用,它对外隐藏了Log4net内复杂的架构和实现原理。

       Config命名控件内的类主要负责Log4net组件的环境配置。它主要通过两种方式来配置Log4net组件,一种是通过设置程序集特性配置,另一种是通过直接在代码中加载配置文件。

       Core命名空间容纳框架的核心接口、连接各个组件的管理类以及在多个组件或层次中都要使用的关键类。这里的接口和类一般不会暴露给用户扩展和使用。

       由于Respository系列类中定义了日志对象(ILogger)的组织结构,他负责组织ILogger对象以及附加功能,所以Respository命名空间包括Respository系列类和ILogger对象的默认实现。以及专门为了组织日志对象需要的类。

       Plugin命名空间提供了附加功能扩展接口以及默认实现类。

       ObjectRender命名空间提供了对象的打印方式接口以及默认实现类。

       Logger组件不是命名空间,但是它在框架中却是一个很重要的角色:日志对象类。由于它的重要性以及在框架中的应用广泛性,它的顶层接口ILogger Core命名空间中定义,而默认实现却在Respository命名空间中,就是为了实现对日志对象结构的组织和管理。有架构图可以看出,每个Logger对象都有自己的输出方式Appender

       Appender命名空间中的类负责日志的输出,定义日志的输出方式,框架中定义了16种输出方式。在Appender对象中可以定义自己的日志布局和过滤方式。

       Filter命名空间为定义要输出的日志的过滤器接口及默认实现类。过滤器是以职责链的形式组织的。

       Layout命名空间定义了日志的输出格式类。

2.3      日志的记录过程分析

      用户在使用Log4net框架来记录日志时,需要通过LogManager.GetLogger()获取ILog对象,然后用ILog对象的Error()等方法记录日志。然而,在框架中日志对象是ILogger的实现类,ILog对象只是对ILogger对象的包装,以便于用户的理解和使用。

       ILogger对象在Log4net中是已一定的层次结构组织的。这就是Repository的作用。ILogger拥有继承机制,可以继承父节点的AppenderILogger拥有自己的Appender集合,负责输出日志。Appender拥有自己的过滤器Filter和布局Layout

2.3.1     在创建日志对象前必须配置日志环境,通常是通过XML来配置的。下图是配置的过程:

                                       

2、解析配置文件的类图

       2展现了两种配置方式:

       一是直接在代码中通过调用XmlConfigurator.Configure()来解析配置文件,配置日志环境;

       二是通过定义程序集特性来加载并解析配置文件,配置日志环境。不过这种方式只能在创建第一个ILog对象时才能加载配置文件。

2.3.2     在加载并解析配置文件时就会搭建Log4net日志环境。图3就是搭建日志环境以及创建各种对象的流程。


3、搭建日志环境以及创建各种对象的流程

 

2.3.3     既然用户是通过ILog对象来记录日志的,那么如何获取ILog对象以及它又如何包装日志对象(ILogger对象)呢?图4即是创建ILog对象的过程。

图4、创建ILog对象的过程

 

       ILog对象是通过LogManager工具类来创建的。LogManager工具类通过LoggerManager创建ILogger对象,然后使用ILoggerWraper对其进行包装,并通过WrapperMap进行管理LoggerILoggerWraper之间的映射。

       ILogger对象的集合在ILoggerRepository中按一定的结构进行组合和管理所以需要从 ILoggerRepository中获取ILogger对象。欲获取ILogger对象,必须首先获取ILoggerRepository对象。IRepositorySelector就是负责缓存和管理ILoggerRepository对象的类,所以需要通过IRepositorySelector获取ILogger对象所在的ILoggerRepository对象,然后再从ILoggerRepository对象中获取ILogger对象。

2.3.4     既然ILog对象不是日志对象,那么ILog又是如何记录日志的呢?

图5、记录日志的过程

 

       用户通过LogManager.GetLogger()获取ILog对象,然后通过ILog对象的Error()等方法记录日志。但是ILog对象的方法最终会映射为ILogger对象的Log()方法。在调用ILoggerLog()方法时,会创建一个LoggingEvent对象,此对象记录了日志的信息,之后就可以把LoggingEvent对象在ILogger对象和IAppender对象之间传递,直到把日志信息写入TextWriter中才可销毁。LoggingEvent对象的生命周期是从调用ILoggerLog()方法起,直到此条消息写入TextWriter中为止。ILogger对象需要调用自己的IAppender对象来把日志信息写到媒体上,IAppender对象需要调用IFilter对象来过滤需要写入媒体的日志,然后调用ILayout对象来设置日志的输出格式。

原创粉丝点击