I am using Serilog to log information about an asp.net core 2.1
application hosted on IIS. When exceptions occur, I am informed by email. The thing is, some exceptions happen without hurting the application at all and I don't want to be noticed each time it happens.
Is there a way in Serilog to exclude a specific exception type from being logged?
EDIT :
Here is how I configured Serilog in my Program.cs :
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 = "[email protected]", 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();
}
}
EDIT 2:
@reza baiat, @GoldenAge & @Alessandro Di Cicco: Of course your answers would allow me to handle exceptions, but just the ones occurring outside Serilog's logger. Serilog is a logging library that replaces Microsoft's default one and enables me to omit all the Try/Catch inside the rest of my code as it will log them all in (in my case) a log file and an SQL table. The thing I'm trying to do is to tell Serilog to not log, for example, ObjectDisposedException
exceptions that happens inside the critical code. I guess the Try/Catch was confusing in my code so I'll drop it from my example as it is not relevant. Serilog will catch any exception thrown once the application is built and run. What I was thinking was maybe an additional Serilog config line like this :
.Filter.ByExcluding(ObjectDisposedException)
or something like that. Is it possible?
Thank you
Adding a filter when you declare your LoggerConfiguration should work just fine:
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
...
.Filter
.ByExcluding(logEvent =>
logEvent.Exception != null &&
logEvent.Exception.GetType() == typeof(OperationCanceledException))
...
.CreateLogger();
EDIT
Let me clarify that I was mostly thinking about the production code where I still stand on what I wrote before that every unhandled exception should be logged by the logger to be able to catch some edge cases that normally you would never predict. If you disagree please write down a comment so we can discuss it. For other environments e.g localhost you can use the Grzegorz Smulko answer
ANSWER:
Is there a way in Serilog to exclude a specific exception type from being logged?
I would just create an empty catch for that specific type of exception and do just nothing inside the body e.g.
try
{
// invoke some function/s
}
catch (BlahException)
{
// do nothing
}
catch (Exception e)
{
Log.Fatal(ex, "Host terminated unexpectedly");
// do something
}
finally
{
Log.CloseAndFlush();
}
If you want to ignore more exceptions I would create some extra function which checks if you want to log this type of error or not.
// 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;
}
}
then inside the catch block, you can pass the exception code to this method. e.g.
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");
}
I think every unhandled exception should be logged by logger because this is its main responsibility. I can't see any advantage to ignore logging unhandled exception and there shouldn't be such a setting, this is just too scary! If you know that exception can occur in a given place, then you should create the try and catch blocks to catch as many expected exceptions as possible. Then you can make a decision if you want to ignore some specific exception or no in the catch block.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With