3 Log4net重点对象介绍
3.1 ILogger日志实体:
在Log4Net架构中,对日志的记录是以日志实体为单位的。它记录日志的最低级别(高于此基本的消息都可以记录),日志的名称,以及维护日志结构的库(Repository)。它包含记录日志的操作。但在扩展日志类实体时,一般不直接实现ILogger接口,而是继承Logger类,这是一个虚类。它除了实现接口ILogger外,也实现了IAppenderAttachable,以确保使自己可以被绑定到Appender上。一个日志实体可以绑定到一个或多个Appender上。由于框架支持分层级的组织结构,所以它有一个属性Parent,已建立与上层的关联。RootLogger继承自Logger,它表示根层节点。
3.2 日志结构ILoggerRespository:
若某一个日志对象有个父节点,但是这个父节点却还没有被指定,这时就可以用一个临时节点来代替,ProvisionNode的作用就在于此。它是一个集合对象,继承自ArrayList,可以暂时在此保存它的所有自节点,以方便于以后指定一个ILogger对象来替换它。
ILoggerRespository类就像是Log4net的骨架,他支撑着整个Log4net的结构并管理着Log4net的各个部件。下面我们分析一下ILoggerRespository的功能以及工作原理:
ILoggerRespository类中维护着LevelMap,PluginMap分别是Level,Plugin对象以其名称为键的集合,,Rendermap是IObjectRender以其类型为键的集合。而Hierarchy中存储着已创建的ILogger的对象集合,此集合是以LoggerKey为键的映射。
ILoggerRespository中维护并存储着这些对象的集合,但它并不负责创建这些对象,而是把创建的工作委托给了XmlHierarchyConfigurator。它负责解析对Log4net的Xml(节点)配置。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对象。ILog是ILoggerWrapper的子接口,它是Log4Net Framework的对外接口。框架使用者通过它可以对各种日志对象进行操作,写相应基本的日志等。
3.5 LoggerManager 工具类
LoggerManager 工具类被用来获取ILoggerRepository和ILogger对象。但它并不能直接创建和维护这些对象。所以它把创建ILoggerRepository对象的工作委托IRepositorySelector,它只负责IRepositorySelector对象的创建和维护工作。但是IRepositorySelector也只是负责对ILoggerRepository对象的创建和维护工作。所以LoggerManager通过IRepositorySelector获取ILoggerRepository对象,然后再通过获取到的ILoggerRepository对象获取ILogger对象。LoggerManager通过两种方式创建IRepositorySelector对象:从配置文件种获取对象类型或者创建默认对象:DefaultRepositorySelector。另外在LoggerManager中添加了销毁IRepository对象进程监控,即当应用程序进程关闭时,自动销毁IRepository对象,这种监控是在创建LoggerManager的静态构造函数时建立的。
3.6 IRepositorySelector
IRepositorySelector是用来维护ILoggerRepository的,在Log4net框架中,它有两个子类:DefaultRepositorySelector和CompactRepositorySelector。由于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就会覆盖Root的IAppender.而其子节点会继承<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中,此类负责类型转换器的注册及缓存。OptionConverter从ConverterRegistry中获取相应的目标类。目标类主要是指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抽象类是上下文属性类的基类,此系列类是用来存储某一类型上下文的字典类。
这些属性分别有GlobalContext,ThreadContext,LogicalThreadContext来创建,并在LoggingEvent,PropertyPatternConverter被调用来生成各种参数。其中LogicalThreadContextProperties是通过CallContext.GetData("log4net.Util.LogicalThreadContextProperties")取得数据,也就是说它支持通过Remoting在客户端与服务器端传输的数据。ThreadContextProperties是通过System.Threading.Thread.GetData(s_threadLocalSlot)来获取数据,即是存储在当前线程的数据插槽中,使之与其它线程隔绝。GlobalContextProperties是全局性上下文属性,存储在字典集合中,包含进程级数据。
3.17 SecurityContext
SecurityContext类用来提供受保护的数据,比如模拟一个系统用户。这是一个抽象类,在框架中有两个个实现NullSecurityContext和WindowsSecurityContext. NullSecurityContext对象是一个空实现,不做任何操作,它由SecurityContextProvider类负责创建。WindowsSecurityContext是对Windows域用户的模拟。这些上下文对象在部分IAppender中被使用,以保证数据操作的安全性,例如:AdoNetAppender,FileAppender等。
3.18 IErrorHandler
IErrorHandler属于异常处理类,它被委托来处理异常。它在框架中只有一个实现类:OnlyOnceErrorHandler,用来在框架内部日志中记录异常信息。异常处理类在AppenderSkeleton中和QuietTextWriter中被使用。
3.19 Log4net目前支持的输出方式包括:
1AdoNetAppender
将日志记录到数据库中。可以采用SQL和存储过程两种方式。
2AnsiColorTerminalAppender
在ANSI窗口终端写下高亮度的日志事件。
3AspNetTraceAppender
能用asp.net中Trace的方式查看记录的日志。
4BufferingForwardingAppender
在输出到子Appenders之前先缓存日志事件。
5ConsoleAppender
将日志输出到控制台。
6EventLogAppender
将日志写到WindowsEventLog.
7FileAppender
将日志写到文件中。
8LocalSyslogAppender
将日志写到localsyslogservice(仅用于UNIX环境下).
9 MemoryAppender
将日志存到内存缓冲区。
10NetSendAppender
将日志输出到WindowsMessengerservice.这些日志信息将在用户终端的对话框中显示。
11RemoteSyslogAppender
通过UDP网络协议将日志写到Remotesyslogservice。
12RemotingAppender
通过.NETRemoting将日志写到远程接收端。
13RollingFileAppender
将日志以回滚文件的形式写到文件中。
14SmtpAppender
将日志写到邮件中。
15TraceAppender
将日志写到.NETtrace系统。
16UdpAppender
将日志connectionlessUDPdatagrams的形式送到远程宿主或以UdpClient的形式广播。
3.20 日志等级:
日志等级分为:(Unrecoverable errors,Recoverable errors,Information,Debug)不可恢复的错误一定要记录下来,用户不可轻易删除,以便于开发人员分析处理。可恢复的错误,也要记录,并提供处理措施,应有查看及分析工具支持。
消息日志用来记录一些关键操作,可作为用户监控,需要分析工具支持。调试日志,用来供开发人员和维护人员跟踪操作流程以及分析问题,平时需要屏蔽,仅在相关维护人员跟踪问题时再临时开放日志权限。
| 级别 | 允许的方法 | 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 |
|
来自:
本文深入介绍了Log4Net的日志记录架构,涵盖了ILogger日志实体、日志结构ILoggerRepository、LogManager、ILoggerWrapper日志包装类等多个核心组件。此外,还详细解析了IAppender输出方式、IFilter过滤方案、ILayout消息格式定义等关键概念。
167

被折叠的 条评论
为什么被折叠?



