如何从 Serilog 中排除特定的异常类型?
How to exclude specific exception types from Serilog?
我正在使用 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 table。我想做的是告诉 Serilog 不要记录,例如,发生在关键代码中的 ObjectDisposedException
异常。我猜 Try/Catch 在我的代码中令人困惑,所以我将从我的示例中删除它,因为它不相关。 Serilog 将捕获应用程序构建后抛出的任何异常 运行。我在想的可能是像这样的额外 Serilog 配置行:
.Filter.ByExcluding(ObjectDisposedException)
或类似的东西。可能吗?
谢谢
以下代码可能对您有所帮助
catch (Exception ex)
{
if (ex.GetType() != typeof(ExceptionTypeToExclude) ) {
Log.Fatal(ex, "Host terminated unexpectedly");
}
return;
}
编辑
让我澄清一下,我主要考虑的是生产代码,我仍然坚持我之前写的东西,记录器应该记录每个未处理的异常,以便能够捕获一些通常你永远无法预测的边缘情况.如果您不同意,请写下评论,以便我们进行讨论。对于其他环境,例如本地主机,您可以使用
答案:
Is there a way in Serilog to exclude a specific exception type from
being logged?
我只想为特定类型的异常创建一个空捕获,并且在主体内什么也不做,例如
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 块中不。
在声明 LoggerConfiguration 时添加过滤器应该可以正常工作:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
...
.Filter
.ByExcluding(logEvent =>
logEvent.Exception != null &&
logEvent.Exception.GetType() == typeof(OperationCanceledException))
...
.CreateLogger();
我正在使用 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 table。我想做的是告诉 Serilog 不要记录,例如,发生在关键代码中的 ObjectDisposedException
异常。我猜 Try/Catch 在我的代码中令人困惑,所以我将从我的示例中删除它,因为它不相关。 Serilog 将捕获应用程序构建后抛出的任何异常 运行。我在想的可能是像这样的额外 Serilog 配置行:
.Filter.ByExcluding(ObjectDisposedException)
或类似的东西。可能吗?
谢谢
以下代码可能对您有所帮助
catch (Exception ex)
{
if (ex.GetType() != typeof(ExceptionTypeToExclude) ) {
Log.Fatal(ex, "Host terminated unexpectedly");
}
return;
}
编辑
让我澄清一下,我主要考虑的是生产代码,我仍然坚持我之前写的东西,记录器应该记录每个未处理的异常,以便能够捕获一些通常你永远无法预测的边缘情况.如果您不同意,请写下评论,以便我们进行讨论。对于其他环境,例如本地主机,您可以使用
答案:
Is there a way in Serilog to exclude a specific exception type from being logged?
我只想为特定类型的异常创建一个空捕获,并且在主体内什么也不做,例如
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 块中不。
在声明 LoggerConfiguration 时添加过滤器应该可以正常工作:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
...
.Filter
.ByExcluding(logEvent =>
logEvent.Exception != null &&
logEvent.Exception.GetType() == typeof(OperationCanceledException))
...
.CreateLogger();