Skip to content

feat(serilog)!: the Sentry sink no longer initializes the SDK - #5573

Merged
jamescrosswell merged 19 commits into
version7from
feat/no-init-from-logging-5245
Sep 29, 2026
Merged

jamescrosswell merged 19 commits into
version7from
feat/no-init-from-logging-5245

Conversation

@jamescrosswell

@jamescrosswell jamescrosswell commented Sep 14, 2026 •

Copy link
Copy Markdown
Collaborator

The Serilog portion of #5245, following the design in this comment. The Sentry sink for Serilog now only configures the sink; Sentry has to be initialized separately via SentrySdk.Init, UseSentry, etc.

Part of #5245

Breaking changes

  • SentrySerilogOptions no longer derives from SentryOptions. It carries only sink settings: MinimumEventLevel, MinimumBreadcrumbLevel, FormatProvider, TextFormatter, RestrictedToMinimumLevel, LevelSwitch. Anything else (Dsn, Release, SampleRate, …) belongs on the options used to initialize Sentry.
  • SentrySerilogOptions.InitializeSdk is removed.
  • The WriteTo.Sentry(string dsn, …) overload is removed. Note that Serilog.Settings.Configuration does not fail when a configuration still supplies dsn: it filters candidate methods on the method's own parameters, so unmatched arguments are dropped silently — not even to SelfLog. The sink is attached, Sentry is never initialized, and the app reports nothing. feat(serilog): configuring a DSN on the sink now fails with a migration error #5611 stacks a tombstone overload on this branch to turn that into a loud failure.
  • ApplySerilogScopeToEvents() is renamed UseSerilog(), to match UseOpenTelemetry(). It returns void like its siblings and is now idempotent.
  • A WriteTo.Sentry(o => …) configuration that only sets sink settings still compiles, and nothing in the API can catch it. On 6.x that overload initialized the SDK itself (InitializeSdk defaulted to true), taking the DSN from SENTRY_DSN or a [Dsn] assembly attribute; now the sink is attached, Init is never called, and every event is dropped. The sink therefore warns at runtime: on the first log event at or above MinimumEventLevel, if Sentry is not initialized but a DSN can still be found, it writes one line to Serilog's SelfLog and to standard error, at most once per sink. Thanks to @ric-oliv for spotting this.
  • Events and structured logs no longer report sentry.dotnet.serilog as the SDK name. Sdk.Name identifies the integration that initialized Sentry, and the sink identifies itself through the log origin (auto.log.serilog). See Metrics and SentrySdk.Logger logs emitted during a request carry no sentry.sdk.name/sentry.sdk.version on ASP.NET Core #5497.

Before:

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sentry(o =>
    {
        o.Dsn = "...";
        o.MinimumEventLevel = LogEventLevel.Error;
    })
    .CreateLogger();

After:

using var _ = SentrySdk.Init(o =>
{
    o.Dsn = "...";
    o.UseSerilog();
});

Log.Logger = new LoggerConfiguration()
    .WriteTo.Sentry(o => o.MinimumEventLevel = LogEventLevel.Error)
    .CreateLogger();

Notes for review

  • UseSerilog() registers the processor that copies Serilog LogContext properties onto events. It has to live on the SentryOptions used for init, because it enriches every event, not only ones the sink creates. To keep that discoverable, the sink logs a one-time diagnostic warning when it's missing (only visible with Debug = true).
  • The old WriteTo.Sentry(o => …) overload initialized the SDK but never registered that processor — only the dsn parameter overload did. That's why IntegrationTests.Simple snapshots gain inventory/MyTaskId tags: the test now calls UseSerilog(), and the processor is actually running.
  • The runtime warning writes to standard error as well as SelfLog because there is no DiagnosticLogger to write to when the SDK was never initialized, and SelfLog only reaches people who already suspect a problem. It is gated on a DSN being discoverable, so an app that deliberately runs without Sentry stays quiet. The shared policy lives in Sentry.Internal.UninitializedSdkWarning; each integration supplies its own channel and message.
  • The sink no longer implements IDisposable. It never owned the hub, so Log.CloseAndFlush() no longer disposes the SDK; disposing the handle from SentrySdk.Init does that.
  • SerilogAspNetSentrySdkTestFixture was initializing the SDK twice (once via WriteTo.Sentry(ValidDsn), then again via UseSentry); it now only initializes via UseSentry.
  • ApiApprovalTests.Run.Net4_8.verified.txt can't regenerate on macOS; it was byte-identical to the DotNet10_0 snapshot before this change, so it's a copy of the regenerated one.

