如何在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 && exception.GetType().FullName == 'Microsoft.EntityFrameworkCore.DbUpdateException' && exception.InnerException != null && exception.InnerException.GetType().FullName == 'MySqlConnector.MySqlException' && exception.InnerException.Number == 1062" action="Ignore" /> <!-- 可选:过滤所有来自控制器的Error级别异常日志 --> <when condition="starts-with(name, 'YourNamespace.Controllers') && 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
相关产品推荐
相关产品推荐

