Skip to content

feat: Microsoft.Extensions.Logging integration no longer initializes the SDK - #5595

Draft
jamescrosswell wants to merge 2 commits into
feat/no-init-from-logging-log4net-5245from
feat/no-init-from-logging-mel-5245
Draft

jamescrosswell wants to merge 2 commits into
feat/no-init-from-logging-log4net-5245from
feat/no-init-from-logging-mel-5245

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Sep 17, 2026

Copy link
Copy Markdown
Collaborator

The Microsoft.Extensions.Logging portion of #5245, stacked on #5592 (log4net) and following the same design. AddSentry now only wires up the logger providers; Sentry has to be initialized separately via SentrySdk.Init, UseSentry, etc.

This is the last of the four logging integrations, so it closes the issue.

Closes #5245

Changelog Entry

  • The Microsoft.Extensions.Logging integration no longer initializes the SDK. Sentry must now be initialized separately from the logging integration (using SentrySdk.Init or UseSentry) - #5595
  • Blazor WebAssembly's logger now respects the MinimumEventLevel, MinimumBreadcrumbLevel, log entry filters and ConfigureScope callbacks set in UseSentry - #5595

Breaking changes

  • SentryLoggingOptions no longer derives from SentryOptions, matching the Serilog and NLog options. It carries only MinimumBreadcrumbLevel, MinimumEventLevel and log entry filters, so builder.Logging.AddSentry(o => o.Dsn = "…") now fails to compile instead of silently doing nothing. Core SDK settings go on the options used to initialize Sentry.
  • SentryLoggingOptions.ConfigureScope is removed. Call SentrySdk.ConfigureScope after initializing Sentry.
  • ILoggingBuilder.AddSentry(string dsn) is removed.
  • ILoggerFactory.AddSentry(…) no longer initializes Sentry, replaces the current hub, or assigns a MelDiagnosticLogger as the SDK's DiagnosticLogger.
  • InitializeSdk is removed, from code and from configuration binding.
  • SentryAspNetCoreOptions, SentryMauiOptions and SentryBlazorOptions now derive from a new abstract SentryHostOptions : SentryOptions. They still have MinimumBreadcrumbLevel, MinimumEventLevel, ConfigureScope and AddLogEntryFilter, and the same keys still bind from the Sentry configuration section, so existing UseSentry callbacks and appsettings.json files keep working. Code that treats them as a SentryLoggingOptions no longer compiles.
  • ServiceCollectionExtensions.AddSentry<TOptions> now requires TOptions : SentryHostOptions.
  • ConfigureScope callbacks on the framework options now run when Sentry is initialized, rather than when the Sentry logger provider is first created.

Before:

var builder = Host.CreateApplicationBuilder();
builder.Logging.AddSentry("https://key@sentry.io/1");

After:

var builder = Host.CreateApplicationBuilder();

using var sentry = SentrySdk.Init(o => o.Dsn = "https://key@sentry.io/1");

builder.Logging.AddSentry();

Fixes

  • Blazor WebAssembly's logger ignored the logging settings in UseSentry. Blazor registered the plain MEL logger provider, which dependency injection built from a separate, default IOptions<SentryLoggingOptions> rather than the SentryBlazorOptions configured in UseSentry. MinimumEventLevel, MinimumBreadcrumbLevel, log entry filters and ConfigureScope were all silently ignored by the logger; SDK initialization itself was unaffected. The same bug exists on main.
  • Structured logs from plain MEL took default attributes from the wrong options. This came from the first commit on this branch: sentry.environment, sentry.release and server.address were read from SentryLoggingOptions, which the SDK was no longer initialized with. The structured logger now reads them from the hub.

