Skip to content

Duplicate invocations of Sentry SDK initialization conflict and fail silently #832

@aleksihakli

Description

@aleksihakli

Environment

How do you use Sentry?

Sentry SaaS (sentry.io)

Which SDK and version?

.NET 5 and Sentry SDK version 3.0.6

Steps to Reproduce

Use both

  • AddSentry in ConfigureLogging
  • AND UseSentry in ConfigureWebHostDefaults.

Only configure options for the later one (see below).

Expected Result

Later invocation either

  • reconfigures flags and does not conflict with earlier invocation
  • OR raises an exception because the SDK is already configured.

Reconfiguration or duplicate SDK configuration should IMO either always produce an error on misconfiguration or correctly reconfigure the options, but never fail silently.

Actual Result

The first invocation sets the SDK options and the options in the second invocation are ignored. Sentry does not e.g. enable debugging or performance tracing mode if options clash in the correct fashion.

EDIT: the logging docs do mention that the SDK should only be initialised once. However, the ordering and semantics of initialisations should perhaps be made clearer in the docs?

https://docs.sentry.io/platforms/dotnet/guides/extensions-logging/#options-and-initialization


The following code DOES NOT work:

using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;

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

        public static IHostBuilder CreateHostBuilder(string[] args) =>
            Host.CreateDefaultBuilder(args)
                .ConfigureAppConfiguration((hostingContext, config) =>
                {
                    config.AddEnvironmentVariables();
                })
                .ConfigureLogging((c, l) =>
                {
                    l.AddConfiguration(c.Configuration);
                    l.AddSentry();
                })
                .ConfigureWebHostDefaults(webBuilder =>
                {
                    webBuilder.UseSentry(o =>
                    {
                        o.Debug = true;
                        o.TracesSampleRate = 1.0;
                    });
                    webBuilder.UseStartup<Startup>();
                });
    }
}

image

The following code DOES work:

.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseSentry(o =>
    {
        o.Debug = true;
        o.TracesSampleRate = 1.0;
    });
    webBuilder.UseStartup<Startup>();
})
.ConfigureLogging((c, l) =>
{
    l.AddConfiguration(c.Configuration);
    l.AddSentry();
})

The following code also DOES work and produces the same end result:

.ConfigureLogging((c, l) =>
{
    l.AddConfiguration(c.Configuration);
    l.AddSentry(o =>
    {
        o.Debug = true;
        o.TracesSampleRate = 1.0;
    });
})
.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseSentry();
    webBuilder.UseStartup<Startup>();
})

Configuring options in all invocations DOES work correctly but is error prone as forgetting to add options in one place and remembering the strict invocation ordering produces easy-to-make and hard-to-debug bugs:

.ConfigureLogging((c, l) =>
{
    l.AddConfiguration(c.Configuration);
    l.AddSentry(o =>
    {
        o.Debug = true;
        o.TracesSampleRate = 0.05;
    });
})
.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseSentry(o =>
    {
        o.Debug = true;
        o.TracesSampleRate = 0.05;
    });
    webBuilder.UseStartup<Startup>();
})

I'm assuming that the correct way to initialize the SDK with both error tracing and logging would be something like the following to avoid duplicate initializations? There's not a whole lot of documentation on this.

.ConfigureWebHostDefaults(webBuilder =>
{
    webBuilder.UseStartup<Startup>();
    // Initializing Sentry for error and performance tracing
    // https://docs.sentry.io/platforms/dotnet/guides/aspnetcore/
    webBuilder.UseSentry(o =>
    {
        o.Debug = true;
        o.TracesSampleRate = 1.0;
    });
})
.ConfigureLogging((c, l) =>
{
    l.AddConfiguration(c.Configuration);
    // Adding Sentry integration to Microsoft.Extensions.Logging for Entity Framework integration
    // Note that the SDK only needs to be initialized once
    // https://docs.sentry.io/platforms/dotnet/guides/extensions-logging/#options-and-initialization
    l.AddSentry(o => o.InitializeSdk = false);
});

image

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions