zoukankan      html  css  js  c++  java
  • Log4net源码View之Logger解析

     

    1.简介

    Logger是Log4net的三大核心载体之一,搞清楚它的意义很重大。另外两个分别是AppenderLayout。其对应关系为一个Logger对应多个Appender,一个Appender对应一个Layout。

    对于Log4net的内部实现,ILogger才是接口(所有日志需要实现的——Interface that all loggers implement)。

    为什么不是我们所使用的ILog接口呢?实际上,ILog是对ILogger进行了包装,是典型的Wrapper模式,话说不仔细看的话,还真搞不清楚它们的关系。

    下图表明了关系:ILog——>ILoggerWrapper——>ILogger.

    所以,从下面开始,请先忽略ILog接口,将关注点放在ILogger上,这也是本文的重点。

    2.ILogger接口

    方法

    含义

    string Name{ get; }

    获取ILogger的名称

    Log(Type callerStackBoundaryDeclaringType, Level level, object message, Exception exception);

    将需要记录的信息(level、msg、ex)变成一个LoggerEvent对象,然后将LoggerEvent对象分发到各个Appender。

    void Log(LoggingEvent logEvent);

    直接记录一个LoggerEvent

    bool IsEnabledFor(Level level);

    检查某级别是否可用

    ILoggerRepository Repository { get; }

    ILogger所在的仓储

    从接口结合源码可以得出:

    2.1 仓储

    通过Repository可以找到ILogger所在的仓储,得到对应的分组(Repository Group);

    设计思想

    将多个日志对象进行分组,以便于管理。比如用户User,用户组UserGroup,其中UserGroup就是分组。

    而Repository除了有分组的意义之外,还有存储的作用,可以理解为带有缓存功能的工厂(Factory+Cache)。

     

    2.2 LoggerEvent

    LoggerEvent又是什么呢?(很早以前看到LoggerEvent时,一直很纠结为什么要这样取名?是为了让别人看不懂源码吗?仔细揣摩之后,比如WCF的Messaging,EBaySDK中的Request,只是某个语境下的一个特性称谓)

    设计思想

    LoggerEvent可以理解为一个信封Envelope,类似于WebService中soap的概念,也类似于MessageQueue中的Messaging的设计。其主要用来包装与消息(object message)有关的数据。这样,通过将LoggerEvent分发给Appender,就实现了输出到多个终端。如下代码:

    1. virtual protected void CallAppenders(LoggingEvent loggingEvent)
    2. {
    3. //......
    4.     int writes = 0;
    5.     for (Logger c = this; c != null; c = c.Parent)
    6.     {
    7.         if (c.m_appenderAttachedImpl != null)
    8.         {
    9.             // Protected against simultaneous call to addAppender, removeAppender,...
    10.             c.m_appenderLock.AcquireReaderLock();
    11.             try
    12.             {
    13.                 if (c.m_appenderAttachedImpl != null)
    14.                 {
    15.                     writes += c.m_appenderAttachedImpl.AppendLoopOnAppenders(loggingEvent);
    16.                 }
    17.             }
    18.             finally
    19.             {
    20.                 c.m_appenderLock.ReleaseReaderLock();
    21.             }
    22.         }
    23.        //......
    24.     }
    25. }

    其中,m_appenderAttachedImpl为Appender的集合,AppendLoopOnAppenders循环将LoggerEvent添加到Appender。

     

    2.3 LoggerEventData

    "信封"里的数据是什么呢?——LoggerEventData对象。

    1. public struct LoggingEventData
    2. {
    3.    public string LoggerName;
    4.    public Level Level;
    5.    public string Message;
    6.    public string ThreadName;
    7.    public DateTime TimeStamp;
    8.    public LocationInfo LocationInfo;
    9.    public string UserName;
    10.    public string Identity;
    11.    public string ExceptionString;
    12.    public string Domain;
    13.    public PropertiesDictionary Properties;
    14. }

    最常用的数据,TimeStamp,Message,ExceptionString

    3.抽象类Logger

    特点:

    1)通过继承IAppenderAttachable接口,这样Logger与IAppender之间就有一对多的包含与调用关系;

    2)Logger具有层次结构,公布了类型为Logger的父亲指针Parent;

    3)通过实现ILogger(具体是使用了LoggerEvent对象),则将日志的整体包装起来;

    4.ILoggerFactory

    用于创建Logger对象

    其在DefaultLoggerFactory中的实现为:

    1. public Logger CreateLogger(ILoggerRepository repository, string name)
    2. {
    3.    if (name == null)
    4.    {
    5.       return new RootLogger(repository.LevelMap.LookupWithDefault(Level.Debug));
    6.    }
    7.    return new LoggerImpl(name);
    8. }

        其中,LoggerImpl对象继承自Logger,并没有做什么特殊的改变。

        RootLogger带有一个默认的Level。

    总结:

    Logger其实提供了一种处理中心的功能,类似分发站,将message发给各个Appender。

    待续~

  • 相关阅读:
    【poj3764】 The xor-longest Path
    【poj3261】 Milk Patterns
    【poj3237】 Tree
    【bzoj2654】 tree
    【poj3122】 Pie
    【poj1011】 Sticks
    【poj1186】 方程的解数
    【poj2741】 Colored Cubes
    【poj3141】 Distant Galaxy
    【bzoj2456】 mode
  • 原文地址:https://www.cnblogs.com/pengzhen/p/log4net.html
Copyright © 2011-2022 走看看