NLog 基本介紹與偵錯

NLog一直以來都是以好用上手聞名,使用上也很少遇到問題,直到最近開始使用較深一點的功能後,卻發生了沒寫入卻又沒有錯誤訊息可以追查的事件

首先就先介紹一下NLog的基本功能

最重要的東西就是NLog.Config這個檔案了,裡面主要有兩個比較重要的元素構成

  1. Target
  2. Rules

 

Target

裡面可以選用NLog就內建的一些系統參數

你也可以選擇target輸出的是file, db, email.... 之類的,真的是太便利了

不外乎就是basedir:目前的執行路徑, counter 第幾行,  logger 像是 namespace的東西, 

如果要記中文類的,encoding 記得要設成utf-8,否則會有亂碼產生

 <target name="file" xsi:type="File"
              fileName="${basedir}/App_Data/Logs/${shortdate}/${logger}.txt"
              layout="${counter} | ${longdate} | ${level:uppercase=true} | ${logger:shortName=true} 
              | ${message} ${newline}" encoding="utf-8"/>

 

Rule

 你可以設定自定的規則,logger name 不設限的話,全部會寫到我們上面所定義的 file target

但要注意的是這邊設定的是只有Info level的資料

請參考目前的 level 有哪些,最低的是Trace, 最高的則是 Fatal

<logger name="*" level="Info" writeTo="file" />

 甚至你可以這樣定義,所有在System.Web.Controllers的namespace都可以寫到你所指定的 target裡

<logger name="System.Web.Controllers.*" minlevel="Info" writeTo="Controllerfile"  />

要特別注意的是,如果你這兩條rule都加的話,這兩個log可是都會寫到不同的兩個地方去,所以你的log可是會多一倍的資料

再來要注意的是,如果你的namespace 沒有吻合到任何一條rule, 就會發生記不到的情況了

另一個minlevel 若設為 Info,代表的只有這幾個log level 才會被記進去, 保守起見的話還是設成最低的Trace

  • Fatal
  • Error
  • Warn
  • Info

 

偵錯

預設來說,NLog都是發生錯誤不會導出錯誤訊息, 在NLog中可以這樣設置

      throwExceptions="true"
      internalLogLevel="Trace" internalLogFile="c:\temp\nlog-internal.log">

當你發佈到正式環境時,但卻又沒有Log產生時,你可以設定這樣,如此一來就可以到指定的路徑查看錯誤的原因了

錯誤的來源可說是有極多可能,比如說權限設定,config是不是正確的XML 檔案

這些輸出的訊息都是有極大的幫助

權限不足錯誤

若是在c:\temp\nlog-internal.log看到這類的錯誤訊息 Exception: System.UnauthorizedAccessException: Access to the path 'C:\www\xxx\App_Data\Logs\2018-05-17\' is denied.

請在Log資料夾加上 IIS AppPool/[your iis identity] 的權限至該 folder,並授予足夠的權限可以寫入資料

 

雖然有這些debug工具可以使用,然而還是遇到了一個奇異的情況

那就是logger並沒有完整的呈現出我所定義的namespace,而是出現了Lambda_method 這樣的奇怪字眼

若是rule是以logger來做設定的話,你會發現一件事,就是你的log怎樣都記不到

然而去設定internalLogFile的偵錯日誌也看不出問題在哪

最後找了一些資料才發現這種情況是IoC (如Ninject, Autofac這一類的IoC套件)所產生的,而debug模式deploy的程式非常正常

但release模式deploy的卻會有這樣的情況

所以解決方案會有兩種

1. 使用debug mode發佈測試跟正式環境,但就得注意一下debug模式底下web.config的設定發佈到正式環境會不會產生問題

2. 修改IoC套件注入的方式,可參考這樣的做法

參考資料

https://github.com/nlog/NLog/wiki/Layout-Renderers

https://github.com/NLog/NLog/wiki/Configuration-file#log-levels

https://github.com/NLog/NLog/issues/364

https://stackoverflow.com/a/4525456 

https://support.appharbor.com/discussions/problems/804-nloglogmanagergetcurrentclasslogger