Asp.net Core 如何记录 System.AccessViolationException

问题描述

我们最近发现我们的应用程序在利用某些第三方库进行一些非托管内存访问时抛出 System.AccessViolationException。 我当然会尝试与第三方合作以从他们那里获得修复,但这篇文章不是为此而写的 :)

我希望对如何将这些异常信息真正写入我的日志有一些见解。我们正在运行 Asp.net Core 5。 我们仅通过启用 stdoutLogEnabled :https://docs.microsoft.com/en-us/aspnet/core/test/troubleshoot-azure-iis?view=aspnetcore-5.0#aspnet-core-module-stdout-log-iis 才发现此错误。但是,不建议将其用于生产环境。 所以我目前的问题是,我怎样才能真正捕获相同的日志消息 stdoutLogEnabled=true 能够通过使用其他一些日志记录提供程序(即 Log4Net)提供给我们。

我的应用设置中有以下内容

"Logging": {
    "LogLevel": {
      "Default": "Trace",}
  },

然而,当我运行一些不安全的代码来模拟 System.AccessViolationException 时,我看不到是否登录到我的任何 log4net 附加程序中。

我没有特别需要让它为 log4net 工作,这正是我们今天使用的。一般来说,我希望能够使用一些高级日志提供程序捕获此日志,以便它可能会记录服务器上本地文件以外的其他地方。

服务器上 stdoutLogEnabled 的示例日志输出

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
Repeat 2 times:
--------------------------------
   at   +.(IntPtr,System.String,Byte[],Int32,IntPtr ByRef,Int32 ByRef,System.String ByRef)
--------------------------------
   at d.(,System.IO.Stream)
   at ThirdPartyClass.Save(System.String,System.IO.Stream)
   at FirstPartyClass.CreateImage()
   at FirstPartyClass.Execute()
   at System.Threading.ThreadHelper.ThreadStart_Context(System.Object)
   at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext,System.Threading.ContextCallback,System.Object)
   at System.Threading.ThreadHelper.ThreadStart()

编辑: 添加更多信息。我确实读过这篇类似的帖子:Gracefully handling corrupted state exceptions in .NET Core 这对我的问题来说不是好兆头。不过,我的问题确实有所不同,因为我不在乎捕捉异常,我对应用程序崩溃没问题。我只是想确保当这些错误确实发生时,我们可以将此信息记录到我们选择的日志提供程序。

解决方法

如果你没有尝试过,你可以使用 ILogger 接口或 Serilog 包。您可以从以下链接找到帮助文档。

Logging in .NET Core and ASP.NET Core

Serilog

,

要获得此类未处理的异常,请确保您正在调用 UseExceptionHandler

在下面的链接中搜索“捕获并记录未处理的异常”

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling?view=aspnetcore-5.0

在启动类中,寻找函数

public void Configure

在该函数中,确保您调用了 UseExceptionHandler,如下所示,如文档中所述。

if (env.IsDevelopment())
{
    app.UseDeveloperExceptionPage();
}
else
{
    app.UseExceptionHandler("/Error");
    app.UseHsts();
}