关于c#:ELMAH日志处理异常

ELMAH Log handled exceptions

我正在使用ELMAH来尝试记录处理过的异常(在try catch中发生的异常)。 但是我无法让ELMAH记录try catch中发生的任何异常。

这是我的行动:

1
2
3
4
5
6
7
8
9
10
11
    [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/和这里:如何让ELMAH使用ASP.NET MVC [HandleError]属性?

但我的ElmahExceptionLogger只会因未处理的异常而被触发。

这是我的ElmahExceptionLogger

1
2
3
4
5
6
7
public class ElmahExceptionLogger : IExceptionFilter {
    public void OnException(ExceptionContext filterContext) {
        if (filterContext.ExceptionHandled) {
            ErrorSignal.FromCurrentContext().Raise(filterContext.Exception);
        }
    }
}

这是我的global.asax

1
2
3
4
5
6
7
8
9
10
  public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            AreaRegistration.RegisterAllAreas();
            FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
            RouteConfig.RegisterRoutes(RouteTable.Routes);
            BundleConfig.RegisterBundles(BundleTable.Bundles);        
        }      
    }

这是我的寄存器全局过滤方法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 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块中。

1
2
3
4
5
6
catch (Exception e)
{
    ModelState.AddModelError("","Something unexpected happened, please try again.");
    ErrorSignal.FromCurrentContext().Raise(e);
    return View(model);
}

如果你发现自己做了很多,那么我建议你关掉使用Elmah。 Elmah不是一般的日志记录框架,它适用于未处理的错误。最好使用诸如Serilog或Nlog之类的日志系统,然后将这些日志记录到Seq等专用系统。


虽然不完全是"自动",但我采用的方法是至少在Try-Catch块中使记录更容易。

我首先创建了Exception类的扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
    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

要使用它,您可以这样做:

1
2
3
4
5
6
7
   Try

      YOUR CODE HERE

  Catch
      ex.LogToElmah()
  End Try

这会将异常对象传递给ELMAH并记录错误。

所以不是很自动,但更容易。特别是,如果您使用ReSharper之类的东西来创建包含"ex.LogToELMAH"的代码快捷方式。