log4net工作原理(2)

 上回说道:Repository可以说成基于一个log4net配置节创建的log4net容器,它根据log4net配置节的指示创建其他所有对象(Logger/Appender/Filter/Layout等等)并保有他们的实例,随时为你所用。

       每个Repository都有自己唯一的名字,如 root。

       一般而言一个AppDomain(或者说一个进程)有一个Repository,该AppDomain下所有程序集Assembly都可以使用这个Repository。Repository需要实现ILoggerRepository,log4net中log4net.Repository.Hierarchy.Hierarchy就通过继承LoggerRepositorySkeleton实现了ILoggerRepository,它也是log4net中唯一实现ILoggerRepository的类。     

Hierarchy

       那么Hierarchy是什么呢?

       Hierarchy里存放着通过配置文件创建的所有Logger。由于Logger们是有父子关系的,因此Hierarchy通过继承树来存放所有的Logger。根节点就是我们熟悉的Root,如例:

Logger 

日志级别

从父Logger继承的级别

root

INFO

INFO

my

none

INFO

my.net

DEBUG

DEBUG

my.net.tcp

none

DEBUG

对应配置文件,应该是:

<root>
       <level value="INFO" />
       <appender-ref ref="ConsoleAppender" />
</root>

<logger name=" my">
       <appender-ref ref="ConsoleAppender" />
</logger>

<logger name=" my.net ">
       <appender-ref ref="ConsoleAppender" />
</logger>

<logger name=" my.net.tcp">
       <filter type="log4net.Filter.LevelRangeFilter">
                            <param name="LevelMin" value="DEBUG"/>
                            <param name="LevelMax" value="INFO"/>
       </filter>
       <appender-ref ref=" ColoredConsoleAppender" />
</logger>

       上例中,定义了三个Logger,都将存放在Hierarchy中。三个Logger形成继承关系,Logger中未定义的属性都将从父Logger中继承

       一旦你的应用程序通过log4net.LogManager.GetLogger()得到ILog(也就是logger的代理),那么将从Hierarchy的继承树中找出对应的Logger。

   log4net.LogManager.GetLogger() 得到 root
   log4net.LogManager.GetLogger(“my”) 得到 my logger    

    这样,你就可以为程序集中不同的命名空间甚至是某个类设置相应的log4net配置。如上例“my.net.tcp”就可以实现和其父Logger不同的日志行为。 

使用不同的Repository

      如果你的应用程序中不同程序集需要使用不同<log4net>…</log4net>配置节,或者说需要使用不同的log4net配置文件,那就使用不同的Repository。

       如在my.net.tcp程序集中,加入语句:[assembly: log4net.Config.DOMConfigurator(ConfigFile="my.net.tcp.config", Watch=true)]

    这样,你的就可以单独使用一份配置文件,创建一个新的Repository。

       你也可以为自己的Repository命名: [assembly: log4net.Config.AliasRepository(“myrepository”)] 

如何共用Repository

      不作上面所说的所有改动,一个AppDomain中所有程序集都共用缺省的Repository,但是当需要共用另一个Repository时,就需要做一些工作。产生这样的需求包括:

1.        两个应用程序共用一份log4net配置,对日志做同样的处理
2.        两个AppDomain需要共用一份log4net配置,对日志做同样的处理。特别时在运行时动态升级程序集时,这个需求显得尤其关键。

首先记载log4net的程序集需要为Repository命名:[assembly: log4net.Config.AliasRepository(“myrepository”)]

后续的程序集,只需要引用它即可:[assembly: log4net.Config.Repository(“myrepository”)]

        这种方式下,两个AppDomain写同一份日志文件时,可能产生文件共享冲突的错误(文件已经被锁定,不能写),需要修改配置,在RollingLogFileAppender中加入lockingModel配置,如:   
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
        <param name="File" value="log\\TaskScheduleServer.log" />
        <lockingModel type="log4net.Appender.FileAppender+MinimalLock" />   
</appender>

posted @ 2017-11-29 17:14  闫宝平  阅读(466)  评论(0编辑  收藏  举报