[.NET] Sentry with Serilog what's a real advantage?

Hey folks!

I’am using the Sentry.Serilog to integrate with Serilog library, but, I’am so confused now.

Following the documentation, we can configure the Sentry Serilog sink as follows:

 public static IHostBuilder CreateHostBuilder(string[] args) =>
               Host.CreateDefaultBuilder(args)
                   .ConfigureWebHostDefaults(webBuilder =>
                   {
                       webBuilder.UseSerilog(SerilogLoggerConfiguration());
                       webBuilder.UseStartup<Startup>();
                   });

private static Action<WebHostBuilderContext, LoggerConfiguration> SerilogLoggerConfiguration()
{
    return (webHostBuilderContext, loggerConfiguration) =>
    {
        loggerConfiguration
            .Enrich.FromLogContext()
            .WriteTo.Sentry(s =>
            {
                s.MinimumBreadcrumbLevel = LogEventLevel.Debug;
                s.MinimumEventLevel = LogEventLevel.Error;
            });
    };
}

Considerating:

1- What’s is the real advantage of init integration this way, without set the Dsn property? On this way, how Serilog can WriteTo Sentry without initialize the SDK?

2- So, if we set the Dsn property or call the .UseSentry() method, the Sentry lib always catch the exceptions and send the event to server. My doubt is: How we can configure Sentry to send events to server only if we call Serilog.Logger.Error(...), for example?

An example:

Program.cs

public class Program
{
    public static void Main(string[  ] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseSerilog(SerilogLoggerConfiguration());
                webBuilder.UseStartup<Startup>();
            });

    private static Action<WebHostBuilderContext, LoggerConfiguration> SerilogLoggerConfiguration()
    {
        return (webHostBuilderContext, loggerConfiguration) =>
        {
            loggerConfiguration
                .Enrich.FromLogContext()
                .WriteTo.Sentry(s =>
                {
                    s.Dsn = new Dsn("<dsn>"); // Starts Sentry SDK
                    s.MinimumBreadcrumbLevel = LogEventLevel.Debug;
                    s.MinimumEventLevel = LogEventLevel.Error;
                });
        };
    }
}

Startup.cs

public class Startup
{
	//... Omitted for brevity...
	public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
	{
		//... Omitted for brevity...
		app.UseExceptionHandler(configure =>
		{
            // Tiny middleware to handle exceptions...
			app.Use(async (httpContext, nextMiddleware) =>
			{
				// Another error treatments...
				var exceptionDetails = httpContext.Features.Get<IExceptionHandlerFeature>();

				// Serilog call...
				Log.Logger.Error("Error from my custom middleware!", exceptionDetails?.Error);

				await nextMiddleware();
			});
		});
		//... Omitted for brevity...
	}
}

WeatherForecastController.cs

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    [HttpGet]
    public IActionResult Get()
    {
        int.Parse("sentry"); // Throws an exception

        return default;
    }
}

With this configuration, the server always receive the Exception twice, see:

The only configuration that works for me(send only error from my custom middleware), is configuring the Dsn on method WriteTo.Sentry(...) when we set a new LoggerConfiguration to property Logger of Serilog.Log static class.

Like this:

Program.cs

public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .ConfigureWebHostDefaults(webBuilder =>
            {
                Log.Logger = new LoggerConfiguration()
                  .WriteTo.Sentry(o =>
                  {
                      o.Dsn = new Sentry.Dsn("<dsn>");
                      o.MinimumEventLevel = LogEventLevel.Warning;
                      o.MinimumBreadcrumbLevel = LogEventLevel.Debug;
                  })
                  .CreateLogger();

                webBuilder.UseStartup<Startup>();
            });
}

PS.: I know about Event and Exception Processors, but in this case I need a custom middleware.

Any explanation is welcome! :grinning: