NLog 是在.Net Framework 中最熱門的 Log 記錄工具之一,它不僅使用簡單,並且設定檔的設定項目也十分豐富。
基本上,它的Layout能滿足大多設定上的需求,但因為可設定項目太多,光是要輸出個可以方便抓蟲的完整 Exception 資訊,可能就要試了老半天,
所以本篇就針對Exception 的 Layout 用法加以介紹,方便大家設定。
NLog 是在.Net Framework 中最熱門的 Log 記錄工具之一,它不僅使用簡單,並且設定檔的設定項目也十分豐富。
基本上,它的Layout能滿足大多設定上的需求,但因為可設定項目太多,光是要輸出個可以方便抓蟲的完整 Exception 資訊,可能就要試了老半天,
所以本篇就針對Exception 的 Layout 用法加以介紹,方便大家設定。
文章使用版本: NLog v2.0
下載方式: NuGet
Layout基本格式
Layout 的內容分純文字(plain text)與變數預留位置(variable placeholder),如 "Msg: ${message}",被 ${} 包住的文件就是 Layout 的變數,在產生一筆記錄時 ${variable} 會換成變數值,而不在 ${} 中的文字就是純文字啦。
Layout 的設定可以參考: http://nlog-project.org/wiki/Layout_renderers
而每一個變數可能會有選項,選項與變數或其他選項用 : (冒號)分隔,而選項與值使用 = (等號)連結,如 ${exception:format=Type}
使用範例
以下範例皆使用此程式執行,僅換掉 Layout 部分
class Program
{
private static Logger logger = LogManager.GetCurrentClassLogger();
static void Main(string[] args)
{
try
{
throw new InvalidProgramException("發生錯誤啦", new ArgumentException("args沒有值"));
}
catch (Exception ex)
{
logger.ErrorException("執行失敗", ex);
}
}
}
1. layout="${message} - ${exception}"
輸出:
執行失敗 - 發生錯誤啦
個人使用心得: 不好,只知道有錯誤,卻不知道錯誤的明細。
2. layout="${message} - ${exception} - ${stacktrace}"
輸出:
執行失敗 - 發生錯誤啦 - Program.Main
個人使用心得: 不好,雖然知道那一個Main出錯了,但不知道那一行。
3. layout="${message} - ${exception} - ${stacktrace:format=Raw}"
輸出:
執行失敗 - 發生錯誤啦 - Main at offset 176 in file:line:column <filename unknown>:0:0
個人使用心得: XD,看不懂後面的東西是什麼。
4. layout="${message} - ${exception} - ${stacktrace:format=DetailedFlat}"
輸出:
執行失敗 - 發生錯誤啦 - [Void Main(System.String[])]
個人使用心得: XD,只有 Mathod 與 Paramaters 好像沒有幫助了。
個人心得:
${stacktrace} 對輸出 Exception 資訊的用途很小,不過對非 Exception 的記錄多少有幫助,例如是在哪一個 Method 中呼叫 logger.Info("我是訊息") 的,不過用來抓蟲資訊又嫌不足。
5.layout="${message} - ${exception:format=Type}"
輸出:
執行失敗 - System.InvalidProgramException
個人使用心得: XD,只有Type好像沒有什麼幫助。
6.layout="${message} - ${exception:format=StackTrace}"
輸出:
執行失敗 - 於 NlogTest.Program.Main(String[] args) 於 Program.cs: 行 17
個人使用心得: 好像有一點幫助了,但沒有Exception的訊息阿。
7.layout="${message} - ${exception:format=ToString}"
輸出:
執行失敗 - System.InvalidProgramException: 發生錯誤啦 ---> System.ArgumentException: args沒有值--- 內部例外狀況堆疊追蹤的結尾 ---於 NlogTest.Program.Main(String[] args) 於 Program.cs: 行 17
個人使用心得: 搞了半天還是 Exception.ToString() 的資料才是最完整的,而且 InnerException 的資訊也有顯示出來。
8.layout="${message} ${onexception:inner=${newline} *****Error***** ${newline} ${exception:format=ToString}}"
輸出:
執行失敗*****Error*****System.InvalidProgramException: 發生錯誤啦 ---> System.ArgumentException: args沒有值 --- 內部例外狀況堆疊追蹤的結尾 --- 於 NlogTest.Program.Main(String[] args) 於 Program.cs: 行 17
個人使用心得: 如果你懶得用2個 Layout 來顯示一般訊息與有 Exception 訊息,可以使用 ${onexception:inner= layout } 當發生 Exception 時才輸出特定的 Layout。
而當編譯成 .dll 或 .exe 後為什麼 Exception 的 StackTrace 呢?
祕密就在 .pdb (符號檔)檔案中,這個檔案會記錄原始檔案資訊,如 IL 對應到原始檔案的那一行,Debugger 想要中斷點也必需要靠這個檔案。
所以程式在執行時沒有部署 .dll 或 .exe 的 .pdb 檔,當發生 Exception 時,StackTrace 就不會有檔案的資訊與行號。
當然不部署 .pdb 也是有好處的,.pdb 檔案記錄得東西很多,所以不會太小,執行時不載入 .pdb 檔,可以節省一些記憶體空間。