記錄Exception的內容
使用NLog的最大一個功能就是要去捕捉並且記錄下發生Exception的訊息與內容,
而在有關「使用NLog - Advanced .NET Logging 」系列的文章中都有說明到如何記錄以及記錄哪些資料,
NLog有提供很多的Layout Renderer可以使用,而Exception Layout Renderer更是要好好的來仔細整理一下,
首先看一下在「使用NLog - Advanced .NET Logging (1)」中有介紹的一個方法「LogUtility.BuildExceptionMessage()」
public class LogUtility
{
/// <summary>
/// Builds the exception message.
/// </summary>
/// <param name="x">The x.</param>
/// <returns></returns>
public static string BuildExceptionMessage(Exception x)
{
Exception logException = x;
if (x.InnerException != null)
{
logException = x.InnerException;
}
StringBuilder message = new StringBuilder();
message.AppendLine();
message.AppendLine("Error in Path : " + System.Web.HttpContext.Current.Request.Path);
// Get the QueryString along with the Virtual Path
message.AppendLine("Raw Url : " + System.Web.HttpContext.Current.Request.RawUrl);
// Type of Exception
message.AppendLine("Type of Exception : " + logException.GetType().Name);
// Get the error message
message.AppendLine("Message : " + logException.Message);
// Source of the message
message.AppendLine("Source : " + logException.Source);
// Stack Trace of the error
message.AppendLine("Stack Trace : " + logException.StackTrace);
// Method where the error occurred
message.AppendLine("TargetSite : " + logException.TargetSite);
return message.ToString();
}
}
這邊稍微修改 NLog.Config 裡 Fatal Target 的設定
<target name="FatalFile" xsi:type="File"fileName="${basedir}/App_Data/Logs/${shortdate}/FatalFile.txt"layout="====================================================================================================${newline}發生時間:${longdate} ${newline}${newline}Log等級:${level:uppercase=true} ${newline}${newline}Logger:${logger} ${newline}${newline}Source:${callsite:className=true} ${newline}${newline}錯誤訊息:${message} ${newline}${newline}====================================================================================================${newline}"/>
然後在程式中實際應用
public ActionResult About()
{try
{int a = 6;
int b = 0;
int result = a / b;
}catch (Exception ex)
{logger.Fatal(LogUtility.BuildExceptionMessage(ex));}return View();
}
最後得到的記錄結果
====================================================================================================發生時間:2011-11-21 21:52:05.1874Log等級:FATALLogger:Test.Web.Controllers.HomeControllerSource:Test.Web.Controllers.HomeController.About錯誤訊息:Error in Path : /Home/AboutRaw Url : /Home/AboutType of Exception : DivideByZeroExceptionMessage : 嘗試以零除。Source : Test.WebStackTrace : 於 Test.Web.Controllers.HomeController.About() 於 D:\Develope\Lab\Lab_Of_NLog\Test.Web\Controllers\HomeController.cs: 行 27TargetSite : System.Web.Mvc.ActionResult About()====================================================================================================
但如果想要記錄到Exception裡更詳細的InnerException內容時,那是必要去修改以上的「LogUtility.BuildExceptionMessage()」
但其實不用自己來寫,因為NLog有提供Layout Renderer的設定
NLog - Exception logging enhancements
依據文件中所提供的內容,我們對Fatal Taeget做了修改:
<target name="FatalFile" xsi:type="File"fileName="${basedir}/App_Data/Logs/${shortdate}/FatalFile.txt"layout="====================================================================================================${newline}發生時間:${longdate} ${newline}${newline}Log等級:${level:uppercase=true} ${newline}${newline}Logger:${logger} ${newline}${newline}Source:${callsite:className=true} ${newline}${newline}錯誤訊息:${message} ${newline}${newline}StackTrace:${newline}${exception:format=stacktrace}${newline}${newline}Exception類別:${exception:format=type} ${newline}${newline}Exception訊息:${exception:format=message} ${newline}${newline}${newline}InnerException Detail:${newline}${onexception:EXCEPTION OCCURRED\:${exception:format=type,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}}${newline}====================================================================================================${newline}"/>
這邊要特別提到的是「${exception:maxInnerExceptionLevel=N}」,
因為Exception發生時,其InnerException有可能會有包相當多層,
所以我們可以藉由這一個設定去讓NLog記錄到說多少層的InnerException內容,如此一來我們就不必去勞師動眾的改寫程式。
改好Fatal Target之後,我們將實際執行的程式再去做個修改:
public ActionResult About()
{try
{int a = 6;
int b = 0;
int result = a / b;
}catch (Exception ex)
{logger.Fatal(ex);}return View();
}
直接使用 logger.Fatal(ex) 的方式來記錄Exception內容,而得到的 Log資料如下:
====================================================================================================發生時間:2011-11-21 22:05:59.0481Log等級:FATALLogger:Test.Web.Controllers.HomeControllerSource:Test.Web.Controllers.HomeController.About錯誤訊息:System.DivideByZeroException: 嘗試以零除。於 Test.Web.Controllers.HomeController.About() 於 D:\Develope\Lab\Lab_Of_NLog\Test.Web\Controllers\HomeController.cs: 行 27StackTrace:Exception類別:Exception訊息:InnerException Detail:====================================================================================================
上面的Log資訊怎麼好像看起來不是我們所想要的…
其實NLog這邊對於Exception的紀錄方式有提供了一組方法,可以讓Nlog正確的記錄Exception內容
- TraceException()
- DebugException()
- InfoException()
- WarnException()
- ErrorException()
- FatalException()
- LogException() – takes log level as a parameter
所以我們去修改一下程式的內容也順便修改一下Fatal Target的內容:
<target name="FatalFile" xsi:type="File"fileName="${basedir}/App_Data/Logs/${shortdate}/FatalFile.txt"
layout="
====================================================================================================${newline}發生時間:${longdate} ${newline}${newline}Log等級:${level:uppercase=true} ${newline}${newline}
Logger:${logger} ${newline}${newline}Source:${callsite:className=true} ${newline}${newline}
錯誤訊息:${message} ${newline}${newline}StackTrace:${newline}${exception:format=stacktrace}${newline}${newline}Exception類別:${exception:format=type} ${newline}${newline}Exception訊息:${exception:format=message} ${newline}${newline}EXCEPTION OCCURRED:${newline}${exception:format=type,message,method:maxInnerExceptionLevel=5:innerFormat=shortType,message,method}${newline}====================================================================================================${newline}"
/>
public ActionResult About()
{try
{int a = 6;
int b = 0;
int result = a / b;
}catch (Exception ex)
{logger.FatalException("刻意產生的異常 ", ex);
}return View();
}
改用 logger.FatalException() 方法來記錄 Exception內容,而NLog所記錄的log內容如下:
====================================================================================================發生時間:2011-11-21 22:19:55.2339Log等級:FATALLogger:Test.Web.Controllers.HomeControllerSource:Test.Web.Controllers.HomeController.About錯誤訊息:刻意產生的異常StackTrace:於 Test.Web.Controllers.HomeController.About() 於 D:\Develope\Lab\Lab_Of_NLog\Test.Web\Controllers\HomeController.cs: 行 27Exception類別:System.DivideByZeroExceptionException訊息:嘗試以零除。EXCEPTION OCCURRED:System.DivideByZeroException 嘗試以零除。 System.Web.Mvc.ActionResult About()====================================================================================================
就log記錄的內容而言,都有正確的記錄到Exception的詳細內容。
這一邊簡單的說明一下如何使用NLog所提供的方法去正確的紀錄Exception內容,更清楚了解程式問題發生的原因。
參考連結:
NLog - Exception layout renderer
NLog - Exception logging enhancements
NLog - How to properly log exceptions?
以上
沒有留言:
張貼留言