From 769a3adb2757489715f7cc588c3096b600e75f97 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 4 Nov 2025 12:54:29 +0100 Subject: [PATCH 1/3] fix(logs): Serilog integration captures log when Event with Exception has been captured --- src/Sentry.Serilog/SentrySink.cs | 5 +-- .../SentrySinkTests.Structured.cs | 32 +++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/Sentry.Serilog/SentrySink.cs b/src/Sentry.Serilog/SentrySink.cs index 369d52a673..6bb1c1e08a 100644 --- a/src/Sentry.Serilog/SentrySink.cs +++ b/src/Sentry.Serilog/SentrySink.cs @@ -105,6 +105,7 @@ private void InnerEmit(LogEvent logEvent) var exception = logEvent.Exception; var template = logEvent.MessageTemplate.Text; var formatted = FormatLogEvent(logEvent); + var addedBreadcrumb = false; if (logEvent.Level >= _options.MinimumEventLevel) { @@ -137,11 +138,11 @@ private void InnerEmit(LogEvent logEvent) // Capturing exception events adds a breadcrumb automatically... we don't want to add another one if (exception != null) { - return; + addedBreadcrumb = true; } } - if (logEvent.Level >= _options.MinimumBreadcrumbLevel) + if (!addedBreadcrumb && logEvent.Level >= _options.MinimumBreadcrumbLevel) { Dictionary? data = null; if (exception != null && !string.IsNullOrWhiteSpace(formatted)) diff --git a/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs b/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs index dd1f44928d..dc061a37e5 100644 --- a/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs +++ b/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs @@ -134,4 +134,36 @@ public void Emit_StructuredLogging_LogEvent(bool withActiveSpan) log.TryGetAttribute("property.Structure-Property", out object? structure).Should().BeTrue(); structure.Should().Be("""[42, "42"]"""); } + + [Fact] + public void Emit_StructuredLoggingWithException_NoBreadcrumb() + { + InMemorySentryStructuredLogger capturer = new(); + _fixture.Hub.Logger.Returns(capturer); + _fixture.Options.Experimental.EnableLogs = true; + + var sut = _fixture.GetSut(); + var logger = new LoggerConfiguration().WriteTo.Sink(sut).MinimumLevel.Verbose().CreateLogger(); + + logger.Write(LogEventLevel.Error, new Exception("expected message"), "Message"); + + _fixture.Scope.Breadcrumbs.Should().BeEmpty(); + capturer.Logs.Should().ContainSingle().Which.Message.Should().Be("Message"); + } + + [Fact] + public void Emit_StructuredLoggingWithoutException_LeavesBreadcrumb() + { + InMemorySentryStructuredLogger capturer = new(); + _fixture.Hub.Logger.Returns(capturer); + _fixture.Options.Experimental.EnableLogs = true; + + var sut = _fixture.GetSut(); + var logger = new LoggerConfiguration().WriteTo.Sink(sut).MinimumLevel.Verbose().CreateLogger(); + + logger.Write(LogEventLevel.Error, (Exception?)null, "Message"); + + _fixture.Scope.Breadcrumbs.Should().ContainSingle().Which.Message.Should().Be("Message"); + capturer.Logs.Should().ContainSingle().Which.Message.Should().Be("Message"); + } } From 9984a49ce1f506d253a8200ab335fe64910c03e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 4 Nov 2025 13:05:51 +0100 Subject: [PATCH 2/3] docs: add CHANGELOG entry --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6444961f6..4deb0480d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,10 @@ - The SDK now provides a `IsSessionActive` to allow checking the session state ([#4662](https://github.com/getsentry/sentry-dotnet/pull/4662)) - The SDK now makes use of the new SessionEndStatus `Unhandled` when capturing an unhandled but non-terminal exception, i.e. through the UnobservedTaskExceptionIntegration ([#4633](https://github.com/getsentry/sentry-dotnet/pull/4633)) +### Fixes + +- The `Serilog` integration captures _Structured Logs_ (when enabled) independently of captured Events and added Breadcrumbs ([#4691](https://github.com/getsentry/sentry-dotnet/pull/4691)) + ## 6.0.0-preview.2 ### BREAKING CHANGES From 46b46ae5b7a2f370919feca082538ebfc0febaff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 4 Nov 2025 13:15:05 +0100 Subject: [PATCH 3/3] ref: clarify local variable name --- src/Sentry.Serilog/SentrySink.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Sentry.Serilog/SentrySink.cs b/src/Sentry.Serilog/SentrySink.cs index 6bb1c1e08a..4a4ad3e7f7 100644 --- a/src/Sentry.Serilog/SentrySink.cs +++ b/src/Sentry.Serilog/SentrySink.cs @@ -105,7 +105,7 @@ private void InnerEmit(LogEvent logEvent) var exception = logEvent.Exception; var template = logEvent.MessageTemplate.Text; var formatted = FormatLogEvent(logEvent); - var addedBreadcrumb = false; + var addedBreadcrumbForException = false; if (logEvent.Level >= _options.MinimumEventLevel) { @@ -138,11 +138,11 @@ private void InnerEmit(LogEvent logEvent) // Capturing exception events adds a breadcrumb automatically... we don't want to add another one if (exception != null) { - addedBreadcrumb = true; + addedBreadcrumbForException = true; } } - if (!addedBreadcrumb && logEvent.Level >= _options.MinimumBreadcrumbLevel) + if (!addedBreadcrumbForException && logEvent.Level >= _options.MinimumBreadcrumbLevel) { Dictionary? data = null; if (exception != null && !string.IsNullOrWhiteSpace(formatted))