筆記如何透過 NLog 並且在 ASP.NET MVC 使用 Exception Filter 的方式達成發生例外情形時,儲存為日誌資訊,讓系統維護人員能夠主動出擊處理問題。

說明
需要日誌紀錄的原因:
一、依照系統設計的安全性需求,紀錄管理者行為、身分驗證行為、存取資源行為與重要資料異動等留下稽核紀錄。
二、將例外情形發生時,儲存相關資訊為日誌紀錄,讓系統維護人員在處理問題時能夠得到更詳盡甚至是還原使用者所碰到的問題。
Nuget Install
<package id="NLog" version="5.1.4" targetFramework="net48" />
<package id="NLog.Config" version="4.7.15" targetFramework="net48" />
<package id="NLog.Database" version="5.1.4" targetFramework="net48" />
<package id="NLog.Extensions.Logging" version="5.2.3" targetFramework="net48" />
<package id="NLog.Schema" version="5.1.4" targetFramework="net48" />
<package id="NLog.Web" version="5.2.3" targetFramework="net48" />
```
<code class="watch">/NLog.config</code>
```xml
<?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"
xsi:schemaLocation="http://www.nlog-project.org/schemas/NLog.xsd NLog.xsd"
autoReload="true"
throwExceptions="true"
internalLogLevel="Off" internalLogFile="c:\temp\nlog-internal.log">
<!-- optional, add some variables
https://github.com/nlog/NLog/wiki/Configuration-file#variables
-->
<variable name="myvar" value="myvalue"/>
<!--
See https://github.com/nlog/nlog/wiki/Configuration-file
for information on customizing logging rules and outputs.
-->
<extensions>
<add assembly="NLog.Web"/>
</extensions>
<targets>
<target name="database" xsi:type="Database" connectionStringName="NorthwindEntities">
<commandText>
insert into dbo.Log
(
MachineName, Logged, Level, Message, Exception, UserName, IP, RequestUrl
)
values (
@MachineName, @Logged, @Level, @Message, @Exception, @UserName, @IP, @RequestUrl
);
</commandText>
<parameter name="@MachineName" layout="${machinename}" />
<parameter name="@Logged" layout="${date}" />
<parameter name="@Level" layout="${level}" />
<parameter name="@Message" layout="${message}" />
<parameter name="@Exception" layout="${exception:tostring}" />
<parameter name="@UserName" layout="${aspnet-user-identity}" />
<parameter name="@IP" layout="${aspnet-request-ip}" />
<parameter name="@RequestUrl" layout="${aspnet-request-url}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="database" />
</rules>
</nlog>
除了使用 NLog.web
的方式來使用 aspnet-user-identity
、aspnet-request-ip
以及 aspnet-request-url
等方式來分別取得使用者名稱、來源 IP 以及目標路徑外,也可以使用 NLog 的 WithProperty
來自行傳遞資料:
NLog.web | With Property |
---|---|
aspnet-user-identity | context.HttpContext.User.Identity.Name |
aspnet-request-ip | context.HttpContext.Request.UserHostAddress |
aspnet-request-url | context.HttpContext.Request.Url |
Application_Error
Global.asax.cs
void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
var logger = LogManager.GetCurrentClassLogger();
logger.Error(exception);
}
Application_Error in global.asax not catching errors in WebAPI
ExceptionFilter
ASP.NET MVC實現IExceptionFilter接口編寫自定義異常處理過濾器
HandleErrorAttribute
HandleErrorAttribute 是 ASP.NET MVC 預設實作的例外處理機制,會透過 FilterConfig.cs
註冊的全域中,讓所有發生的 ASP.NET Http Status Code 500 Error (對 🙂 只有 500,404 等其他 Http Status Code 並不會) 都會經由 HandleErrorAttribute
處理。而 HandleErrorAttribute
的處理就是以 /Views/Shared/Error.cshtml 作為回應結果。
using NLog;
using System.Web.Mvc;
public class NLogExceptionFilter : HandleErrorAttribute
{
private readonly Logger logger = LogManager.GetCurrentClassLogger();
public override void OnException(ExceptionContext context)
{
logger.Error(context.Exception);
}
}
[NLogExceptionFilter]
public class HomeController : Controller
{
// ...
}