Notes for review

  • Why SentryHostOptions. SentryLoggingOptions was doing two jobs: configuring the MEL logger, and acting as the base class for integrations that initialize the SDK. Splitting them is what lets SentryLoggingOptions go standalone. The host options pass the log levels and filters through to an inner SentryLoggingOptions instance (the same object, not a copy), and that is what their logger providers receive.

  • Why abstract. It's the natural options type for a generic-host init path (Add a non-logging way to initialise Sentry in generic host apps #5572). Making it concrete later is additive; the reverse would be breaking. It lives in Sentry.Extensions.Logging because that's the one package ASP.NET Core, MAUI and Blazor all reference. Where it ultimately belongs is the packaging question Add a non-logging way to initialise Sentry in generic host apps #5572 raises.

  • ConfigureScope timing. For MAUI and Blazor, the only thing that applied these callbacks used to be the MEL logger provider's constructor, gated on hub.IsEnabled when the provider was built. They're now applied right after init: in AddSentry<TOptions>'s hub factory (ASP.NET Core, Blazor) and in SentryMauiInitializer (MAUI). ASP.NET Core still also applies them per request in SentryMiddleware, and gRPC in its interceptor.

  • InitializeSdk. MAUI initializes in SentryMauiInitializer, so it calls an internal non-initializing overload of AddSentry<TOptions> instead of setting a flag. Tests that set InitializeSdk = false to avoid initializing now use DisableSdkDsnValue. UseSentry_OptionsNotInitializeSdk_DisabledSdk tested the flag itself and is deleted; UseSentry_DisableDsn_DisabledSdk still covers a disabled SDK.

  • Blazor registrations. UseSentry now delegates to an internal ILoggingBuilder extension so it can be unit tested (WebAssemblyHostBuilder needs a browser runtime). The providers are registered by factory so they keep their existing types, and with them the existing provider alias and filter configuration. Configuration binding moved to a small SentryHostOptionsSetup<TOptions> in Sentry.Extensions.Logging, which has the configuration-binding source generator enabled, since Blazor WASM is trimmed.

  • New tests.

    • The DI init path runs ConfigureScope callbacks, and the non-initializing path doesn't.
    • MAUI ConfigureScope data reaches events. Nothing tested that before.
    • The Blazor logger respects MinimumEventLevel.

    Each test was checked to fail with its fix reverted.

  • The ApplyDefaultTags tests only used SentryLoggingOptions as a vehicle for a core SentryOptions method; they moved to SentryOptionsTests.

  • The structured-logger tests now give their mocked hub options through SentryOptionsForTestingOnly and reset it afterwards. The MEL provider test previously passed only because another test class happened to leave it set.

  • builder.Logging.AddSentry(dsn) was the only way to initialize Sentry in a generic-host app, so samples/Sentry.Samples.GenericHost now calls SentrySdk.Init directly. Add a non-logging way to initialise Sentry in generic host apps #5572 tracks the replacement and should land before this ships.

  • ApiApprovalTests.Run.Net4_8 can't regenerate on macOS. It was byte-identical to the other snapshots before this change, so it's a copy of the regenerated one.

🤖 Generated with Claude Code

…the SDK

Completes the logging-integration part of #5245. The MEL integration now only
wires up the logger providers; Sentry has to be initialized separately.

Unlike Serilog, NLog and log4net, SentryLoggingOptions keeps deriving from
SentryOptions, because SentryAspNetCoreOptions, SentryMauiOptions and
SentryBlazorOptions derive from it and those integrations do initialize the SDK.
InitializeSdk therefore stays as internal plumbing, now defaulting to false and
opted into by the framework integrations that own it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 18, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 95.94595% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 74.65%. Comparing base (6438db5) to head (d318a86).

Files with missing lines Patch % Lines
...or.WebAssembly/WebAssemblyHostBuilderExtensions.cs 86.66% 2 Missing ⚠️
...entry.Extensions.Logging/SentryStructuredLogger.cs 75.00% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@                            Coverage Diff                             @@
##           feat/no-init-from-logging-log4net-5245    #5595      +/-   ##
==========================================================================
+ Coverage                                   74.56%   74.65%   +0.09%     
==========================================================================
  Files                                         514      517       +3     
  Lines                                       18728    18743      +15     
  Branches                                     3641     3637       -4     
==========================================================================
+ Hits                                        13964    13993      +29     
+ Misses                                       3891     3874      -17     
- Partials                                      873      876       +3     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

… framework options

SentryLoggingOptions no longer derives from SentryOptions, matching the Serilog
and NLog options: it carries only the log levels and entry filters.
SentryAspNetCoreOptions, SentryMauiOptions and SentryBlazorOptions now derive from
a new abstract SentryHostOptions, which keeps MinimumEventLevel,
MinimumBreadcrumbLevel, ConfigureScope and AddLogEntryFilter by passing them
through to an inner SentryLoggingOptions, so existing UseSentry callbacks and
configuration keys keep working.

InitializeSdk is removed. Integrations that initialise through DI call
AddSentry<TOptions>; MAUI, which initialises in SentryMauiInitializer, uses an
internal non-initialising overload. ConfigureScope callbacks are applied right
after the SDK is initialised instead of when the MEL logger provider is built.

Also fixes Blazor WebAssembly's logger ignoring the logging settings from
UseSentry (it was built from a separate, default IOptions<SentryLoggingOptions>),
and structured logs from plain MEL taking default attributes from options the
SDK was not initialised with.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant