Asp.net

ASP.Net MVC 6 中的全域錯誤日誌記錄

  • February 1, 2017

我正在測試 MVC 6 Web Api 並希望實現登錄到全域錯誤處理程序。只是保證沒有錯誤會在沒有被記錄的情況下離開系統。我創建了一個 ExceptionFilterAttribute 並在啟動時將其全域添加:

public class AppExceptionFilterAttribute : ExceptionFilterAttribute
{
   public override void OnException(ExceptionContext context)
   {
       //Notice pulling from HttpContext Application Svcs -- don't like that
       var loggerFactory = (ILoggerFactory)context.HttpContext.ApplicationServices.GetService(typeof (ILoggerFactory));

       var logger = loggerFactory.Create("MyWeb.Web.Api");
       logger.WriteError(2, "Error Occurred", context.Exception);

       context.Result = new JsonResult(
           new
           {
               context.Exception.Message,
               context.Exception.StackTrace
           });
   }
}

現在在啟動時,我將這個過濾器添加到:

services.Configure<MvcOptions>(options =>
{
   options.Filters.Add(new AppExceptionFilterAttribute());
});

這一切似乎都是蠻力……有沒有更好的方法可以使用 MVC 6 到達這裡?

我不喜歡或不確定這種方法的事情:

  1. 不喜歡從 http 上下文中提取 DI
  2. 沒有太多關於引發錯誤的控制器的上下文(也許我可以通過某種方式從上下文中獲取它)。

我能想到的另一個選擇是有一個基本控制器,它接受所有控制器都繼承的 ILoggerFactory。

想知道是否有某種診斷中間件可以插入日誌記錄…

你的問題有兩個部分。1) DI 可注射過濾器 2) 全域錯誤處理。

關於#1:您可以ServiceFilterAttribute用於此目的。例子:

//Modify your filter to be like this to get the logger factory DI injectable.
public class AppExceptionFilterAttribute : ExceptionFilterAttribute
{
   private readonly ILogger _logger;
   public AppExceptionFilterAttribute(ILoggerFactory loggerfactory)
   {
      _logger = loggerFactory.CreateLogger<AppExceptionFilterAttribute>();
   }
   public override void OnException(ExceptionContext context)
   {
       //...
   }
}

//Register your filter as a service (Note this filter need not be an attribute as such)
services.AddTransient<AppExceptionFilterAttribute>();

//On the controller/action where you want to apply this filter,
//decorate them like
[ServiceFilter(typeof(AppExceptionFilterAttribute))]
public class HomeController : Controller
{
....
}

您應該能夠從ExceptionContext傳遞的控制器中獲取控制器的詳細資訊。

關於#2:從你以前的文章看起來你正在玩ExceptionHandlerMiddleware擴展源)……使用它怎麼樣?……關於它的一些資訊:

  • 這個中間件是通用的,適用於在它之後註冊的任何中間件,因此任何諸如控制器/動作資訊之類的概念都是特定於 MVC 的,中間件不會知道。
  • 此中間件不處理格式化程序寫入異常。您可以編寫自己的緩衝中間件,在其中可以將響應主體修改為緩衝流(MemoryStream),並讓 MVC 層將響應寫入它。在格式化程序寫入異常的情況下,您可以擷取它並發送帶有詳細資訊的 500 錯誤響應。

引用自:https://stackoverflow.com/questions/28967183