Logging Application Block (一):入門教學

摘要:本文說明 Enterprise Library 的 Logging Application Block 的基本用法,其中包含兩個 step-by-step 練習,分別示範將 log 訊息輸出至 Windows 事件檢視器以及可循環使用的純文字 log 檔案。


小引

幾乎每個企業級的軟體系統都需要輸出 log 訊息的機制,例如:輸出到資料庫、純文字檔案、Windows 事件日誌、寄送 e-mail 通知等等。目前不管是 Java 還是 .NET 平台,都已經有許多現成的 logging 元件可用。在選擇 .NET 平台的 logging 元件時,我試了 NLogEnterprise Library 的 Logging Application Block,這兩個都很不錯,最後選擇了後者,主要是因為 (1) EL 是由微軟官方釋出,而且(比較可能)持續出新版;(2) EL 與微軟自家平台和工具的整合(通常)較緊密 ,例如:與 Visual Studio 整合、與 WCF 整合。簡單地說,就是以將來的持續維護和發展為主要考量。

那麼,為什麼不考慮 log4net 呢?一方面是因為以前用過 log4j,印象中感覺在設定方面有點麻煩,而且,最重要的是 log4net 已經很久很久沒更新了。

接著就來看如何在應用程式中使用 EL 的 Logging Application Block 來輸出 log 訊息。

安裝元件

若使用 VS2005+.NET Framework 2.0 ,請下載 Enterprise Library 3.1。如果是 VS2008+.NET Framework 3.x,目前最新的版本是 Enterprise Library 4.1

練習 1:寫入 Windows Event Log

步驟如下:
  1. 建立一個新的 Console 專案,命名為 WindowsEventLogDemo。
  2. 在專案中加入應用程式組態檔,然後把自動開啟的 App.config 編輯視窗關閉。
  3. 在 Solution Explorer 中的 App.config 上點右鍵,選「Edit Enterprise Library Configuration」。如下圖:



  4. 接著會在 Visual Studio 中開啟 Enterprise Library 的組態檔編輯器。在 App.config 項目上點右鍵,選 New > Logging Application Block。



  5. 接著你會在 App.config 編輯視窗中看到預設幫你建立的 Formatted EventLog TraceListener。先儲存 App.config,並將編輯視窗關閉,再到 Solution Explorer 中雙擊 App.config,大概瀏覽一下組態檔的內容。
  6. 加入 Enterprise Library Logging Application Block 組件參考。



  7. 編輯 Program.cs。先 using Microsoft.Practices.EnterpriseLibrary.Logging 命名空間,然後在 Main 函式中撰寫輸出 log 訊息的程式碼。如下所示:
   1:          static void Main(string[] args)
   2:          {
   3:              if (Logger.IsLoggingEnabled())
   4:              {
   5:                  LogEntry log = new LogEntry();
   6:                  log.Severity = System.Diagnostics.TraceEventType.Information;
   7:                  log.Message = "測試 log 訊息,嚴重層級:Information。";
   8:                  log.Title = "log 標題";
   9:                  log.TimeStamp = DateTime.Now;
  10:                  Logger.Write(log);
  11:  
  12:                  log.Severity = System.Diagnostics.TraceEventType.Error;
  13:                  log.Message = "測試 log 訊息,嚴重層級:Error。";
  14:                  Logger.Write(log);
  15:              }
  16:          }

此範例程式輸出兩個 log 訊息到 Windows 事件檢視器,一個是 Information 層級,一個是 Error 層級。按 F5 執行此程式,然後開啟事件檢視器,應該就可以看到程式輸出的 log。參考下圖:



練習 2:Roll, Log Roll!

EL 的 Logging Application Block 提供多種 log 輸出目標,這裡再示範循環式 Log 檔案的做法,使用的 trace listener 是 Rolling Flat File Trace Listener。

方便起見,這裡就直接修改剛才的範例。步驟如下:
  1. 在 Solution Explorer 中的 App.config 上點右鍵,選「Edit Enterprise Library Configuration」。
  2. 在 Logging Application Block 之下的 Trace Listeners 節點上點右鍵,選 New > Rolling Flat File Trace Listener。參考下圖:



  3. 接著到屬性視窗修改此 trace listener 的屬性。這裡僅修改 FileName 和 RollSizeKB 屬性:
    FileName = trace.log (Log 檔名,可包含相對或絕對路徑名稱)
    RollSizeKB = 2 (代表每當 log 檔案大小超過 2KB 時,就把舊的 log 丟棄,重新寫入)



    由於這裡的 FileName 並未指定路徑名稱,因此 log 檔會輸出在應用程式所在的目錄下。
  4. 在節點 Logging Application Block > Category Sources > General 上點右鍵,選 New > Trace Listener Reference。



  5. 點一下剛剛新建立的 TraceListener Reference 節點,再到屬性視窗中設定其 ReferencedTraceListener 屬性。設定時可直接從屬性值的下拉清單挑選 "Rolling Flat File Trace Listener"。
  6. 程式碼都不用改,直接按 F5 執行,然後用檔案總管瀏覽此專案的執行檔所在的目錄,應該會有一個 trace.log。每執行一次,新的 log 訊息會附加在檔尾。執行個兩三次之後,log 檔案應該就會超過 2K,觀察看看是否每超過 2K 就會重新寫入。
Rolling Flat File Trace Listener 還有兩個屬性可能也常用到:RollInterval 和 TimeStampPattern。

RollInterval 可以讓你依特定的時間間隔來建立不同的 log 檔,可用的時間間隔包括:None(預設)、Minute、Hour、Day、Week、Month、Year。每當輸出 log 訊息時,trace listener 會拿現在時間跟上一次輸出 log 訊息的時間比較,若超出指定的間隔時間,就另外產生一個檔案。

那麼,每一次產生的檔案名稱一定不同,它是用甚麼命名規則呢?這就要看 TimeStampPattern 屬性的設定值了(可別誤以為這個屬性是 log 訊息的時間欄位格式喔!)。這個屬性的預設值為 yyyy-MM-dd,所以每次建立 log 檔時,檔案名稱會是:

[FileName 的主檔名].[TimeStampPattern].[FileName 的副檔名]

例如:trace.2009-03-09.log。

訊息的時間格式

還有一個常見的問題:如果前面的範例程式碼的第 9 行沒寫的話(不指定 TimeStamp 屬性),logging 元件預設會用 UTC 時間,結果輸出的 log 訊息中,顯示的時間就會跟台北時間相差八小時。此問題的解法同時也能夠讓你自訂 log 訊息的時間格式。作法如下:
  1. 如練習 2 的步驟 1,開啟 Enterprise Library 的組態檔編輯器。
  2. 選取 Logging Application Block > Trace Listeners > Rolling Flat File Trace Listener 節點,然後到屬性視窗中修改 Formatter 屬性,將它改為 TextFormatter。
  3. 接著展開 Formatter 屬性左邊的加號,修改底下的 Template 屬性,把樣板內容裡面的 Timestamp 欄位樣式改成這樣:

    Timestamp: {timestamp(local:yyyy-MM-dd HH:mm:ss)}

    參考下圖:


基礎的用法大概就介紹到這裡,其他屬性應該稍微試一下就會用啦。Happy coding :)

相關文章

Post Comments

技術提供:Blogger.