ASP.NET Azure 上的 MVC 5 应用程序不会记录异常
ASP.NET MVC 5 application on Azure won't log exceptions
将我的 ASP.NET MVC 5 应用程序部署到 Azure 应用服务插槽时,我无法记录未捕获的异常。当发生未捕获的异常时,该应用程序正确地 returns 500 和标准 "Error. An error occurred while processing your request" Error.cshtml 页面,但从未在我的任何日志中记录任何提及异常。
当前设置:
- Azure 设置:
- 应用程序日志记录:打开,在信息级别记录到文件系统和存储 blob
- 详细错误消息:开启
- 请求跟踪失败:开启
- 应用程序设置:
- 使用 NLog 写入文件和 Trace 目标,这在其他地方和捕获的异常上都运行良好
- 没有在我的 Web.configs 中明确设置
<customErrors />
,但它们在本地和远程显示为关闭,正如预期和期望的那样
- 向
Global.asax
添加了 Application_Error
覆盖(见下文)
- 添加了自定义
ExceptionLoggingFilter
(见下文)并将其作为第一项注册到我的 FilterConfig.cs
管道中
Application_Error 在 Global.asax 中覆盖:
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 中注册的客户 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 配置。
我实际上用你的配置试过了,发现了问题。
如果您使用 Logger.Fatal,Trace 消息会出于某种原因以详细级别写入。更改您的日志过滤器以使用错误函数:
Logger.Error(ex, "Uncaught exception bubbled up to MVC root.");
此外,异常过滤器 运行 last-to-first,因此在您的情况下,首先是 HandleErrorAttribute 运行s。然而,这并不意味着您的过滤器不会 运行(ASP.NET 核心在这方面有点不同)。
NLog 的 Fatal 函数调用 Trace class 的 Fail function,它应该用于在 Windows 环境中向用户显示消息框。出于某种原因,在 IIS 上处于详细级别。
TL;DR 不要使用 Fatal()
,使用 Error()
.
将我的 ASP.NET MVC 5 应用程序部署到 Azure 应用服务插槽时,我无法记录未捕获的异常。当发生未捕获的异常时,该应用程序正确地 returns 500 和标准 "Error. An error occurred while processing your request" Error.cshtml 页面,但从未在我的任何日志中记录任何提及异常。
当前设置:
- Azure 设置:
- 应用程序日志记录:打开,在信息级别记录到文件系统和存储 blob
- 详细错误消息:开启
- 请求跟踪失败:开启
- 应用程序设置:
- 使用 NLog 写入文件和 Trace 目标,这在其他地方和捕获的异常上都运行良好
- 没有在我的 Web.configs 中明确设置
<customErrors />
,但它们在本地和远程显示为关闭,正如预期和期望的那样 - 向
Global.asax
添加了Application_Error
覆盖(见下文) - 添加了自定义
ExceptionLoggingFilter
(见下文)并将其作为第一项注册到我的FilterConfig.cs
管道中
Application_Error 在 Global.asax 中覆盖:
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 中注册的客户 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 配置。
我实际上用你的配置试过了,发现了问题。
如果您使用 Logger.Fatal,Trace 消息会出于某种原因以详细级别写入。更改您的日志过滤器以使用错误函数:
Logger.Error(ex, "Uncaught exception bubbled up to MVC root.");
此外,异常过滤器 运行 last-to-first,因此在您的情况下,首先是 HandleErrorAttribute 运行s。然而,这并不意味着您的过滤器不会 运行(ASP.NET 核心在这方面有点不同)。
NLog 的 Fatal 函数调用 Trace class 的 Fail function,它应该用于在 Windows 环境中向用户显示消息框。出于某种原因,在 IIS 上处于详细级别。
TL;DR 不要使用 Fatal()
,使用 Error()
.