ELMAH 日志处理异常
ELMAH Log handled exceptions
我正在使用 ELMAH 尝试并记录已处理的异常(发生在 try catch 中的异常)。但是我无法让 ELMAH 记录在 try catch 中发生的任何异常。
这是我的操作:
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model) {
try {
throw new Exception("Log me elmah");
}
catch (Exception e) {
ModelState.AddModelError("", "Something unexpected happened, please try again.");
return View(model);
}
}
我听从了这里的建议:
https://docs.elmah.io/elmah-and-custom-errors/ and here: How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?
但我的 ElmahExceptionLogger
只会因未处理的异常而被触发。
这是我的 ElmahExceptionLogger
:
public class ElmahExceptionLogger : IExceptionFilter {
public void OnException(ExceptionContext filterContext) {
if (filterContext.ExceptionHandled) {
ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
}
}
}
这是我的 global.asax
:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
这是我注册全局过滤器的方法:
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new ElmahExceptionLogger());
filters.Add(new HandleErrorAttribute());
/*Append no cache to all actions in all controllers so we don't cache any pages, I dont particularly like it because it means an increased server load
However there are reasons to this; The first being data gets updated regularly and we want users to have the most up-to-date data
And also you can press back after logging out to get to the cached page before. It can be overridden per action if needed */
filters.Add(new OutputCacheAttribute {
VaryByParam = "*",
Duration = 0,
NoStore = true
});
}
}
有谁知道如何让 ELMAH 在 try catch 中记录我的异常?
当然只有未处理的异常才会触发。这些过滤器仅 运行 用于允许冒泡的错误(意思是,未处理)。如果你想记录一个已处理的异常,那么你需要把那个 ErrorSignal.FromCurrentContext().Raise()
逻辑放在你的 catch 块中。
catch (Exception e)
{
ModelState.AddModelError("", "Something unexpected happened, please try again.");
ErrorSignal.FromCurrentContext().Raise(e);
return View(model);
}
如果您发现自己经常这样做,那么我建议您停止使用 Elmah。 Elmah 不是通用的日志记录框架,它适用于未处理的错误。最好使用 Serilog or Nlog and then have those log to a specialized system such as Seq.
等日志系统
虽然不完全是 "automatic" 这是我采用的一种方法,至少可以使 Try-Catch 块中的日志记录更容易。
我首先创建了异常的扩展 class:
Imports Elmah
Imports System
Imports System.Web
Imports System.Runtime.CompilerServices
Public Module ElmahExtension
<Extension()>
Public Sub LogToElmah(ex As Exception)
If HttpContext.Current Is Nothing Then
ErrorLog.GetDefault(Nothing).Log(New [Error](ex))
Dim req = New HttpRequest(String.Empty, "https://YOURWEBSITE", Nothing)
Dim res = New HttpResponse(Nothing)
Else
ErrorSignal.FromCurrentContext().Raise(ex)
ErrorLog.GetDefault(HttpContext.Current).Log(New [Error](ex))
End If
End Sub
End Module
要使用它,您可以这样做:
Try
YOUR CODE HERE
Catch
ex.LogToElmah()
End Try
这会将异常对象传递给 ELMAH 并记录错误。
所以不是很自动,但更容易。特别是,如果您使用 ReSharper 之类的工具来创建包含 "ex.LogToELMAH" 的代码快捷方式。
我正在使用 ELMAH 尝试并记录已处理的异常(发生在 try catch 中的异常)。但是我无法让 ELMAH 记录在 try catch 中发生的任何异常。
这是我的操作:
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model) {
try {
throw new Exception("Log me elmah");
}
catch (Exception e) {
ModelState.AddModelError("", "Something unexpected happened, please try again.");
return View(model);
}
}
我听从了这里的建议: https://docs.elmah.io/elmah-and-custom-errors/ and here: How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?
但我的 ElmahExceptionLogger
只会因未处理的异常而被触发。
这是我的 ElmahExceptionLogger
:
public class ElmahExceptionLogger : IExceptionFilter {
public void OnException(ExceptionContext filterContext) {
if (filterContext.ExceptionHandled) {
ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
}
}
}
这是我的 global.asax
:
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
}
这是我注册全局过滤器的方法:
public class FilterConfig {
public static void RegisterGlobalFilters(GlobalFilterCollection filters) {
filters.Add(new ElmahExceptionLogger());
filters.Add(new HandleErrorAttribute());
/*Append no cache to all actions in all controllers so we don't cache any pages, I dont particularly like it because it means an increased server load
However there are reasons to this; The first being data gets updated regularly and we want users to have the most up-to-date data
And also you can press back after logging out to get to the cached page before. It can be overridden per action if needed */
filters.Add(new OutputCacheAttribute {
VaryByParam = "*",
Duration = 0,
NoStore = true
});
}
}
有谁知道如何让 ELMAH 在 try catch 中记录我的异常?
当然只有未处理的异常才会触发。这些过滤器仅 运行 用于允许冒泡的错误(意思是,未处理)。如果你想记录一个已处理的异常,那么你需要把那个 ErrorSignal.FromCurrentContext().Raise()
逻辑放在你的 catch 块中。
catch (Exception e)
{
ModelState.AddModelError("", "Something unexpected happened, please try again.");
ErrorSignal.FromCurrentContext().Raise(e);
return View(model);
}
如果您发现自己经常这样做,那么我建议您停止使用 Elmah。 Elmah 不是通用的日志记录框架,它适用于未处理的错误。最好使用 Serilog or Nlog and then have those log to a specialized system such as Seq.
等日志系统虽然不完全是 "automatic" 这是我采用的一种方法,至少可以使 Try-Catch 块中的日志记录更容易。
我首先创建了异常的扩展 class:
Imports Elmah
Imports System
Imports System.Web
Imports System.Runtime.CompilerServices
Public Module ElmahExtension
<Extension()>
Public Sub LogToElmah(ex As Exception)
If HttpContext.Current Is Nothing Then
ErrorLog.GetDefault(Nothing).Log(New [Error](ex))
Dim req = New HttpRequest(String.Empty, "https://YOURWEBSITE", Nothing)
Dim res = New HttpResponse(Nothing)
Else
ErrorSignal.FromCurrentContext().Raise(ex)
ErrorLog.GetDefault(HttpContext.Current).Log(New [Error](ex))
End If
End Sub
End Module
要使用它,您可以这样做:
Try
YOUR CODE HERE
Catch
ex.LogToElmah()
End Try
这会将异常对象传递给 ELMAH 并记录错误。
所以不是很自动,但更容易。特别是,如果您使用 ReSharper 之类的工具来创建包含 "ex.LogToELMAH" 的代码快捷方式。