NLog, log4net and Microsoft.Extensions.Logging follow separately. The generic host replacement for builder.Logging.AddSentry(dsn) is tracked in #5572.

🤖 Generated with Claude Code

The Sentry sink for Serilog now only configures the sink. Sentry must be
initialized separately (SentrySdk.Init, UseSentry, etc).

- SentrySerilogOptions no longer derives from SentryOptions and only
  carries sink settings; InitializeSdk is removed
- Remove the WriteTo.Sentry(string dsn, ...) overload
- Rename ApplySerilogScopeToEvents() to UseSerilog(), make it idempotent
- The sink logs a one-time diagnostic warning when UseSerilog() was not
  called on the options used to initialize Sentry

Part of #5245

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@jamescrosswell jamescrosswell added Breaking Change Binary/Source/Behavioral Breaking Changes. Serilog labels Sep 14, 2026
@github-actions github-actions Bot added the public API Additions/modifications to, or removals from, the public API surface area. label Sep 14, 2026
@codecov

codecov Bot commented Sep 14, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 91.78082% with 6 lines in your changes missing coverage. Please review.
⚠️ Please upload report for BASE (version7@aa02031). Learn more about missing BASE report.

Files with missing lines Patch % Lines
src/Sentry/Internal/ConcurrentBagLite.cs 37.50% 5 Missing ⚠️
src/Sentry.Serilog/SentrySink.cs 96.42% 0 Missing and 1 partial ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             version7    #5573   +/-   ##
===========================================
  Coverage            ?   74.73%           
===========================================
  Files               ?      516           
  Lines               ?    18866           
  Branches            ?     3676           
===========================================
  Hits                ?    14100           
  Misses              ?     3892           
  Partials            ?      874           

☔ 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.

@ric-oliv

Copy link
Copy Markdown
Member

Nice @jamescrosswell! Assuming we agree with this direction (Logging extension only configures the sink and does not inits the SDK), I think it's looking pretty good!

  • We should probably remove the Dsn (not used anymore) and the the EnableTracing (never used) properties from the appsettings.json example.
  • While testing the Serilog sample project (as a user upgrading and not initializing the Sentry SDK manually), I don't get any crash or warning... the SDK configures the sink, but no-ops on the execution. It might be worth checking if we should crash the SDK (or log via another channel) in this scenario.
  • Having the SDK initialized but not calling "UseSerilog()" is only going to show up in the logs as a warning, and only if we have debug = true. This feels a bit prone to issues with integrators forgetting to call "UseSerilog()" and not seeing any information at all about the issue. It would be great is we could somehow make the SDK itself register the SerilogScopeEventProcessor and avoid the call completely. Not sure if we can do this though.

Other than that, I believe we're good to merge this PR!

The sample sets the DSN in code via UseSentry, so the commented-out Dsn
entry is misleading. EnableTracing is declared on BindableSentryOptions
but never applied, so setting it has no effect.

Part of #5245

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread src/Sentry.Serilog/SentrySink.cs Outdated
@jamescrosswell

Copy link
Copy Markdown
Collaborator Author
  • We should probably remove the Dsn (not used anymore) and the the EnableTracing (never used) properties from the appsettings.json example.

Good call. Done in 0aada87

Emit can run concurrently, so the check-then-set on the warned flag could
let more than one thread log the warning.

Part of #5245

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

jamescrosswell commented Sep 21, 2026 •

Copy link
Copy Markdown
Collaborator Author
  • While testing the Serilog sample project (as a user upgrading and not initializing the Sentry SDK manually), I don't get any crash or warning... the SDK configures the sink, but no-ops on the execution. It might be worth checking if we should crash the SDK (or log via another channel) in this scenario.

I'm guessing we're talking about the scenario where someone initialises both Serilog and the Sdk via configuration bindings (e.g. appsettings.json)... and yeah, that's an issue since they wouldn't get any compiler warnings letting them know the DSN is no longer used.

We could try to bind to the DSN value in the logging config... not because we actually want to use it but just to check if someone has erroneously configured it there and so that we can show them a warning?

EDIT: did a bit of research on this...

Serilog.Settings.Configuration automatically populates an IConfiguration parameter on a sink method, so we could add an IConfiguration parameter and use this to walk the config and check for a DSN configuration. However we'd need to add a new public dependency on Microsoft.Extensions.Configuration.Abstractions to Sentry.Serilog to do that, purely to produce this warning for the upgrade to v7.x.

Normally I'd be against adding a dependency for a single warning... however this is a fairly major change and most apps would have that particular dependency already anyway, so we could do it.

Also Serilog.Settings.AppSettings (the XML app.config provider, still relevant for net462) binds args by name too and IConfiguration injection won't reach it.

@ric-oliv thoughts?

@jamescrosswell

Copy link
Copy Markdown
Collaborator Author
  • Having the SDK initialized but not calling "UseSerilog()" is only going to show up in the logs as a warning, and only if we have debug = true. This feels a bit prone to issues with integrators forgetting to call "UseSerilog()" and not seeing any information at all about the issue. It would be great is we could somehow make the SDK itself register the SerilogScopeEventProcessor and avoid the call completely. Not sure if we can do this though.

That one's trickier... the call to initialise the SDK is made from the Sentry library... whereas the call to UseSerilog is made from the Sentry.Serilog library. SentrySdk.Init doesn't know whether the Sentry.Serilog package has been added to the user's project or not and, even if it did, it wouldn't have access to the SerilogScopeEventProcessor type via any means other than reflection (which we can't really use - it breaks AOT compilation).

The only other mechanisms that I can think of are:

  • An analyzer (that warns people if they've included the Sentry.Serilog integration but not called UseSerilog()
  • A source generator (that takes the analyser one step further)
  • Maybe some solution with module initialisers.

I think any of those is a fairly complex piece of work that would have lots of edge cases and testing (given that people can initialise both Sentry and Serilog either from code and/or from configuration bindings, we don't know the order of initialisation, init logic may be delegated to code from other external modules etc.). If we do want to tackle it, I think it's a separate issue/PR and probably safer to assume we won't get it done before v7.

Sdk.Name should identify the integration that initialised the hub, which after
this change can no longer be a logging integration. The sink identifies itself
through the log origin (auto.log.serilog) instead.
See #5497.

Events are no longer stamped with sentry.dotnet.serilog, and structured logs no
longer carry it as sentry.sdk.name; both now report the SDK that initialised
Sentry.

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

ric-oliv commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

I'm guessing we're talking about the scenario where someone initialises both Serilog and the Sdk via configuration bindings (e.g. appsettings.json)

Exactly!

@ric-oliv thoughts?

How do you feel about keeping the SentrySinkExtension "Sentry" with the DSN as an obsolete overload that will throw an exception whenever bounded to? (instead of deleting it).
That way, any integrator that does not change the implementation will immediately have an exception instead of only loosing the logs. We could then remove this overload in v8.

I'll create a PR into this branch so you can have a look if it's a good approach.

As a side-note: the PR description says that the config-bound dsn args "will no longer bind to a Sentry sink method", but they do bind, that's why the issue is silent.

…on error

Serilog configuration providers bind sink arguments by parameter name, so
removing the dsn-first overload made them drop `dsn` silently: the sink still
binds, Sentry is never initialized, and nothing is reported. Keeping the
overload as an [Obsolete(error: true)] tombstone that throws makes both
Serilog.Settings.Configuration (appsettings.json) and Serilog.Settings.AppSettings
(app.config) fail loudly with migration guidance, while code callers get a
compile error instead of a type mismatch on the second argument.

The overload mirrors the surviving overload's parameters plus `dsn`. With only
`string dsn` it loses Serilog's overload ranking whenever a configuration
supplies two or more of the surviving arguments, which would restore the silent
behaviour.

Part of #5245

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ric-oliv

ric-oliv commented Sep 22, 2026 •

Copy link
Copy Markdown
Member

That one's trickier... the call to initialise the SDK is made from the Sentry library... whereas the call to UseSerilog is made from the Sentry.Serilog library. SentrySdk.Init doesn't know whether the Sentry.Serilog package has been added to the user's project or not and, even if it did, it wouldn't have access to the SerilogScopeEventProcessor type via any means other than reflection (which we can't really use - it breaks AOT compilation).

Yes, and we might be able to use SentryOptions to automatically register the SerilogScopeEventProcessor in the SentrySink.
We could potentially call it both in the SentrySink constructor and in the Emit method.

The only issue currently is that SentryOptions keeps the processors in Lists, and SentryClient enumerates those lazily for the whole duration of a capture, so adding one from another thread throws. We can solve it by changing those to a ConcurrentBagLite and adding a couple of auxiliary methods.

In this case, the user should still call UseSerilog() to catch any error that occurs before the SentrySink is initialized, but if it isn't called then we still manage to recover and register ourselves.

One thing I ran into while testing (unrelated to this PR) was the Emit method answering a reentrant log event with another diagnostic. This caused Serilog to route that back into the sink, and each message embeds the previous one. The IsSentrySdk filter that would break the cycle sits in InnerEmit, after the reentrancy branch has already returned.
This can be reproduced in the AspNetCore.Serilog sample with DiagnosticLevel: Info and no UseSerilog(), the Moving the filter above the reentrancy check fixes it (we can also fix that in a separate PR).

I've drafted #5612 just so you have an idea... the test suite passes but we might need to discuss it more. Your call if we follow this path or not (totally fine you see a problem with the approach, or if we should break this down in separate PRs, etc.)

…ration

The migration guard works only because of Serilog's overload ranking, and
nothing exercised that path. These tests bind a sink from IConfiguration
the way a provider does, so a Serilog change that stops selecting the
tombstone fails here rather than silently dropping the DSN again.

Verified they fail without the tombstone overload. Selection behaves the
same on Serilog.Settings.Configuration 3.4.0 (Serilog 2.12) and 10.0.1
(Serilog 4.3); 3.4.0 is referenced to avoid bumping Serilog in the tests.

Part of #5245

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread samples/Sentry.Samples.AspNetCore.Serilog/appsettings.json
Restores the DSN comment dropped from the Serilog sample's appsettings.json,
pointing at where this sample actually sets it, and records in AGENTS.md that
"prefer no comments" covers the library rather than samples - including their
JSON configuration files.

Part of #5245

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Comment thread src/Sentry.Serilog/SentrySink.cs
Comment thread AGENTS.md Outdated
@jamescrosswell
jamescrosswell removed this pull request from stack #5603 September 27, 2026 22:03
@ric-oliv

Copy link
Copy Markdown
Member

Hi @jamescrosswell,
I missed a couple of things here previously.

  1. There's still a path where Sentry silently stops working: the WriteTo.Sentry(o => …) callback with only sink settings (e.g. o.MinimumEventLevel = …), where the DSN comes from SENTRY_DSN or [assembly: Dsn(...)] (SettingLocator). On 6.x that overload initialized the SDK itself, because InitializeSdk defaulted to true. With this PR the code still compiles, no dsn reaches the tombstone, nothing calls Init, and the sink drops everything without any output. It's also the first sample under Configure in the Serilog docs (which we will need to update as well once this is merged).

I tested that sample with a Log.Error(...) call:

  • version7 with SENTRY_DSN set: SDK enabled, event captured.
  • version7 without it: the app crashes at startup (You must supply a DSN), so anyone running this pattern today gets their DSN from the environment or the attribute.
  • This PR, either way: SDK disabled, event dropped, exit code 0, nothing printed.

We can't make it fail at startup, because logging before UseSentry initializes is legitimate (bootstrap loggers). But we could signal it once at runtime. On the first event at or above MinimumEventLevel, if Sentry isn't initialized and a DSN can be found, write one line to SelfLog and to Console.Error. SelfLog alone only reaches people who have enabled it, so it wouldn't help anyone who doesn't know something is wrong. Either way, I think this belongs under Breaking changes, with a migration note.

@ric-oliv

Copy link
Copy Markdown
Member
  1. LogContext properties now become tags on every event, for everyone using the sink.

Before this PR, SerilogScopeEventProcessor was only registered if the app called ApplySerilogScopeToEvents() (which isn't in our docs or samples) or used the WriteTo.Sentry("dsn") overload, which called it internally. Everyone else, including the common UseSentry + WriteTo.Sentry() setup, only saw LogContext properties as extras on events created from log lines, and only if the logger had Enrich.FromLogContext().

With the automatic registration from my last PR here, the sink registers the processor itself, in its constructor or on its first log event. So for everyone using the sink, LogContext properties are now added as tags on every event: unhandled exceptions and SentrySdk.CaptureException included, not just events created from logs.

This matches Sentry.Extensions.Logging, where BeginScope key/values become tags on the Sentry scope by default. Since ApplySerilogScopeToEvents() was never documented, I think having this on by default is what users expect from the integrationbut Serilog and MEL integrations still differ in a few ways:

  • Which values: MEL keeps only string values (UserId = 42 is dropped). Serilog converts every property with ToString().
  • When they're read: MEL copies the values into the Sentry scope when BeginScope is called. Serilog reads LogContext each time an event is captured.
  • Opt-out: MEL can be customised or switched off through the public SentryOptions.SentryScopeStateProcessor. The Serilog processor is internal, so it can't be removed or replaced.
  • Global mode (MAUI, desktop): MEL's PushScope does nothing there. The Serilog processor still runs.
  • Coverage from startup: MEL applies from the moment Sentry is initialised. The automatic registration only applies from when the sink is created or first used. Calling UseSerilog() closes that gap.

Suggestions:

  • Keep the automatic registration. Under our logging policy, adding the sink is the user signal, and requiring UseSerilog() on top would effectively be a double opt-in.
  • List it under Breaking changes, e.g. "Events now include Serilog LogContext properties as tags", and if needed we can also mention in the migration notes how to remove unwanted keys with SetBeforeSend (plus SetBeforeSendFeedback, since feedback also goes through event processors).

What do you think?

@jamescrosswell

jamescrosswell commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator Author

Serilog and MEL integrations still differ in a few ways:

Most of those things were true before this PR... we can create a follow up issue to try to make these more consistent. Some of the differences may be necessary due to functional differences between MEL and SeriLog though.

The only one that's actually changed is the last one. With WriteTo.Sentry(dsn) the sink was the init, and that gap disappears once we merge #5595... which makes the same true for MEL.

I've added a follow up to look into this - I think it can be prioritised separately though (not a stopper for v7):

Keep the automatic registration. Under our logging policy, adding the sink is the user signal, and requiring UseSerilog() on top would effectively be a double opt-in.

Agreed.

List it under Breaking changes, e.g. "Events now include Serilog LogContext properties as tags", and if needed we can also mention in the migration notes how to remove unwanted keys with SetBeforeSend (plus SetBeforeSendFeedback, since feedback also goes through event processors).

Yeah sure, we'll have all this in the release notes for version 7.0.

…try is not initialized

The tombstoned overloads catch everyone who passes a DSN to the sink, but they cannot see
the `WriteTo.Sentry(o => ...)` callback that only sets sink options and gets its DSN from
SENTRY_DSN or a [Dsn] assembly attribute. On 6.x that overload initialized the SDK itself;
now it compiles, nothing calls Init, and the sink drops everything silently.

Warn once, on the first event at or above MinimumEventLevel, when the hub is disabled and a
DSN can still be found. There is no DiagnosticLogger to write to in that state, so the
warning goes to Serilog's SelfLog and to standard error.

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

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Want reviews to match your repository better? Bugbot Learning can learn team-specific rules from PR activity. A team admin can enable Learning in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 2925072. Configure here.

{
return;
_uninitializedSdkWarning.WarnOnce(UninitializedSdkMessage);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shutdown logs warn SDK never initialized

Low Severity

A disabled hub after Close or disposing the Init handle is treated the same as never initializing. If SENTRY_DSN (or a Dsn attribute) is still present, a later event-level log can write the one-time stderr warning telling the app to call SentrySdk.Init, even when Sentry was initialized correctly and then shut down.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 2925072. Configure here.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Highly unlikely... that implies the SDK has been initialised, the app has been running and the SDK closed all before a single log is made (since the warning only ever fires once - it will only be triggered by the first log message if the SDK is not initialised at that time).

Comment thread src/Sentry/Internal/UninitializedSdkWarning.cs
@jamescrosswell

Copy link
Copy Markdown
Collaborator Author

Suggestions:

* Keep the automatic registration. Under our logging policy, adding the sink is the user signal, and requiring `UseSerilog()` on top would effectively be a double opt-in.

* List it under Breaking changes, e.g. _"Events now include Serilog LogContext properties as tags"_, and if needed we can also mention in the migration notes how to remove unwanted keys with `SetBeforeSend` (plus `SetBeforeSendFeedback`, since feedback also goes through event processors).

What do you think?

@ric-oliv implemented across all 4 PRs - adds a bit of complexity but for the transition from version6 to version7, probably worth keeping. We can always remove this in a later version.

Comment thread src/Sentry.Serilog/SentryOptionExtensions.cs

@ric-oliv ric-oliv left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good!

I think we just need to update the PR title to state the breaking change (e.g.: feat(serilog)!: ….), since this will probably otherwise land under Features in the release notes, right? Same for the others #5585, #5592 and #5595.

Co-authored-by: Ricardo Colombo Oliveira <github@ricoliv.com>
@jamescrosswell jamescrosswell changed the title feat: Serilog sink no longer initializes the SDK feat(serilog)!: the Sentry sink no longer initializes the SDK Sep 29, 2026
@jamescrosswell
jamescrosswell merged commit a19eb2f into version7 Sep 29, 2026
32 checks passed
@jamescrosswell
jamescrosswell deleted the feat/no-init-from-logging-5245 branch September 29, 2026 22:12
jamescrosswell added a commit that referenced this pull request Sep 29, 2026
Conflict resolutions:

- global.json, Directory.Build.props: kept version7's .NET 11 SDK/workload pins and the
  7.0.0-prerelease version.
- AGENTS.md: kept both sides. main added the good/bad comment examples; version7 has the
  samples exemption, which scopes the whole section and follows them.
- integration-test/ios.Tests.ps1: kept version7's renamed source app (net9-maui became
  maui-device, so main's path no longer exists) plus main's stale bin/obj cleanup.
- samples/Sentry.Samples.Google.Cloud.Functions/appsettings.json: took main. EnableTracing
  is gone from both SentryOptions and BindableSentryOptions, so it would be ignored.
- samples/Sentry.Samples.AspNetCore.Serilog/appsettings.json: kept version7's DSN comment
  (main's commented-out Dsn would now mislead, since the sink takes no DSN) plus main's
  TracesSampleRate.
- test/Sentry.Serilog.Tests/SentrySinkTests.cs: kept EmitBreadcrumb_WithException_
  ProvidesExceptionInHint, which main added in #5523 and version7 has never had. Dropped
  Emit_SerilogSdk_Name and Emit_SerilogSdk_Packages, which #5573 removed along with the
  sink's SDK name.

Two fixes the merge made necessary:

- main pins SQLitePCLRaw.bundle_e_sqlite3 forward to 2.1.13 for every .NETCoreApp target to
  dodge GHSA-2m69-gcr7-jv3q, but EF Core 11 already floors it at 3.0.5, so on net11.0 the pin
  is a downgrade and NU1605 fails the build. net11.0 is now excluded from it.
- ApiApprovalTests.Run.DotNet11_0 regenerated for HintTypes.Exception, the AddBreadcrumb hint
  overload and StringOrRegex.IsRegex. main updated its own snapshots and those merged cleanly,
  but the net11.0 one only exists here.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jamescrosswell added a commit that referenced this pull request Sep 29, 2026
…-logging-nlog-5245

version7 now has main merged into it, and #5573 has landed there, so this picks both up.

All four conflicts took version7's side, which is strictly newer in each case:

- AGENTS.md, samples/Sentry.Samples.AspNetCore.Serilog/appsettings.json and
  test/Sentry.Serilog.Tests/SentrySinkTests.cs were resolved when main was merged into
  version7; this branch only carried the pre-merge side of them.
- src/Sentry.Serilog/SentryOptionExtensions.cs: the UseSerilog() doc comment here still said
  the sink "cannot do this for you", which stopped being true when #5612 made the sink
  register the scope processor itself. version7 has the corrected wording.

The merge also brings #5523's breadcrumb hint to the NLog target (hint: exception.ToHint())
and its test, which don't overlap with anything in this PR.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jamescrosswell added a commit that referenced this pull request Sep 29, 2026
…245' into feat/no-init-from-logging-log4net-5245

Picks up version7 (which now has main merged in) and #5573 via the NLog branch. No conflicts.

main added test/Sentry.Log4Net.V3.Tests, which shares the appender test sources by <Compile
Include> and runs them against log4net 3.4.0 instead of 2.0.12. The new
SentryAppenderUninitializedSdkTests.cs is now included there too, so the runtime warning is
covered on both log4net majors. That also confirms LogLog.Warn(Type, string) is binary
compatible across the two, which the appender relies on: Sentry.Log4Net compiles against
2.0.12 but the V3 tests load it against 3.4.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
jamescrosswell added a commit that referenced this pull request Sep 29, 2026
…t-5245' into feat/no-init-from-logging-mel-5245

Picks up version7 (which now has main merged in) plus #5573 and the NLog and log4net branches.

test/Sentry.Extensions.Logging.Tests/SentryLoggingOptionsSetupTests.cs was the only textual
conflict, and kept this branch's side: the test asserts only MinimumBreadcrumbLevel and
MinimumEventLevel because SentryLoggingOptions no longer derives from SentryOptions, so the
core SDK properties the other side binds don't exist on it. version7's only change to that
file was #5631 removing three assertions this version never makes.

Two things merged cleanly but did not compile, where main's new log entry filters meet this
branch's options split:

- Main moved the category, EF and filter checks out of ShouldCaptureEvent into their own early
  return, leaving it level-only, so the runtime warning's gate no longer had a 3-argument
  overload to call. It now goes through WouldCaptureEvent, which mirrors the real path.
- SentryLogger reported a failing filter callback via _options.LogError, which only resolves
  while SentryLoggingOptions is a SentryOptions. It now reports through the hub's options,
  matching how the structured logger reads its defaults on this branch. The two tests covering
  it set the diagnostic logger substitute on the hub's options instead.

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

Breaking Change Binary/Source/Behavioral Breaking Changes. public API Additions/modifications to, or removals from, the public API surface area. risk: high PR risk score: high Serilog

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants