1. 程式人生 > >動態修改log4net元件的日誌檔名

動態修改log4net元件的日誌檔名

註冊部落格員也滿長時間了,這算是一個開篇文章把.

最近專案使用到log4net來記錄日誌,當然二話不說先到cnblogs上檢視一下各位高手關於log4net的教程和心得
主要參看了摩詰Log4Net使用指南 (確實是非常好的log4net的入門指南),在此篇文章的評論中@所羅門 有個
問題可能摩詰比較忙沒有時間去是實驗和解答,問題如下:
如果我在配置檔案裡不設定Appender的File,即刪除了<param name="File" value="log-file.txt" /> 一行資訊,
我想要在程式執行時動態的設定log日誌的檔名(例如以日期來作檔名),該怎麼處理才能實現

剛好專案也需要動態的更改log的檔名,就嘗試著去跟蹤一下log4net的寫日誌的過程,看看它是如果寫日誌的.
在跟蹤的工程中發現log4net.Repository.Hierarchy.Logger類下面有Appenders屬性,就是返回當前所有的append
集合,剛好通過除錯跟蹤發現

log4net.ILog log  =  log4net.LogManager.GetLogger( " AppLogger " ); 建立的log是一個log4net.Core.LogImpl型別,而此型別中有個Logger屬性剛剛好是log4net.Repository.Hierarchy.Logger
型別,所以想當然的有以下修改log路徑的函式
 1  private void  ChangeLog4netLogFileName(log4net.ILog iLog, string  fileName)
 2          {
 3             log4net.Core.LogImpl logImpl =  iLog  as  log4net.Core.LogImpl;
 4   if (logImpl != null )
 5              {
 6                  log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
 7   for ( int  i = 0 ;i < ac.Count;i ++ )
 8                  {     // 這裡我只對RollingFileAppender型別做修改  9                      log4net.Appender.RollingFileAppender rfa  =  ac[i]  as  log4net.Appender.RollingFileAppender;
10   if (rfa != null )
11                      {
12                          rfa.File  =  fileName;
13   if ( ! System.IO.File.Exists(fileName))
14                          {
15                              System.IO.File.Create(fileName);
16                          }
17                      }
18                  }
19              }
20          } ok,讓我們測試一下
private void  TestChangeLog4netLogFileName()
        {
            
string  fileName  = @" c:/chang.log " ;
            log4net.ILog iLog 
=  log4net.LogManager.GetLogger( " AppLogger " );
            
            ChangeLog4netLogFileName(iLog, fileName);
            iLog.Info(
" Test:info " );
        }
執行,哦C盤根目錄下並沒有要預期一樣沒有出現chang.log檔案.why?猜想RollingFileAppender在初始化的時候就
固定了檔名,後期對檔名的修改是不起作用的.繼續跟蹤程式碼,發現RollingFileAppender在記錄日誌時直接使用
初始化時就例項化的一個QuietTextWriter型別的私有變數m_qtw(直接繼承於基類TextWriterAppender),繼續跟蹤發現
基類(TextWriterAppender)提供了Writer屬性來修改m_qtw的值,所有修改一下上面的ChangeLog4netLogFileName函式
 1  private void  ChangeLog4netLogFileName(log4net.ILog iLog, string  fileName)
 2          {
 3             log4net.Core.LogImpl logImpl =  iLog  as  log4net.Core.LogImpl;
 4   if (logImpl != null )
 5              {
 6                  log4net.Appender.AppenderCollection ac = ((log4net.Repository.Hierarchy.Logger)logImpl.Logger).Appenders;
 7   for ( int  i = 0 ;i < ac.Count;i ++ )
 8                  {     // 這裡我只對RollingFileAppender型別做修改  9                      log4net.Appender.RollingFileAppender rfa  =  ac[i]  as  log4net.Appender.RollingFileAppender;
10   if (rfa != null )
11                      {
12                          rfa.File  =  fileName;
13   if ( ! System.IO.File.Exists(fileName))
14                          {
15                              System.IO.File.Create(fileName);
16                          }
17   // 更新Writer屬性 18                          rfa.Writer = new  System.IO.StreamWriter(rfa.File,rfa.AppendToFile,rfa.Encoding);
19                      }
20                  }
21              }
22          } 在執行上面的測試程式碼,ok,chang.log檔案如願的出現.
第一次寫blogs,羅裡羅嗦一大段,希望不會挑戰你的耐心^_^

最後附上log4net的配置(也直接從cnblogs上的某位大俠上面copy下來的)
 1 <? xml version="1.0" encoding="utf-8"  ?>  2 < configuration >  3      <!-- 如果不用App.config作配置檔案,則configSections節不是必須的。 -->  4      < configSections >  5          <!-- “type”屬性的完整格式為:配置節處理器類名,程式集名稱,Version=程式集版本號,Culture=區域資訊,PublicKeyToken=公鑰 -->  6          < section  name ="log4net"  type ="log4net.Config.Log4NetConfigurationSectionHandler,log4net" />  7      </ configSections >  8      < log4net >  9          <!-- 日誌記錄器logger,可以有多個 --> 10          < logger  name ="AppLogger" > 11              < level  value ="ALL" /> 12              < appender-ref  ref ="RollingLogFileAppender" /> 13              < appender-ref  ref ="ConsoleAppender" /> 14          </ logger > 15          < logger  name ="Form1" > 16              < level  value ="DEBUG" /> 17              < appender-ref  ref ="LogFileAppender" /> 18          </ logger > 19          <!-- 所有logger的基,root的設定在所有logger中都起作用。 
20         當在root和logger中重複設定相同的appender時,你會發現同一日誌資訊將被記錄兩次。 --> 21          <!-- <root> 
22             <level value="WARN" /> 
23             <appender-ref ref="LogFileAppender" /> 
24             <appender-ref ref="ConsoleAppender" /> 
25         </root> --> 26          <!-- 一個appender可以由多個logger共用,當然一個logger可以指定多個appender。 --> 27          < appender  name ="LogFileAppender"  type ="log4net.Appender.FileAppender" > 28              < param  name ="File"  value ="App.log" /> 29              < param  name ="AppendToFile"  value ="true" /> 30              < layout  type ="log4net.Layout.PatternLayout" > 31                  < param  name ="ConversionPattern"  value ="%d [%t] %-5p %c [%x] %X{auth} - %m%n" /> 32              </ layout > 33              < filter  type ="log4net.Filter.LevelRangeFilter" > 34                  < param  name ="LevelMin"  value ="ALL" /> 35                  < param  name ="LevelMax"  value ="FATAL" /> 36              </ filter > 37          </ appender > 38          < appender  name ="RollingLogFileAppender"  type ="log4net.Appender.RollingFileAppender" > 39              < file  value ="log/logfile1.log" /> 40              < appendToFile  value ="true" /> 41              < rollingStyle  value ="Date" /> 42              < datePattern  value ="yyyyMMdd" /> 43              < encoding  value ="utf-8" /> 44              < layout  type ="log4net.Layout.PatternLayout" > 45                  < conversionPattern  value ="%d [%r] [%-5level]: - %message%newline" /> 46              </ layout > 47          </ appender > 48          < appender  name ="ConsoleAppender"  type ="log4net.Appender.ConsoleAppender" > 49              < layout  type ="log4net.Layout.PatternLayout" > 50                  < param  name ="ConversionPattern"  value ="%d [%t] %-5p %c [%x] %X{auth} - %m%n" /> 51              </ layout > 52          </ appender > 53      </ log4net > 54 </ configuration >