在将ASP.NET MVC 5应用程序部署到Azure App Service插槽时,我遇到了捕获未捕获异常的困难。当发生未捕获的异常时,应用程序正确地返回500和标准“错误。处理请求时出错”Error.cshtml页面,但从未在我的任何日志中记录任何异常提及。
当前设置:
<customErrors />
,但它们在本地和远程显示为关闭,如预期和期望Application_Error
添加Global.asax
覆盖(见下文)ExceptionLoggingFilter
(见下文)并在我的FilterConfig.cs
pipepline中注册为第一项Global.asax中的Application_Error覆盖:
protected void Application_Error(Object sender, EventArgs e)
{
Trace.TraceError("Uncaught exception bubbled up. Details: {0}", e);
Logger log = LogManager.GetCurrentClassLogger();
Exception ex = Server.GetLastError();
log.Fatal(ex, "Uncaught exception bubbled up to MVC root.");
}
在GlobalFilters中注册的Customer ExceptionLoggingFilter:
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
public void OnException(ExceptionContext filterContext)
{
var ex = filterContext.Exception;
var request = filterContext.HttpContext.Request;
Logger.Fatal(ex, "Uncaught exception bubbled up to MVC root.");
}
FilterConfig.cs:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ExceptionLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
NLog.config:
...
<targets async="true">
<target xsi:type="File" name="f" fileName="${basedir}/logs/${shortdate}.log" layout="${longdate} ${uppercase:${level}} ${message} ${exception:format=tostring}" />
<target xsi:type="Trace" name="trace" layout="${logger} ${message} ${exception:format=tostring}" />
<!-- another target for sending data to Slack here... -->
</targets>
...
<rules>
<logger name="*" minlevel="Debug" writeTo="f" />
<logger name="*" minlevel="Trace" writeTo="trace" />
</rules>
...
我尝试了什么:
我创建了一个故意触发未捕获异常(var neverResult = Convert.ToInt32("a");
)的操作,当我导航到该页面时,我得到了自定义错误页面。在Azure上的生产中实现<customErrors mode="Off" />
做了我期望的事情:我知道在导航到该示例操作时看到完整的错误消息和堆栈跟踪但是我没有进行任何记录,而不是来自NLog,跟踪,观看流媒体日志,nada。
我已经尝试添加额外的处理程序和过滤器来记录错误,如上所述,但仍然没有,尽管我通过远程调试知道代码全部在这些额外的处理程序中运行。本地一切都记录得很好。
帮助!
我在这里有点不知所措,即使在下一步看。不确定我是否需要查看Azure设置,ASP.NET如何处理事物,或者NLog是否关闭(即使它记录其他一切正常)。任何方向都非常感谢。
更新:添加了实际过滤器配置和NLog配置。
答案 0 :(得分:2)
我实际上已经尝试使用您的配置并发现了问题。
如果使用Logger.Fatal,则由于某种原因,Trace消息将以详细级别写入。更改日志记录筛选器以使用错误功能:
Logger.Error(ex, "Uncaught exception bubbled up to MVC root.");
此外,异常过滤器从头到尾运行,因此在您的情况下,HandleErrorAttribute首先运行。然而,它并不意味着您的过滤器不会运行(ASP.NET Core在这方面有点不同)。
NLog的致命功能调用Trace类的Fail function,它应该用于在Windows环境中向用户显示消息框。由于某些原因,在IIS上的详细级别。
TL; DR 请勿使用Fatal()
,请使用Error()
。