From d116dd95c2dfef0300e660701438abff2f3fb7b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 2 Dec 2025 12:10:46 +0100 Subject: [PATCH 1/5] feat(logs): add more default attributes --- src/Sentry/SentryLog.cs | 72 +++++++++++- test/Sentry.Tests/SentryLogTests.cs | 164 +++++++++++++++++++++++++++- 2 files changed, 233 insertions(+), 3 deletions(-) diff --git a/src/Sentry/SentryLog.cs b/src/Sentry/SentryLog.cs index b3f7b78f5c..13ae6271c1 100644 --- a/src/Sentry/SentryLog.cs +++ b/src/Sentry/SentryLog.cs @@ -24,8 +24,8 @@ internal SentryLog(DateTimeOffset timestamp, SentryId traceId, SentryLogLevel le TraceId = traceId; Level = level; Message = message; - // 7 is the number of built-in attributes, so we start with that. - _attributes = new Dictionary(7); + // we currently set up to 18 default attributes, 23 is the next prime number + _attributes = new Dictionary(23); } /// @@ -164,6 +164,11 @@ internal void SetAttribute(string key, int value) } internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk) + { + SetDefaultAttributes(options, sdk, ReplaySession.Instance, SentrySdk.CurrentHub); + } + + internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk, IReplaySession replaySession, IHub hub) { var environment = options.SettingLocator.GetEnvironment(); SetAttribute("sentry.environment", environment); @@ -182,6 +187,69 @@ internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk) { SetAttribute("sentry.sdk.version", version); } + + var replayId = replaySession.ActiveReplayId; + if (replayId.HasValue && replayId.Value != SentryId.Empty) + { + SetAttribute("sentry.replay_id", replayId.Value.ToString()); + } + + var scope = hub.GetScope(); + if (scope is not null) + { + if (scope.User.Id is { } userId) + { + SetAttribute("user.id", userId); + } + if (scope.User.Username is { } userName) + { + SetAttribute("user.name", userName); + } + if (scope.User.Email is { } userEmail) + { + SetAttribute("user.email", userEmail); + } + + if (scope.Contexts.Browser.Name is { } browserName) + { + SetAttribute("browser.name", browserName); + } + if (scope.Contexts.Browser.Version is { } browserVersion) + { + SetAttribute("browser.version", browserVersion); + } + + var serverAddress = options.ServerName; + if (!string.IsNullOrEmpty(serverAddress)) + { + SetAttribute("server.address", serverAddress); + } + else if (options.SendDefaultPii) + { + SetAttribute("server.address", Environment.MachineName); + } + + if (scope.Contexts.OperatingSystem.Name is { } osName) + { + SetAttribute("os.name", osName); + } + if (scope.Contexts.OperatingSystem.Version is { } osVersion) + { + SetAttribute("os.version", osVersion); + } + if (scope.Contexts.Device.Brand is { } deviceBrand) + { + SetAttribute("device.brand", deviceBrand); + } + if (scope.Contexts.Device.Model is { } deviceModel) + { + SetAttribute("device.model", deviceModel); + } + if (scope.Contexts.Device.Family is { } deviceFamily) + { + SetAttribute("device.family", deviceFamily); + } + } } internal void SetOrigin(string origin) diff --git a/test/Sentry.Tests/SentryLogTests.cs b/test/Sentry.Tests/SentryLogTests.cs index 505249b95e..3512688cc4 100644 --- a/test/Sentry.Tests/SentryLogTests.cs +++ b/test/Sentry.Tests/SentryLogTests.cs @@ -70,6 +70,84 @@ public void Protocol_Default_VerifyAttributes() notFound.Should().BeNull(); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaultAttributes) + { + var options = new SentryOptions + { + Environment = "my-environment", + Release = "my-release", + ServerName = hasAdditionalDefaultAttributes ? "my-server-address" : null, + }; + var sdk = new SdkVersion + { + Name = "Sentry.Test.SDK", + Version = "1.2.3-test+Sentry" + }; + + var replaySession = Substitute.For(); + replaySession.ActiveReplayId.Returns(hasAdditionalDefaultAttributes ? SentryId.Create() : SentryId.Empty); + var hub = Substitute.For(); + var scope = new Scope(options); + if (hasAdditionalDefaultAttributes) + { + scope.User = new SentryUser + { + Id = "my-user-id", + Username = "my-user-name", + Email = "my-user-email", + }; + scope.Contexts.Browser.Name = "my-browser-name"; + scope.Contexts.Browser.Version = "my-browser-version"; + scope.Contexts.OperatingSystem.Name = "my-os-name"; + scope.Contexts.OperatingSystem.Version = "my-os-version"; + scope.Contexts.Device.Brand = "my-device-brand"; + scope.Contexts.Device.Model = "my-device-model"; + scope.Contexts.Device.Family = "my-device-family"; + } + hub.SubstituteConfigureScope(scope); + + var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message") + { + Template = "template", + Parameters = ImmutableArray.Create(new KeyValuePair("param", "params")), + ParentSpanId = ParentSpanId, + }; + log.SetAttribute("attribute", "value"); + log.SetDefaultAttributes(options, sdk, replaySession, hub); + + log.TryGetAttribute("sentry.replay_id", out string replayId).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("user.id", out string userId).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("user.name", out string userName).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("user.email", out string userEmail).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("browser.name", out string browserName).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("browser.version", out string browserVersion).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("server.address", out string serverAddress).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("os.name", out string osName).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("os.version", out string osVersion).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("device.brand", out string deviceBrand).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("device.model", out string deviceModel).Should().Be(hasAdditionalDefaultAttributes); + log.TryGetAttribute("device.family", out string deviceFamily).Should().Be(hasAdditionalDefaultAttributes); + + if (hasAdditionalDefaultAttributes) + { + replayId.Should().Be(replaySession.ActiveReplayId.ToString()); + userId.Should().Be("my-user-id"); + userName.Should().Be("my-user-name"); + userEmail.Should().Be("my-user-email"); + browserName.Should().Be("my-browser-name"); + browserVersion.Should().Be("my-browser-version"); + serverAddress.Should().Be("my-server-address"); + osName.Should().Be("my-os-name"); + osVersion.Should().Be("my-os-version"); + deviceBrand.Should().Be("my-device-brand"); + deviceModel.Should().Be("my-device-model"); + deviceFamily.Should().Be("my-device-family"); + } + } + [Theory] [InlineData(true)] [InlineData(false)] @@ -101,6 +179,7 @@ public void WriteTo_Envelope_MinimalSerializedSentryLog() { Environment = "my-environment", Release = "my-release", + SendDefaultPii = false, }; var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Trace, "message"); @@ -170,7 +249,42 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() { Environment = "my-environment", Release = "my-release", + ServerName = "my-server-address", + }; + + var replaySession = Substitute.For(); + var replayId = SentryId.Create(); + replaySession.ActiveReplayId.Returns(replayId); + var hub = Substitute.For(); + var scope = new Scope(options) + { + User = new SentryUser + { + Id = "my-user-id", + Username = "my-user-name", + Email = "my-user-email", + }, + Contexts = new SentryContexts + { + Browser = + { + Name = "my-browser-name", + Version = "my-browser-version", + }, + OperatingSystem = + { + Name = "my-os-name", + Version = "my-os-version", + }, + Device = + { + Brand = "my-device-brand", + Model = "my-device-model", + Family = "my-device-family", + }, + }, }; + hub.SubstituteConfigureScope(scope); var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message") { @@ -182,7 +296,7 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() log.SetAttribute("boolean-attribute", true); log.SetAttribute("integer-attribute", 3); log.SetAttribute("double-attribute", 4.4); - log.SetDefaultAttributes(options, new SdkVersion { Name = "Sentry.Test.SDK", Version = "1.2.3-test+Sentry" }); + log.SetDefaultAttributes(options, new SdkVersion { Name = "Sentry.Test.SDK", Version = "1.2.3-test+Sentry" }, replaySession, hub); var envelope = EnvelopeItem.FromLog(new StructuredLog([log])); @@ -266,6 +380,54 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() "value": "1.2.3-test+Sentry", "type": "string" }, + "sentry.replay_id": { + "value": "{{replayId.ToString()}}", + "type": "string" + }, + "user.id": { + "value": "my-user-id", + "type": "string" + }, + "user.name": { + "value": "my-user-name", + "type": "string" + }, + "user.email": { + "value": "my-user-email", + "type": "string" + }, + "browser.name": { + "value": "my-browser-name", + "type": "string" + }, + "browser.version": { + "value": "my-browser-version", + "type": "string" + }, + "server.address": { + "value": "my-server-address", + "type": "string" + }, + "os.name": { + "value": "my-os-name", + "type": "string" + }, + "os.version": { + "value": "my-os-version", + "type": "string" + }, + "device.brand": { + "value": "my-device-brand", + "type": "string" + }, + "device.model": { + "value": "my-device-model", + "type": "string" + }, + "device.family": { + "value": "my-device-family", + "type": "string" + }, "sentry.trace.parent_span_id": { "value": "{{ParentSpanId.ToString()}}", "type": "string" From e6a974391b952ebe1361407c6d59894a067cb0b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 2 Dec 2025 13:46:15 +0100 Subject: [PATCH 2/5] ref(logs): apply default attributes from scope --- .../SentryStructuredLogger.cs | 2 +- src/Sentry.Serilog/SentrySink.Structured.cs | 2 +- .../Internal/DefaultSentryStructuredLogger.cs | 2 +- src/Sentry/SentryLog.cs | 115 +++++++++--------- test/Sentry.Tests/SentryLogTests.cs | 53 ++++---- 5 files changed, 91 insertions(+), 83 deletions(-) diff --git a/src/Sentry.Extensions.Logging/SentryStructuredLogger.cs b/src/Sentry.Extensions.Logging/SentryStructuredLogger.cs index c5d526253d..366de1f598 100644 --- a/src/Sentry.Extensions.Logging/SentryStructuredLogger.cs +++ b/src/Sentry.Extensions.Logging/SentryStructuredLogger.cs @@ -87,7 +87,7 @@ public void Log(LogLevel logLevel, EventId eventId, TState state, Except ParentSpanId = spanId, }; - log.SetDefaultAttributes(_options, _sdk); + log.SetDefaultAttributes(_options, _hub.GetScope(), _sdk); log.SetOrigin("auto.log.extensions_logging"); if (_categoryName is not null) diff --git a/src/Sentry.Serilog/SentrySink.Structured.cs b/src/Sentry.Serilog/SentrySink.Structured.cs index 41e3f95693..36388e7514 100644 --- a/src/Sentry.Serilog/SentrySink.Structured.cs +++ b/src/Sentry.Serilog/SentrySink.Structured.cs @@ -17,7 +17,7 @@ private static void CaptureStructuredLog(IHub hub, SentryOptions options, LogEve ParentSpanId = spanId, }; - log.SetDefaultAttributes(options, Sdk); + log.SetDefaultAttributes(options, hub.GetScope(), Sdk); log.SetOrigin("auto.log.serilog"); foreach (var attribute in attributes) diff --git a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs index 90f6df853a..2cab2cb422 100644 --- a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs +++ b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs @@ -69,7 +69,7 @@ private protected override void CaptureLog(SentryLogLevel level, string template } var scope = _hub.GetScope(); - log.SetDefaultAttributes(_options, scope?.Sdk ?? SdkVersion.Instance); + log.SetDefaultAttributes(_options, scope, scope?.Sdk ?? SdkVersion.Instance); CaptureLog(log); } diff --git a/src/Sentry/SentryLog.cs b/src/Sentry/SentryLog.cs index 13ae6271c1..9910f70c97 100644 --- a/src/Sentry/SentryLog.cs +++ b/src/Sentry/SentryLog.cs @@ -24,7 +24,7 @@ internal SentryLog(DateTimeOffset timestamp, SentryId traceId, SentryLogLevel le TraceId = traceId; Level = level; Message = message; - // we currently set up to 18 default attributes, 23 is the next prime number + // we currently set up to 18 default attributes, the next prime number is 23 _attributes = new Dictionary(23); } @@ -163,12 +163,12 @@ internal void SetAttribute(string key, int value) _attributes[key] = new SentryAttribute(value, "integer"); } - internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk) + internal void SetDefaultAttributes(SentryOptions options, Scope scope) { - SetDefaultAttributes(options, sdk, ReplaySession.Instance, SentrySdk.CurrentHub); + SetDefaultAttributes(options, scope, scope.Sdk); } - internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk, IReplaySession replaySession, IHub hub) + internal void SetDefaultAttributes(SentryOptions options, Scope? scope, SdkVersion sdk) { var environment = options.SettingLocator.GetEnvironment(); SetAttribute("sentry.environment", environment); @@ -188,67 +188,70 @@ internal void SetDefaultAttributes(SentryOptions options, SdkVersion sdk, IRepla SetAttribute("sentry.sdk.version", version); } - var replayId = replaySession.ActiveReplayId; - if (replayId.HasValue && replayId.Value != SentryId.Empty) + if (scope is null) { - SetAttribute("sentry.replay_id", replayId.Value.ToString()); + return; } - var scope = hub.GetScope(); - if (scope is not null) + if (scope.PropagationContext._dynamicSamplingContext is { } dynamicSamplingContext) { - if (scope.User.Id is { } userId) - { - SetAttribute("user.id", userId); - } - if (scope.User.Username is { } userName) - { - SetAttribute("user.name", userName); - } - if (scope.User.Email is { } userEmail) + if (dynamicSamplingContext.Items.TryGetValue("replay_id", out var replayId)) { - SetAttribute("user.email", userEmail); + SetAttribute("sentry.replay_id", replayId); } + } - if (scope.Contexts.Browser.Name is { } browserName) - { - SetAttribute("browser.name", browserName); - } - if (scope.Contexts.Browser.Version is { } browserVersion) - { - SetAttribute("browser.version", browserVersion); - } + if (scope.User.Id is { } userId) + { + SetAttribute("user.id", userId); + } + if (scope.User.Username is { } userName) + { + SetAttribute("user.name", userName); + } + if (scope.User.Email is { } userEmail) + { + SetAttribute("user.email", userEmail); + } - var serverAddress = options.ServerName; - if (!string.IsNullOrEmpty(serverAddress)) - { - SetAttribute("server.address", serverAddress); - } - else if (options.SendDefaultPii) - { - SetAttribute("server.address", Environment.MachineName); - } + if (scope.Contexts.Browser.Name is { } browserName) + { + SetAttribute("browser.name", browserName); + } + if (scope.Contexts.Browser.Version is { } browserVersion) + { + SetAttribute("browser.version", browserVersion); + } - if (scope.Contexts.OperatingSystem.Name is { } osName) - { - SetAttribute("os.name", osName); - } - if (scope.Contexts.OperatingSystem.Version is { } osVersion) - { - SetAttribute("os.version", osVersion); - } - if (scope.Contexts.Device.Brand is { } deviceBrand) - { - SetAttribute("device.brand", deviceBrand); - } - if (scope.Contexts.Device.Model is { } deviceModel) - { - SetAttribute("device.model", deviceModel); - } - if (scope.Contexts.Device.Family is { } deviceFamily) - { - SetAttribute("device.family", deviceFamily); - } + var serverAddress = options.ServerName; + if (!string.IsNullOrEmpty(serverAddress)) + { + SetAttribute("server.address", serverAddress); + } + else if (options.SendDefaultPii) + { + SetAttribute("server.address", Environment.MachineName); + } + + if (scope.Contexts.OperatingSystem.Name is { } osName) + { + SetAttribute("os.name", osName); + } + if (scope.Contexts.OperatingSystem.Version is { } osVersion) + { + SetAttribute("os.version", osVersion); + } + if (scope.Contexts.Device.Brand is { } deviceBrand) + { + SetAttribute("device.brand", deviceBrand); + } + if (scope.Contexts.Device.Model is { } deviceModel) + { + SetAttribute("device.model", deviceModel); + } + if (scope.Contexts.Device.Family is { } deviceFamily) + { + SetAttribute("device.family", deviceFamily); } } diff --git a/test/Sentry.Tests/SentryLogTests.cs b/test/Sentry.Tests/SentryLogTests.cs index 3512688cc4..c935b60d5a 100644 --- a/test/Sentry.Tests/SentryLogTests.cs +++ b/test/Sentry.Tests/SentryLogTests.cs @@ -30,10 +30,13 @@ public void Protocol_Default_VerifyAttributes() Environment = "my-environment", Release = "my-release", }; - var sdk = new SdkVersion + var scope = new Scope(options) { - Name = "Sentry.Test.SDK", - Version = "1.2.3-test+Sentry" + Sdk = + { + Name = "Sentry.Test.SDK", + Version = "1.2.3-test+Sentry", + } }; var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message") @@ -43,7 +46,7 @@ public void Protocol_Default_VerifyAttributes() ParentSpanId = ParentSpanId, }; log.SetAttribute("attribute", "value"); - log.SetDefaultAttributes(options, sdk); + log.SetDefaultAttributes(options, scope); log.Timestamp.Should().Be(Timestamp); log.TraceId.Should().Be(TraceId); @@ -63,9 +66,9 @@ public void Protocol_Default_VerifyAttributes() log.TryGetAttribute("sentry.release", out string release).Should().BeTrue(); release.Should().Be(options.Release); log.TryGetAttribute("sentry.sdk.name", out string name).Should().BeTrue(); - name.Should().Be(sdk.Name); + name.Should().Be(scope.Sdk.Name); log.TryGetAttribute("sentry.sdk.version", out string version).Should().BeTrue(); - version.Should().Be(sdk.Version); + version.Should().Be(scope.Sdk.Version); log.TryGetAttribute("not-found", out object notFound).Should().BeFalse(); notFound.Should().BeNull(); } @@ -81,18 +84,15 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul Release = "my-release", ServerName = hasAdditionalDefaultAttributes ? "my-server-address" : null, }; - var sdk = new SdkVersion - { - Name = "Sentry.Test.SDK", - Version = "1.2.3-test+Sentry" - }; - - var replaySession = Substitute.For(); - replaySession.ActiveReplayId.Returns(hasAdditionalDefaultAttributes ? SentryId.Create() : SentryId.Empty); - var hub = Substitute.For(); var scope = new Scope(options); + if (hasAdditionalDefaultAttributes) { + options.Dsn = ValidDsn; + var replaySession = Substitute.For(); + replaySession.ActiveReplayId.Returns(SentryId.Parse("f18176ecbb544e549fd23fbbe39064cc")); + _ = scope.PropagationContext.GetOrCreateDynamicSamplingContext(options, replaySession); + scope.User = new SentryUser { Id = "my-user-id", @@ -107,7 +107,6 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul scope.Contexts.Device.Model = "my-device-model"; scope.Contexts.Device.Family = "my-device-family"; } - hub.SubstituteConfigureScope(scope); var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message") { @@ -116,7 +115,7 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul ParentSpanId = ParentSpanId, }; log.SetAttribute("attribute", "value"); - log.SetDefaultAttributes(options, sdk, replaySession, hub); + log.SetDefaultAttributes(options, scope); log.TryGetAttribute("sentry.replay_id", out string replayId).Should().Be(hasAdditionalDefaultAttributes); log.TryGetAttribute("user.id", out string userId).Should().Be(hasAdditionalDefaultAttributes); @@ -133,7 +132,7 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul if (hasAdditionalDefaultAttributes) { - replayId.Should().Be(replaySession.ActiveReplayId.ToString()); + replayId.Should().Be("f18176ecbb544e549fd23fbbe39064cc"); userId.Should().Be("my-user-id"); userName.Should().Be("my-user-name"); userEmail.Should().Be("my-user-email"); @@ -181,9 +180,10 @@ public void WriteTo_Envelope_MinimalSerializedSentryLog() Release = "my-release", SendDefaultPii = false, }; + var scope = new Scope(options); var log = new SentryLog(Timestamp, TraceId, SentryLogLevel.Trace, "message"); - log.SetDefaultAttributes(options, new SdkVersion()); + log.SetDefaultAttributes(options, scope); var envelope = Envelope.FromLog(new StructuredLog([log])); @@ -251,13 +251,19 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() Release = "my-release", ServerName = "my-server-address", }; - var replaySession = Substitute.For(); var replayId = SentryId.Create(); replaySession.ActiveReplayId.Returns(replayId); - var hub = Substitute.For(); - var scope = new Scope(options) + var dynamicSamplingContext = DynamicSamplingContext.Empty(); + dynamicSamplingContext.SetReplayId(replaySession); + var propagationContext = new SentryPropagationContext(TraceId, ParentSpanId!.Value, dynamicSamplingContext); + var scope = new Scope(options, propagationContext) { + Sdk = + { + Name = "Sentry.Test.SDK", + Version = "1.2.3-test+Sentry", + }, User = new SentryUser { Id = "my-user-id", @@ -284,7 +290,6 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() }, }, }; - hub.SubstituteConfigureScope(scope); var log = new SentryLog(Timestamp, TraceId, (SentryLogLevel)24, "message") { @@ -296,7 +301,7 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() log.SetAttribute("boolean-attribute", true); log.SetAttribute("integer-attribute", 3); log.SetAttribute("double-attribute", 4.4); - log.SetDefaultAttributes(options, new SdkVersion { Name = "Sentry.Test.SDK", Version = "1.2.3-test+Sentry" }, replaySession, hub); + log.SetDefaultAttributes(options, scope); var envelope = EnvelopeItem.FromLog(new StructuredLog([log])); From 009f94c22edae3e9198cf94e7e7efac1306ec990 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Tue, 2 Dec 2025 14:48:45 +0100 Subject: [PATCH 3/5] fix(logs): SDK-Logger sets sdk-name and sdk-version attributes --- src/Sentry/Internal/DefaultSentryStructuredLogger.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs index 2cab2cb422..1ab21900bb 100644 --- a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs +++ b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs @@ -69,7 +69,12 @@ private protected override void CaptureLog(SentryLogLevel level, string template } var scope = _hub.GetScope(); - log.SetDefaultAttributes(_options, scope, scope?.Sdk ?? SdkVersion.Instance); + var sdk = scope?.Sdk; + if (sdk is null || (sdk.Name is null && sdk.Version is null)) + { + sdk = SdkVersion.Instance; + } + log.SetDefaultAttributes(_options, scope, sdk); CaptureLog(log); } From 7efc8f616aa48fa3dc338b090b169cf1cf654617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 3 Dec 2025 12:54:56 +0100 Subject: [PATCH 4/5] merge --- test/Sentry.Tests/SentryLogTests.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/test/Sentry.Tests/SentryLogTests.cs b/test/Sentry.Tests/SentryLogTests.cs index 94c95470a8..604bceea6d 100644 --- a/test/Sentry.Tests/SentryLogTests.cs +++ b/test/Sentry.Tests/SentryLogTests.cs @@ -112,7 +112,7 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul { Template = "template", Parameters = ImmutableArray.Create(new KeyValuePair("param", "params")), - ParentSpanId = ParentSpanId, + SpanId = SpanId, }; log.SetAttribute("attribute", "value"); log.SetDefaultAttributes(options, scope); @@ -256,7 +256,7 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() replaySession.ActiveReplayId.Returns(replayId); var dynamicSamplingContext = DynamicSamplingContext.Empty(); dynamicSamplingContext.SetReplayId(replaySession); - var propagationContext = new SentryPropagationContext(TraceId, ParentSpanId!.Value, dynamicSamplingContext); + var propagationContext = new SentryPropagationContext(TraceId, SpanId!.Value, dynamicSamplingContext); var scope = new Scope(options, propagationContext) { Sdk = @@ -433,10 +433,6 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() "device.family": { "value": "my-device-family", "type": "string" - }, - "sentry.trace.parent_span_id": { - "value": "{{ParentSpanId.ToString()}}", - "type": "string" } } } From 0e25afd649192abff1603f5f13f01f5813916f60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20P=C3=B6lz?= <38893694+Flash0ver@users.noreply.github.com> Date: Wed, 3 Dec 2025 13:11:55 +0100 Subject: [PATCH 5/5] assert "sentry.origin" --- test/Sentry.Tests/SentryLogTests.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/Sentry.Tests/SentryLogTests.cs b/test/Sentry.Tests/SentryLogTests.cs index 604bceea6d..b5971aa5d8 100644 --- a/test/Sentry.Tests/SentryLogTests.cs +++ b/test/Sentry.Tests/SentryLogTests.cs @@ -82,13 +82,13 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul { Environment = "my-environment", Release = "my-release", - ServerName = hasAdditionalDefaultAttributes ? "my-server-address" : null, }; var scope = new Scope(options); if (hasAdditionalDefaultAttributes) { options.Dsn = ValidDsn; + var replaySession = Substitute.For(); replaySession.ActiveReplayId.Returns(SentryId.Parse("f18176ecbb544e549fd23fbbe39064cc")); _ = scope.PropagationContext.GetOrCreateDynamicSamplingContext(options, replaySession); @@ -101,6 +101,7 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul }; scope.Contexts.Browser.Name = "my-browser-name"; scope.Contexts.Browser.Version = "my-browser-version"; + options.ServerName = "my-server-address"; scope.Contexts.OperatingSystem.Name = "my-os-name"; scope.Contexts.OperatingSystem.Version = "my-os-version"; scope.Contexts.Device.Brand = "my-device-brand"; @@ -114,7 +115,6 @@ public void Protocol_Default_VerifyAdditionalAttributes(bool hasAdditionalDefaul Parameters = ImmutableArray.Create(new KeyValuePair("param", "params")), SpanId = SpanId, }; - log.SetAttribute("attribute", "value"); log.SetDefaultAttributes(options, scope); log.TryGetAttribute("sentry.replay_id", out string replayId).Should().Be(hasAdditionalDefaultAttributes); @@ -302,6 +302,7 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() log.SetAttribute("integer-attribute", 3); log.SetAttribute("double-attribute", 4.4); log.SetDefaultAttributes(options, scope); + log.SetOrigin("auto.log.sentry_tests"); var envelope = EnvelopeItem.FromLog(new StructuredLog([log])); @@ -433,6 +434,10 @@ public void WriteTo_EnvelopeItem_MaximalSerializedSentryLog() "device.family": { "value": "my-device-family", "type": "string" + }, + "sentry.origin": { + "value": "auto.log.sentry_tests", + "type": "string" } } }