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!