log4net工作原理(2)
上回說道:Repository可以說成基于一個log4net配置節(jié)創(chuàng)建的log4net容器,它根據(jù)log4net配置節(jié)的指示創(chuàng)建其他所有對象(Logger/Appender/Filter/Layout等等)并保有他們的實例,隨時為你所用。
每個Repository都有自己唯一的名字,如 root。
一般而言一個AppDomain(或者說一個進程)有一個Repository,該AppDomain下所有程序集Assembly都可以使用這個Repository。Repository需要實現(xiàn)ILoggerRepository,log4net中l(wèi)og4net.Repository.Hierarchy.Hierarchy就通過繼承LoggerRepositorySkeleton實現(xiàn)了ILoggerRepository,它也是log4net中唯一實現(xiàn)ILoggerRepository的類。
Hierarchy
那么Hierarchy是什么呢?
Hierarchy里存放著通過配置文件創(chuàng)建的所有Logger。由于Logger們是有父子關(guān)系的,因此Hierarchy通過繼承樹來存放所有的Logger。根節(jié)點就是我們熟悉的Root,如例:
|
Logger 名 |
日志級別 |
從父Logger繼承的級別 |
|
root |
INFO |
INFO |
|
my |
none |
INFO |
|
my.net |
DEBUG |
DEBUG |
|
my.net.tcp |
none |
DEBUG |
對應(yīng)配置文件,應(yīng)該是:
<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形成繼承關(guān)系,子Logger中未定義的屬性都將從父Logger中繼承。
一旦你的應(yīng)用程序通過log4net.LogManager.GetLogger()得到ILog(也就是logger的代理),那么將從Hierarchy的繼承樹中找出對應(yīng)的Logger。
log4net.LogManager.GetLogger() 得到 root
log4net.LogManager.GetLogger(“my”) 得到 my logger
這樣,你就可以為程序集中不同的命名空間甚至是某個類設(shè)置相應(yīng)的log4net配置。如上例“my.net.tcp”就可以實現(xiàn)和其父Logger不同的日志行為。
使用不同的Repository
如果你的應(yīng)用程序中不同程序集需要使用不同<log4net>…</log4net>配置節(jié),或者說需要使用不同的log4net配置文件,那就使用不同的Repository。
如在my.net.tcp程序集中,加入語句:[assembly: log4net.Config.DOMConfigurator(ConfigFile="my.net.tcp.config", Watch=true)]
這樣,你的就可以單獨使用一份配置文件,創(chuàng)建一個新的Repository。
你也可以為自己的Repository命名: [assembly: log4net.Config.AliasRepository(“myrepository”)]
如何共用Repository
不作上面所說的所有改動,一個AppDomain中所有程序集都共用缺省的Repository,但是當需要共用另一個Repository時,就需要做一些工作。產(chǎn)生這樣的需求包括:
1. 兩個應(yīng)用程序共用一份log4net配置,對日志做同樣的處理
2. 兩個AppDomain需要共用一份log4net配置,對日志做同樣的處理。特別時在運行時動態(tài)升級程序集時,這個需求顯得尤其關(guān)鍵。
首先記載log4net的程序集需要為Repository命名:[assembly: log4net.Config.AliasRepository(“myrepository”)]
后續(xù)的程序集,只需要引用它即可:[assembly: log4net.Config.Repository(“myrepository”)]
這種方式下,兩個AppDomain寫同一份日志文件時,可能產(chǎn)生文件共享沖突的錯誤(文件已經(jīng)被鎖定,不能寫),需要修改配置,在RollingLogFileAppender中加入lockingModel配置,如:
<appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
<param name="File" value="log\\TaskScheduleServer.log" />
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
</appender>

浙公網(wǎng)安備 33010602011771號