log4net

(史帝芬, 2006/07/01, hi.steven@gmail.com)
使用Java開發程式的人多半用過log4j, 也多半對於log4j的小巧好用留下深刻的印象,現在log4j有了.net版了! 這就是本篇要介紹的主題。 本篇內容主要由任職於 H 銀行的 Alex Chou 與小弟合力完成,小弟將它整理後放置於網站上供網友參考。
在繼續往下看之前當然要先到官方網站上下載log4net,官方網站網址在 http://logging.apache.org/log4net/, 在網站上應該可以找到類似incubating-log4net-1.2.10.zip檔名的下載檔,下載後解開, 找到名為log4net.dll的檔案,將它加入專案中的參考。底下有兩個範例程式及其說明。
  • 第一個範例程式
    using System;
    using log4net; //註1
    using log4net.Config;
    
    
    namespace Log4Net
    {
        public class Bar
        {
            private static readonly ILog log = LogManager.GetLogger(typeof(Bar));
    
            public void DoIt()
            {
                log.Fatal("Fatal");
            }
        }
    
        class Program
        {
        	//註2
            private static readonly ILog log = LogManager.GetLogger(typeof(Program));
    
            static void Main(string[] args)
            {
                //註3
                XmlConfigurator.Configure(new System.IO.FileInfo("d:/config.xml")); 
    
                log.Info("Entering application."); //註4
                Bar bar = new Bar();
                bar.DoIt();
                log.Info("Exiting application.");
                Console.ReadLine();
            }
        }
    }
    
  • 第一個範例程式之設定檔 config.xml

  • <log4net>
      <!-- 輸出到Console -->
      <appender name="A1" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%date %-5level %logger - %message%newline" />
        </layout>
      </appender>
      
      <!-- 輸出到檔案 -->
      <appender name="A2" type="log4net.Appender.RollingFileAppender">
        <file value="d:/logfile.log" /> <!-- 輸出檔名 -->
        <appendToFile value="true" />
        <maximumFileSize value="2048KB" /> <!-- 每個檔案最大size -->
        <maxSizeRollBackups value="5" />
        <rollingStyle value="Date" />
        <datePattern value="yyyyMMdd-HHmm" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level %logger (%file:%line) - %message%newline" />
        </layout>
      </appender>
    
      <root>
        <!-- 輸出訊息等級 -->
        <level value="INFO" />
        <appender-ref ref="A1" />
        <appender-ref ref="A2" />
      </root>
    </log4net>
    
  • 執行結果 - Console
    2006-07-01 20:59:32,437 INFO  Log4Net.Program - Entering application.
    2006-07-01 20:59:32,468 FATAL Log4Net.Bar - Fatal
    2006-07-01 20:59:32,468 INFO  Log4Net.Program - Exiting application.
    
  • 執行結果 - logfile.log
    INFO  Log4Net.Program 
        (D:\Project\CS\Log4Net\Log4Net\Program.cs:26) - Entering application.
    FATAL Log4Net.Bar 
        (D:\Project\CS\Log4Net\Log4Net\Program.cs:14) - Fatal
    INFO  Log4Net.Program 
        (D:\Project\CS\Log4Net\Log4Net\Program.cs:29) - Exiting application.
    
  • 註1: 因為LogManager在namespace log4net,XmlConfigurator在namespace log4net.Config, 所以將這兩個namespace引入。
    註2: 特別注意LogManager.GetLogger的參數,一定要是所在的class,這樣輸出的訊息才能正確 指出是由那一個class輸出的。
    註3: 載入設定檔。
    註4: 輸出訊息,訊息有五種等級由低而高為Debug、Info、Warn、Error、Fatal,訊息要輸出那一 等級的訊息,由<root>裡的<level>設定,上面的設定檔設為INFO,則所有大於等於INFO的訊息 都會輸出。
        除了上述四項外,請各位網友注意一下Console輸出和檔案輸出的格式不同,這可由<appender>中設定。
    看完第一個範例程式基本上就可以運用在大多數的專案中了,底下第二個範例則要解說, 當輸出訊息很多,不適合全部輸出到同一個檔案時,如何將訊息依class輸出到不同檔案。



  • 第二個範例程式
    using System;
    using First;
    using log4net;
    using log4net.Config;
    
    namespace First
    {
        public class GrandFather
        {
            public GrandFather()
            {
                //System.Reflection.MethodBase.GetCurrentMethod().DeclaringType
                //可取得class type
                ILog log =  LogManager.GetLogger(
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                log.Error("年邁的阿公");
            }
        }
    }
    
    namespace Second
    {
        public class Father : GrandFather
        {
            public Father()
            {
                ILog log = LogManager.GetLogger(
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                log.Fatal("嚴父");
            }
        }
    
        public class Child : Father
        {
            public void Play()
            {
                ILog log = LogManager.GetLogger(
                    System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
                log.Warn("貪玩的小孩");
            }
        }
    
        class Program
        {
            static void Main(string[] args)
            {
                //於程式中只要執行一次即可
                XmlConfigurator.Configure(new System.IO.FileInfo("d:/config.xml"));            
    
                Child child = new Child();
                child.Play();
                
                Console.ReadLine();
            }
        }
    }
    
  • 第二個範例程式的設定檔 config.xml
    <log4net>
      <appender name="A1" type="log4net.Appender.ConsoleAppender">
        <layout type="log4net.Layout.PatternLayout">
          <!-- Print the date in ISO 8601 format -->
          <conversionPattern value="%date %-5level %logger - %message%newline" />
        </layout>
      </appender>
      
      <appender name="A2" type="log4net.Appender.RollingFileAppender">
        <file value="d:/logfile.log" />
        <appendToFile value="true" />
        <maximumFileSize value="2048KB" />
        <maxSizeRollBackups value="5" />
        <rollingStyle value="Date" />
        <datePattern value="yyyyMMdd-HHmm" />
        <layout type="log4net.Layout.PatternLayout">
          <conversionPattern value="%level %logger (%file:%line) - %message%newline" />
        </layout>
      </appender>
    
      <!-- 所有的訊息輸出都要輸出到A1 -->
      <root>
        <level value="INFO" />
        <appender-ref ref="A1" />
      </root>
      
      <!-- 僅namespace Second中的Child class輸出訊息至A2 -->
      <logger name="Second.Child">
        <level value="DEBUG" />
        <appender-ref ref="A2" />
      </logger>
    
    </log4net>
    
  • 執行結果 - Console
    2006-07-01 23:17:43,843 ERROR First.GrandFather - 年邁的阿公
    2006-07-01 23:17:43,843 FATAL Second.Father - 嚴父
    2006-07-01 23:17:43,843 WARN  Second.Child - 貪玩的小孩
    
  • 執行結果 - logfile.log
    WARN  Second.Child (D:\Project\CS\Log4Net\Log4Net\Program.cs:35) - 貪玩的小孩