Search code examples
c#serilogsentry

How to make Sentry Ignore some Exceptions?


I'm using serilog to log exceptions to Sentry. I want to ignore some exceptions and not log them to Sentry. I would like to read those exceptions from the app settings file if possible. I tried this, but it did not work. I'm trying here to ignore the NotImplementedException exception.

Appsettings.json

{
  "Logfile": {
    "Name": "/logs/log-Service-.txt"
  },
  "Sentry": {
    "Dsn": "https://sentry.dns"
  },
  "Serilog": {
    "IgnoreList": {
      "ExceptionTypes": [
        "NotImplementedException"
      ]
    }
  },
  "ConnectionStrings": {
    "DefaultConnection": "myconnection"
  }
}

HostBuilderExtensions.cs

    public static class HostBuilderExtensions
    {
        public static IHostBuilder UseCustomSerilog(this IHostBuilder builder, IConfiguration configuration)
        {
            var ignoreList = configuration.GetSection("Serilog:IgnoreList:ExceptionTypes")
            .Get<string[]>() ?? Array.Empty<string>();

            return builder.UseSerilog((context, config) =>
            {
                config.MinimumLevel.Verbose()
                    .MinimumLevel.Override("Microsoft", LogEventLevel.Fatal)
                    .WriteTo.Udp(
                        remoteAddress: configuration.GetSection("Logstash")["Host"] ?? throw new InvalidOperationException(),
                        remotePort: int.Parse(configuration.GetSection("Logstash")["Port"] ?? throw new InvalidOperationException()),
                        family: AddressFamily.InterNetwork, formatter: new CompactJsonFormatter()
                    )
                    .Enrich.WithProperty("type", configuration.GetSection("Logstash")["Type"] ?? throw new InvalidOperationException())
                    .WriteTo.File(
                        new CompactJsonFormatter(),
                        configuration.GetSection("Logfile")["Name"] ?? throw new InvalidOperationException(),
                        rollingInterval: RollingInterval.Day
                    )
                    .WriteTo.Console()
                    .WriteTo.Sentry(o =>
                    {
                        o.Dsn = configuration.GetSection("Sentry")["Dns"];
                        o.MinimumEventLevel = LogEventLevel.Error;
                        o.MinimumBreadcrumbLevel = LogEventLevel.Error;
                        o.SetBeforeSend((sentryEvent, _) =>
                        {
(exceptionsToIgnore.Contains(sentryEvent.Exception?.GetType().FullName))
                            if (ignoreList.Contains(sentryEvent.Exception?.GetType().FullName))
                            {
                                Console.WriteLine("Ignored");
                                return null;
                            }

                            return sentryEvent;
                        });
                        //o.AddExceptionFilterForType<NotImplementedException>();
                    })
                    .Enrich.FromLogContext();
            });
        }
    }

Program.cs

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.WebHost.UseSentry();

builder.Host.UseCustomSerilog(builder.Configuration);

var app = builder.Build();

app.UseSwagger();

app.UseSwaggerUI(c =>
{
    string swaggerJsonBasePath = string.IsNullOrWhiteSpace(c.RoutePrefix) ? "." : "..";
    c.SwaggerEndpoint($"{swaggerJsonBasePath}/swagger/v1/swagger.json", "Bet");
});

app.UseHttpsRedirection();

app.UseAuthorization();

app.UseMiddleware<GlobalExceptionHandling>();

app.UseMiddleware<GlobalLoggerHandling>();

app.UseMiddleware<ValidationMiddleware>();

app.MapControllers();

app.Run();

It still logs the exception.

Thanks


Solution

  • The Sentry codebase has an example of how ignore exceptions of a particular type

    class ExceptionTypeFilter<TException> : IExceptionFilter where TException : Exception
    {
        private readonly Type _filteredType = typeof(TException);
        public bool Filter(Exception ex) => _filteredType.IsInstanceOfType(ex);
    }
    

    You could wire that up when configuring Sentry with something like:

    SentrySdk.Init(options => {
        // All your other config here...
        options.AddExceptionFilter(new ExceptionTypeFilter<NotImplementedException>());
    });
    

    You can obviously modify that to do fancier stuff and the SetBeforeSend callback event that you've found is a good pick to filter events more generally (not just events for exceptions).

    In situations where you can't run the code in a debugger (which hopefully are rare), Logging might help. You could/should also try to test your code with unit tests before deploying it. Ideally though, you're going to want to be able to run stuff in a debugger to make sense of things.