log4net

    (史帝芬, 2006/07/01, hi.steven@gmail.com)

    使用Java開發程式的人多半用過 log4j,也多半對於 log4j 的小巧好用留下深刻的印象,現在 log4j 有了.net 版了! 這就是本篇要介紹的主題。在繼續往下看之前當然要先到官方網站上下載 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) - 貪玩的小孩