zoukankan      html  css  js  c++  java
  • Log4net源码分析(二)

    转:http://blog.csdn.net/dhx20022889/article/details/3446633

    3          Log4net重点对象介绍

    3.1      ILogger日志实体:

           Log4Net架构中,对日志的记录是以日志实体为单位的。它记录日志的最低级别(高于此基本的消息都可以记录),日志的名称,以及维护日志结构的库(Repository)。它包含记录日志的操作。但在扩展日志类实体时,一般不直接实现ILogger接口,而是继承Logger类,这是一个虚类。它除了实现接口ILogger外,也实现了IAppenderAttachable,以确保使自己可以被绑定到Appender上。一个日志实体可以绑定到一个或多个Appender上。由于框架支持分层级的组织结构,所以它有一个属性Parent,已建立与上层的关联。RootLogger继承自Logger,它表示根层节点。

       

    3.2      日志结构ILoggerRespository

           日志的结构是层级结构,可选择子日志对象(通过属性Additivity)是否继承父对象的Appender,子对象和父对象在一个Hierarchy中。同时通过两种方式记录日志的层次关系,一种为子日志对象指定其父日志对象,另一种方式是通过日志的名称来记录:如果有两个logger,分别被定义为a.b.ca.b,那么我们说a.ba.b.c的祖先。

           若某一个日志对象有个父节点,但是这个父节点却还没有被指定,这时就可以用一个临时节点来代替,ProvisionNode的作用就在于此。它是一个集合对象,继承自ArrayList,可以暂时在此保存它的所有自节点,以方便于以后指定一个ILogger对象来替换它。

           ILoggerRespository类就像是Log4net的骨架,他支撑着整个Log4net的结构并管理着Log4net的各个部件。下面我们分析一下ILoggerRespository的功能以及工作原理:

           ILoggerRespository类中维护着LevelMap,PluginMap分别是Level,Plugin对象以其名称为键的集合,,RendermapIObjectRender以其类型为键的集合。而Hierarchy中存储着已创建的ILogger的对象集合,此集合是以LoggerKey为键的映射。

        ILoggerRespository中维护并存储着这些对象的集合,但它并不负责创建这些对象,而是把创建的工作委托给了XmlHierarchyConfigurator。它负责解析对Log4netXml(节点)配置。Hierarchy类不直接创建ILogger对象,而是通过ILoggerFactory对象来创建ILogger对象。在Hierarchy类中保存ILoggerFactory的一个默认实现:DefaultLoggerFactory

    3.3      LogManager

           LogManager作为面向用户的接口,它是在启用配置文件后被应用程序调用来创建ILog对象的。我们知道ILog是继承自ILoggerWrapper,所以ILog对象也是对ILogger对象的封装,ILog暴露出的接口比ILogger对象接口更好理解,更好使用。但是最终在Log4net框架中操作的是ILogger对象,而用户看到的却是对ILog对象的操作,这中间又是如何关联的呢,或者说这其中的机制是什么呢?

           LogManager中有一个类型为WrapperMap的静态成员变量s_wrapperMap。我们先看看WrapperMap类,它被用来创建ILog对象,并维护ILogger对象与ILoggerWrapper对象的对应关系。它的映射关系是:

    <Hashtable>

           <key type=”ILoggerRepository”/>

    <value type =”Hashtable”>

           <Hashtable>

                  <key type=”ILogger”/>

                  <value type=”ILoggerWrapper”/>

           </Hashtable>

    </value>

           </Hashtable>

        这个类复杂对这个映射关系的维护,包括创建、获取及销毁。但是,ILoggerWrapper对象的创建工作却是通过代理委托出去了,在这里是委托给LogManager中的一个静态方法了:private static ILoggerWrapper WrapperCreationHandler(ILogger logger)

    3.4      ILoggerWrapper日志包装类:

           日志包装类是对日志对象的包装,通过此接口可以获取它说包装的ILogger对象。ILogILoggerWrapper的子接口,它是Log4Net Framework的对外接口。框架使用者通过它可以对各种日志对象进行操作,写相应基本的日志等。

            

    3.5      LoggerManager 工具类

           LoggerManager 工具类被用来获取ILoggerRepositoryILogger对象。但它并不能直接创建和维护这些对象。所以它把创建ILoggerRepository对象的工作委托IRepositorySelector,它只负责IRepositorySelector对象的创建和维护工作。但是IRepositorySelector也只是负责对ILoggerRepository对象的创建和维护工作。所以LoggerManager通过IRepositorySelector获取ILoggerRepository对象,然后再通过获取到的ILoggerRepository对象获取ILogger对象。LoggerManager通过两种方式创建IRepositorySelector对象:从配置文件种获取对象类型或者创建默认对象:DefaultRepositorySelector。另外在LoggerManager中添加了销毁IRepository对象进程监控,即当应用程序进程关闭时,自动销毁IRepository对象,这种监控是在创建LoggerManager的静态构造函数时建立的。

    3.6      IRepositorySelector

           IRepositorySelector是用来维护ILoggerRepository的,在Log4net框架中,它有两个子类:DefaultRepositorySelectorCompactRepositorySelector。由于CompactRepositorySelector是在嵌入式系统中用到的,所以我们只讨论DefaultRepositorySelector。虽说这是一个默认实现,但也是暂时为止唯一的实现。在此类中,以数据字典的方式维护着对ILoggerRepository的缓存。若是第一次使用某个名字的ILoggerRepository是需要创建的。它有两种创建方式,一是通过程序集属性获取ILoggerRepository的名称和类型,二是通过参数传入ILoggerRepository的名称和类型,然后通过反射创建出对象。另外,若是不通过配置文件配置Log4net设置,而是通过程序集设置,也是通过此类中的方法获取Log4net配置的xml文件,并加载配置。默认情况下使用的是默认的ILoggerRepository名称“log4net-default-repository”,这时是从配置文件“log4net.Config中取配置项的。

    3.7      输出方式IAppender

           IAppender有一个抽象子类:AppenderSkeleton。在此抽象类中完成了IAppender的基本功能的实现,几乎所有的底层类都继承此类。AppenderCollection类是IAppender对象的集合类,方便对IAppender的集合进行维护。

        每个ILogger对象需要维护着自己的IAppender集合,并向里面写入日志内容。而这些工作可以看作一个单一的职责,类AppenderAttachedImpl负责此职责。所以IAppender只是拥有AppenderAttachedImpl的一个实例作为成员变量(域)就可以了,然后通过此实例做写入日志工作。

        在配置文件中必须有一个<log>节点或<root>节点,用以绑定Appender对象等信息,而若没有<root>节点,ILogger的根节点就无实际意思,而设置的<log>节点为Root的第一层子节点,此时,而其他节点就会作为<log>节点的子节点。这时<log>节点的IAppender就会覆盖RootIAppender.而其子节点会继承<log>节点的IAppender

    3.8      IFilter

           IFilter为输出Logger的过去方案,此过滤方案是负责哪些LoggingEvent应该被处理。过滤方案是在AppenderSkeleton中被使用的,并以以职责链的模式对IFilter对象的维护和使用。

    3.9      ILayout

        ILayout为消息输出格式的定义类,通过此类,可以格式化输出消息的格式。此类也是在AppenderSkeleton中使用,以格式化输出文字的格式。

    3.10 PatternLayout

        PatternLayout类中对输出的各种信息以系统框架定义的格式化方式进行格式化。虽说此类中会对ParttenConvertor对象进行缓存,但是还是通过PatternParser创建了一系列PatternConverter对象,并以职责链模式把他们组合在一起。通过这些PatternConvertor对象格式化日志对象内部数据(包括机器名称,用户名,当前进程ID,信息类型等信息)。

    3.11 ParttenConverter

        对于ParttenConverter系列的类分两个分支:一个是Util/PatternStringConverters下的类,这里的类主要处理系统级别的数据。这些数据需要在加载配置Log4net时加载,PatternString负责对这些对象进行维护,虽说此类中会对ParttenConverter对象进行缓存,但是还是通过PatternParser创建了一系列PatternConverter对象,并以职责链模式把他们组合在一起。而第二个分支是Layout/Pattern目录下的类,这些类用来格式化日志事件LoggerEvent对象内的数据。

    3.12 OptionConverter

        OptionConverter工具类负责类型转换并解析及获取相应的值。而目标类型存储在ConverterRegistry中,此类负责类型转换器的注册及缓存。OptionConverterConverterRegistry中获取相应的目标类。目标类主要是指Util/TypeConverters下的类。其中类PatternLayoutConverter用来转换为PatternLayout对象,PatternStringConverter用来转换为PatternString对象。而类OptionConverter主要在类XmlHierarchyConfigurator中解析配置文件时被调用。

    3.13 IObjectRenderer

        IObjectRenderer对象及其子类用来以字符串的形式输出对象,在框架中它只有一个子类:DefaultRender,而RenderMap对象时以IObjectRenderer类型为键的映射集合。在ILoggerRepository中被调用,而IObjectRenderer对象则是在XmlHierarchyConfigurator中通过反射被创建,并保存在ILoggerRepository对象中。

    3.14 IPlugin

        IPlugin对象是用来定义附加的操作行为,IPluginFactory负责创建IPlugin对象,在架构中特性类PluginAttribute继承IPluginFactory。所以需要通过设置程序集特性来配置IPlugin类型,并且在DefaultRepositorySelector中通过反射创建IPlugin对象并加载到ILoggerRepository对象中。

       

    3.15    TextWriterAdapter

           TextWriterAdapter是通过适配器模式对TextWriter类进行了封装,以便于创建适用于特殊用户的TextWriter对象。在框架中主要由两类:ProtectCloseTextWriter用来隐藏其Close()函数,QuietTextWriter屏蔽其内部产生的异常,并把异常记录到框架自己的日志里。

          

    3.16 ContextPropertiesBase

        ContextPropertiesBase抽象类是上下文属性类的基类,此系列类是用来存储某一类型上下文的字典类。

       

           这些属性分别有GlobalContextThreadContextLogicalThreadContext来创建,并在LoggingEventPropertyPatternConverter被调用来生成各种参数。其中LogicalThreadContextProperties是通过CallContext.GetData("log4net.Util.LogicalThreadContextProperties")取得数据,也就是说它支持通过Remoting在客户端与服务器端传输的数据。ThreadContextProperties是通过System.Threading.Thread.GetData(s_threadLocalSlot)来获取数据,即是存储在当前线程的数据插槽中,使之与其它线程隔绝。GlobalContextProperties是全局性上下文属性,存储在字典集合中,包含进程级数据。

    3.17 SecurityContext

        SecurityContext类用来提供受保护的数据,比如模拟一个系统用户。这是一个抽象类,在框架中有两个个实现NullSecurityContextWindowsSecurityContext. NullSecurityContext对象是一个空实现,不做任何操作,它由SecurityContextProvider类负责创建。WindowsSecurityContext是对Windows域用户的模拟。这些上下文对象在部分IAppender中被使用,以保证数据操作的安全性,例如:AdoNetAppender,FileAppender等。

    3.18 IErrorHandler

        IErrorHandler属于异常处理类,它被委托来处理异常。它在框架中只有一个实现类:OnlyOnceErrorHandler,用来在框架内部日志中记录异常信息。异常处理类在AppenderSkeleton中和QuietTextWriter中被使用。

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

    1 AdoNetAppender
        
    将日志记录到数据库中。可以采用SQL和存储过程两种方式。

    2 AnsiColorTerminalAppender
        
    ANSI 窗口终端写下高亮度的日志事件。

    3 AspNetTraceAppender
        
    能用asp.netTrace的方式查看记录的日志。

    4 BufferingForwardingAppender
        
    在输出到子Appenders之前先缓存日志事件。

    5 ConsoleAppender
        
    将日志输出到控制台。

    6 EventLogAppender
        
    将日志写到Windows Event Log. 

    7 FileAppender
        
    将日志写到文件中。

    8 LocalSyslogAppender
        
    将日志写到local syslog service (仅用于UNIX环境下). 

    9 MemoryAppender
        
    将日志存到内存缓冲区。

    10 NetSendAppender
        
    将日志输出到Windows Messenger service.这些日志信息将在用户终端的对话框中显示。

    11 RemoteSyslogAppender
        
    通过UDP网络协议将日志写到Remote syslog service

    12 RemotingAppender
        
    通过.NET Remoting将日志写到远程接收端。

    13 RollingFileAppender
        
    将日志以回滚文件的形式写到文件中。

    14 SmtpAppender
        
    将日志写到邮件中。

    15 TraceAppender
        
    将日志写到.NET trace 系统。

    16 UdpAppender
        
    将日志connectionless UDP datagrams的形式送到远程宿主或以UdpClient的形式广播。

     

    3.20 日志等级:

           日志等级分为:(Unrecoverable errorsRecoverable errorsInformationDebug)不可恢复的错误一定要记录下来,用户不可轻易删除,以便于开发人员分析处理。可恢复的错误,也要记录,并提供处理措施,应有查看及分析工具支持。

    消息日志用来记录一些关键操作,可作为用户监控,需要分析工具支持。调试日志,用来供开发人员和维护人员跟踪操作流程以及分析问题,平时需要屏蔽,仅在相关维护人员跟踪问题时再临时开放日志权限。

    级别

    允许的方法

    Boolean属性

    优先级别

    分类

    OFF

     

     

    Highest

     

    FATAL

    void Fatal(...);

    bool IsFatalEnabled;

     

    Unrecoverable

    RROR

    void Error(...);

    bool IsErrorEnabled;

     

    Recoverable

    WARN

    void Warn(...);

    bool IsWarnEnabled;

     

    INFO

    void Info(...);

    bool IsInfoEnabled;

     

    Information

    DEBUG

    void Debug(...);

    bool IsDebugEnabled;

     

    Debug

    ALL

     

     

    Lowest

     

  • 相关阅读:
    232 前端之JQuery:JQuery扩展和事件
    231 前端之JQuery:JQuery文档操作
    Result(ActionResult、JsonResult、JavaScriptResult等)
    Controller传值到前端页面的几种方式
    若要允许 GET 请求,请将 JsonRequestBehavior 设置为 AllowGet(转载)
    过滤器
    ViewData丶ViewBag和TempData
    C#-绘图双缓冲
    Kafka的架构原理,你真的理解吗?
    Kafka的架构原理,你真的理解吗?
  • 原文地址:https://www.cnblogs.com/jackljf/p/3588961.html
Copyright © 2011-2022 走看看