March 30, 2013

Logging framework - NLog安裝與設定

公司目前使用的logging framework主要是Enterprise Library的Logging Application Block,前陣子在系統某個獨立的模組中使用了log4net感覺還不差,最近一個新專案則改用NLog試試,以下是安裝方式及設定技巧。

在Package Manager Console中輸入Install-Package NLog,這個指令會將NLog安裝到專案中,安裝完後基本上就可以開始使用NLog了。不過要注意的是使用這指令僅會安裝NLog的DLL檔,並不會有任何文件設定檔(*.config等)。即便如此,我們已經可以開始使用NLog,只是必須透過其所提供的Configuration API設定,即所有的設定皆寫在程式碼中。通常我們還是會以文件設定檔的方式來做設定比較有彈性,畢竟production環境和測試用環境的設定並不一定相同,例如在測試環境中你會想記錄debug資訊,而在production中可能會先記錄warn層級以上的資訊(warn/error/fatal),必要時再修改成debug層級以便追蹤問題。

透過Install-Package NLog.Config指令,我們可以安裝NLog的設定檔(nuget會先檢查NLog的DLL檔是否已經安裝,若沒有的話也會一併安裝)。安裝的過程中可能會出現錯誤訊息,可以先忽略它。錯誤的原因推測可能是我沒有安裝PowerShell的關係,從錯誤訊息看起來似乎是想將NLog.config的Copy to Output Directory屬性改成Copy if newer及Build Action屬性改成Content。這部份我們可以手動來修改,所以問題不大。


完裝完成後在專案中可看到NLog.configNLog.xsd兩個檔案。NLog.config即是NLog的設定檔,NLog.xsd則是NLog.config的結構描述檔。有了NLog.xsd,在Visual Studio中就可以透過Intellisense的支援設定NLog.config,相當方便,這也是log4net所沒有支援的(雖然有熱心網友提供,但畢竟不是官方出品)。
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <!--
  See http://nlog-project.org/wiki/Configuration_file
  for information on customizing logging rules and outputs.
   -->

  <targets>
    <!-- add your targets here --> 

    <!--
    <target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log"
            layout="${longdate} ${uppercase:${level}} ${message}" />
    -->
  </targets>

  <rules>
    <!-- add your logging rules here -->  

    <!--
    <logger name="*" minlevel="Trace" writeTo="f" />
    -->
  </rules>
</nlog>

上面是NLog.config的預設樣板,整個設定檔的設定方式基本上圍繞在targets和rules兩個元素。targets代表你想要輸出log成什麼型態的資料和資料格式的配置(layout),例如文字檔或事件紀錄(event log);rules代表你想針對哪些log層級(debug/warn/error/fatal等)做設定及寫到哪個target。要注意的是預設樣板將target和logger註解起來,若要使用請記得將註解移除。

以預設樣版來說明,在targets元素中宣告了一個名稱為f的target元素,用於將log寫到文字檔中(xsi:type="File"),log會寫到fileName屬性的路徑中,而log的內容會使用layout屬性裡的格式。而在rules元素中則宣告了一個logger元素,最小層級為Trace,表示只要是Trace以上的層級都會被記錄,而writeTo則表示要將log寫到名為f的target。有用過log4net的朋友應該會覺得這其實和log4net的appender及logger概念類似。

在fileName及layout屬性中可以看到如${basedir}或${longdate}這樣的參數,這是NLog所提供的內建樣板參數,稱之為Layout Renders。當然這些內建參數有可能無法達到你的需求,這時可以透過Event Context Layout Renderer來自訂參數。

拿掉預設樣板的註解並執行底下測試程式
using NLog;

namespace NLogTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Logger logger = LogManager.GetCurrentClassLogger();
            logger.Debug("this is a Debug level");
            logger.Trace("this is a Trace level");
            logger.Warn("this is a Warn level");
            logger.Error("this is a Error level");
        }
    }
}

接下來可以在bin/Debug/logs下看到*.log檔案,內容為

2013-03-30 19:06:15.9555 DEBUG this is a Debug level
2013-03-30 19:06:16.0688 TRACE this is a Trace level
2013-03-30 19:06:16.0688 WARN this is a Warn level
2013-03-30 19:06:16.0688 ERROR this is a Error level

接下來我們將設定檔logger元素中的minLevel屬性改成Debug後重新執行程式,輸出的內容會再加上

2013-03-30 19:08:05.3901 DEBUG this is a Debug level
2013-03-30 19:08:05.3901 WARN this is a Warn level
2013-03-30 19:08:05.3901 ERROR this is a Error level

可以發現Trace的部份不見了,原因是在NLog中,Trace層級比Debug層級還低,所以minLevel改為Debug後只會記錄Debug層級以上的資料。透過這樣的設定方式,我們可以在production環境中設為Warn層級,當需要追蹤更細部的問題時改為Trace或Debug層級,完全不需要重新佈署程式。不過要特別注意的是,如果要讓NLog在更改設定檔後重新自動載入新設定則需要在nlog元素中加上autoReload屬性並設定為true

參考

No comments: