zoukankan      html  css  js  c++  java
  • 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>

  • 相关阅读:
    BZOJ 1977: [BeiJing2010组队]次小生成树 Tree( MST + 树链剖分 + RMQ )
    BZOJ 2134: 单选错位( 期望 )
    BZOJ 1030: [JSOI2007]文本生成器( AC自动机 + dp )
    BZOJ 2599: [IOI2011]Race( 点分治 )
    BZOJ 3238: [Ahoi2013]差异( 后缀数组 + 单调栈 )
    ZOJ3732 Graph Reconstruction Havel-Hakimi定理
    HDU5653 Bomber Man wants to bomb an Array 简单DP
    HDU 5651 xiaoxin juju needs help 水题一发
    HDU 5652 India and China Origins 并查集
    HDU4725 The Shortest Path in Nya Graph dij
  • 原文地址:https://www.cnblogs.com/GoogleGetZ/p/7921629.html
Copyright © 2011-2022 走看看