如何从 Serilog 中排除特定的异常类型?
Posted
技术标签:
【中文标题】如何从 Serilog 中排除特定的异常类型?【英文标题】:How to exclude specific exception types from Serilog? 【发布时间】:2019-02-04 16:02:08 【问题描述】:我正在使用 Serilog 记录有关托管在 IIS 上的 asp.net core 2.1
应用程序的信息。发生异常时,我会通过电子邮件收到通知。问题是,一些例外情况的发生根本不会损害应用程序,我不想在每次发生时都被注意到。
Serilog 中是否有办法排除特定异常类型的记录?
编辑:
这是我在 Program.cs 中配置 Serilog 的方式:
using System;
using System.Data;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Serilog;
using Serilog.Sinks.MSSqlServer;
namespace Some_App
public class Program
public static void Main(string[] args)
var configuration = new ConfigurationBuilder()
.AddJsonFile(Environment.CurrentDirectory + "/appsettings.json")
.Build();
var columnOptions = new ColumnOptions
AdditionalDataColumns = new System.Collections.ObjectModel.Collection<DataColumn>
new DataColumn DataType = typeof (string), ColumnName = "email", DefaultValue = "myemail@myemail.com", MaxLength = 4000,
new DataColumn DataType = typeof (string), ColumnName = "subject", DefaultValue = "Application error", MaxLength = 4000,
;
columnOptions.Store.Remove(StandardColumn.Level);
columnOptions.Store.Remove(StandardColumn.LogEvent);
columnOptions.Store.Remove(StandardColumn.Message);
columnOptions.Store.Remove(StandardColumn.MessageTemplate);
columnOptions.Store.Remove(StandardColumn.Properties);
columnOptions.Store.Remove(StandardColumn.TimeStamp);
columnOptions.Exception.ColumnName = "message";
columnOptions.Id.ColumnName = "id";
columnOptions.DisableTriggers = true;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", Serilog.Events.LogEventLevel.Information)
.Enrich.FromLogContext()
.Filter.ByExcluding(ObjectDisposedException) //What is the right way to tell Serilog to ignore this type of exception?
.WriteTo.RollingFile("logs\\log-Hour.txt", retainedFileCountLimit: 168)
.WriteTo.MSSqlServer(
connectionString: configuration.GetConnectionString("DefaultConnection"),
tableName: "emailtosend",
columnOptions: columnOptions,
restrictedToMinimumLevel: Serilog.Events.LogEventLevel.Error
)
.CreateLogger();
CreateWebHostBuilder(args).Build().Run();
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>()
.UseSerilog();
编辑 2:
@reza baiat、@GoldenAge 和@Alessandro Di Cicco:当然,您的回答可以让我处理异常,但仅限于在 Serilog 记录器之外发生的异常。 Serilog 是一个日志库,它取代了 Microsoft 的默认库,使我能够省略其余代码中的所有 Try/Catch,因为它将它们全部记录在(在我的情况下)一个日志文件和一个 SQL 表中。我正在尝试做的事情是告诉 Serilog 不要记录,例如,在关键代码中发生的ObjectDisposedException
异常。我猜 Try/Catch 在我的代码中令人困惑,所以我将从我的示例中删除它,因为它不相关。一旦应用程序构建并运行,Serilog 将捕获任何引发的异常。我在想的可能是一个额外的 Serilog 配置行,如下所示:
.Filter.ByExcluding(ObjectDisposedException)
或类似的东西。有可能吗?
谢谢
【问题讨论】:
您能否详细描述一下您的 Serilog 配置(例如接收器、asp.net 核心的全局过滤器) 答案不应该被接受。它仍然没有回答您在 Edit2 中澄清的问题 您的.Filter.ByExcluding(ObjectDisposedException)
方法对我有用。事实上,它解决了我一直遇到的一个问题。我有异常处理中间件,它以某种格式记录某些类型的异常,但是当我重新抛出异常时,Serilog 会以标准格式再次记录它们。我需要重新抛出它们以保持应用程序在异常时的正确行为,但是将这些异常记录两次很烦人。所以谢谢。你的问题实际上已经回答了自己......你已经解决了我的问题!
【参考方案1】:
在声明 LoggerConfiguration 时添加过滤器应该可以正常工作:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
...
.Filter
.ByExcluding(logEvent =>
logEvent.Exception != null &&
logEvent.Exception.GetType() == typeof(OperationCanceledException))
...
.CreateLogger();
【讨论】:
【参考方案2】:编辑
让我澄清一下,我主要考虑的是生产代码,我仍然坚持我之前编写的内容,记录器应该记录每个未处理的异常,以便能够捕获一些通常你永远无法预测的边缘情况。如果您不同意,请写下评论,以便我们讨论。对于其他环境,例如 localhost,您可以使用 Grzegorz Smulko answer
回答:
Serilog 中有没有一种方法可以排除特定的异常类型 被记录了吗?
我只会为该特定类型的异常创建一个空捕获,并且在主体内什么也不做,例如
try
// invoke some function/s
catch (BlahException)
// do nothing
catch (Exception e)
Log.Fatal(ex, "Host terminated unexpectedly");
// do something
finally
Log.CloseAndFlush();
如果您想忽略更多异常,我会创建一些额外的函数来检查您是否要记录此类错误。
// list of error codes:
// https://docs.microsoft.com/en-gb/windows/desktop/Debug/system-error-codes
public static bool IgnoreError(int errorCode)
switch (errorCode)
case 16389:
return true;
case 16387:
return true;
default:
return false;
然后在 catch 块中,您可以将异常代码传递给该方法。例如
try
throw new ArgumentNullException("value");
catch (Exception e)
// Using an AND operation will retrieve the error code from the HRESULT:
if (IgnoreError(e.HResult & 0xFFFF))
return;
Log.Fatal(e, "message");
我认为每个未处理的异常都应该由记录器记录,因为这是它的主要职责。我看不出忽略记录未处理的异常有什么好处,也不应该有这样的设置,这太可怕了!如果您知道在给定位置可能发生异常,那么您应该创建 try 和 catch 块以捕获尽可能多的预期异常。然后,您可以决定是否要忽略 catch 块中的某些特定异常。
【讨论】:
我想我会这样做。谢谢。【参考方案3】:下面的代码可以帮助你
catch (Exception ex)
if (ex.GetType() != typeof(ExceptionTypeToExclude) )
Log.Fatal(ex, "Host terminated unexpectedly");
return;
【讨论】:
以上是关于如何从 Serilog 中排除特定的异常类型?的主要内容,如果未能解决你的问题,请参考以下文章