You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在ASP.NET Core中用NLog排除已处理异常的日志记录

解决方案

1. 移除控制器中已处理异常的主动日志调用

检查所有catch块,若你在处理异常时主动调用了_logger.LogError(ex, ...),这会直接触发NLog记录该异常。只需删除这些日志调用,或者将级别改为LogDebug/LogInformation(如果需要保留但不纳入Error级别的正式日志)。

示例修改:

// 原代码(会记录已处理异常)
catch (DbUpdateException ex) when (ex.InnerException is MySqlException mysqlEx && mysqlEx.Number == 1062)
{
    _logger.LogError(ex, "重复输入错误"); // 这一行会触发NLog记录
    return Conflict("该记录已存在");
}

// 修改后(不记录已处理异常)
catch (DbUpdateException ex) when (ex.InnerException is MySqlException mysqlEx && mysqlEx.Number == 1062)
{
    // _logger.LogDebug(ex, "重复输入已处理"); // 可选:保留Debug级别日志用于调试
    return Conflict("该记录已存在");
}

2. 配置NLog过滤规则

在nlog.config中添加过滤条件,排除特定类型的已处理异常。比如针对MySQL重复键(错误码1062)的DbUpdateException:

<configuration>
  <nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

    <!-- 目标配置(示例) -->
    <targets>
      <target name="file" xsi:type="File" fileName="logs/${shortdate}.log"
              layout="${longdate} ${level} ${logger} ${message} ${exception:format=ToString}" />
    </targets>

    <!-- 日志规则 -->
    <rules>
      <logger name="*" minlevel="Error" writeTo="file">
        <filters>
          <!-- 过滤MySQL重复键的已处理异常 -->
          <when condition="exception != null 
                          &amp;&amp; exception.GetType().FullName == 'Microsoft.EntityFrameworkCore.DbUpdateException' 
                          &amp;&amp; exception.InnerException != null 
                          &amp;&amp; exception.InnerException.GetType().FullName == 'MySqlConnector.MySqlException' 
                          &amp;&amp; exception.InnerException.Number == 1062" 
                action="Ignore" />
          <!-- 可选:过滤所有来自控制器的Error级别异常日志 -->
          <when condition="starts-with(name, 'YourNamespace.Controllers') &amp;&amp; level == 'Error'" 
                action="Ignore" />
        </filters>
      </logger>
    </rules>
  </nlog>
</configuration>

3. 调整ASP.NET Core日志过滤级别

在appsettings.json中,针对控制器命名空间设置更低的日志级别,避免已处理异常的日志被框架捕获:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning",
      // 将控制器的日志级别设为None,禁止所有控制器的日志输出
      "YourNamespace.Controllers": "None"
    }
  }
}

4. 验证全局异常处理中间件

确保Program.cs中的全局异常处理只针对未捕获的异常,不会捕获已处理的异常:

var builder = WebApplication.CreateBuilder(args);

// 清理默认日志提供器,添加NLog
builder.Logging.ClearProviders();
builder.Logging.AddNLog("nlog.config");

builder.Services.AddControllers();
builder.Services.AddDbContext<YourDbContext>(options =>
    options.UseMySql(
        builder.Configuration.GetConnectionString("DefaultConnection"),
        new MySqlServerVersion(new Version(8, 0, 36))
    )
);

var app = builder.Build();

// 仅处理未捕获的异常(生产环境)
if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/error");
}

app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

内容的提问来源于stack exchange,提问作者Fabricio Rodriguez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 12:43:22