diff --git a/CHANGELOG.md b/CHANGELOG.md index 1881b939f6..878319ce32 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,7 @@ - Exception filters should consider child exceptions of an `AggregateException` ([#1924](https://github.com/getsentry/sentry-dotnet/pull/1924)) - Add Blazor WASM detection to set IsGlobalModeEnabled to true ([#1931](https://github.com/getsentry/sentry-dotnet/pull/1931)) - Respect Transaction.IsSampled in SqlListener ([#1933](https://github.com/getsentry/sentry-dotnet/pull/1933)) +- Tags should not differ based on current culture ([#1949](https://github.com/getsentry/sentry-dotnet/pull/1949)) ## 3.21.0 diff --git a/src/Sentry.Extensions.Logging/SentryLogger.cs b/src/Sentry.Extensions.Logging/SentryLogger.cs index 4fa6aafb9c..7cee2ae163 100644 --- a/src/Sentry.Extensions.Logging/SentryLogger.cs +++ b/src/Sentry.Extensions.Logging/SentryLogger.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Microsoft.Extensions.Logging; using Sentry.Infrastructure; @@ -47,59 +48,7 @@ public void Log( if (ShouldCaptureEvent(logLevel, eventId, exception)) { - var @event = new SentryEvent(exception) - { - Logger = CategoryName, - Message = message, - Level = logLevel.ToSentryLevel() - }; - - if (state is IEnumerable> pairs) - { - foreach (var property in pairs) - { - if (property.Key == "{OriginalFormat}" && property.Value is string template) - { - // Original format found, use Sentry logEntry interface - @event.Message = new SentryMessage - { - Formatted = message, - Message = template - }; - continue; - } - - switch (property.Value) - { - case string stringTagValue: - @event.SetTag(property.Key, stringTagValue); - break; - - case Guid guidTagValue when guidTagValue != Guid.Empty: - @event.SetTag(property.Key, guidTagValue.ToString()); - break; - - case Enum enumValue: - @event.SetTag(property.Key, enumValue.ToString()); - break; - - default: - { - if (property.Value?.GetType().IsPrimitive == true) - { - @event.SetTag(property.Key, property.Value.ToString()!); - } - break; - } - } - } - } - - var tuple = eventId.ToTupleOrNull(); - if (tuple.HasValue) - { - @event.SetTag(tuple.Value.name, tuple.Value.value); - } + var @event = CreateEvent(logLevel, eventId, state, exception, message, CategoryName); _ = _hub.CaptureEvent(@event); } @@ -127,6 +76,65 @@ public void Log( } } + internal static SentryEvent CreateEvent(LogLevel logLevel, EventId id, TState state, Exception? exception, string? message, string category) + { + var @event = new SentryEvent(exception) + { + Logger = category, + Message = message, + Level = logLevel.ToSentryLevel() + }; + + if (state is IEnumerable> pairs) + { + foreach (var property in pairs) + { + if (property.Key == "{OriginalFormat}" && property.Value is string template) + { + // Original format found, use Sentry logEntry interface + @event.Message = new SentryMessage + { + Formatted = message, + Message = template + }; + continue; + } + + switch (property.Value) + { + case string stringTagValue: + @event.SetTag(property.Key, stringTagValue); + break; + + case Guid guidTagValue when guidTagValue != Guid.Empty: + @event.SetTag(property.Key, guidTagValue.ToString()); + break; + + case Enum enumValue: + @event.SetTag(property.Key, enumValue.ToString()); + break; + + default: + { + if (property.Value?.GetType().IsPrimitive == true) + { + @event.SetTag(property.Key, Convert.ToString(property.Value, CultureInfo.InvariantCulture)!); + } + break; + } + } + } + } + + var tuple = id.ToTupleOrNull(); + if (tuple.HasValue) + { + @event.SetTag(tuple.Value.name, tuple.Value.value); + } + + return @event; + } + private bool ShouldCaptureEvent( LogLevel logLevel, EventId eventId, diff --git a/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs b/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs index 787d11f120..0e1c01948c 100644 --- a/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs +++ b/test/Sentry.Extensions.Logging.Tests/SentryLoggerTests.cs @@ -98,6 +98,34 @@ public void Log_WithProperties_SetsTagsInEvent() e.Tags["fooEnum"] == "Absolute")); } + [Fact] + public void Culture_does_not_effect_tags() + { + var props = new List> + { + new("fooInteger", 12345), + new("fooDouble", 12345.123d), + new("fooFloat", 1234.123f), + }; + SentryEvent sentryEvent; + var culture = Thread.CurrentThread.CurrentCulture; + + try + { + Thread.CurrentThread.CurrentCulture = new("da-DK"); + sentryEvent = SentryLogger.CreateEvent(LogLevel.Debug, default, props, null, null, "category"); + } + finally + { + Thread.CurrentThread.CurrentCulture = culture; + } + + var tags = sentryEvent.Tags; + Assert.Equal("12345", tags["fooInteger"]); + Assert.Equal("12345.123", tags["fooDouble"]); + Assert.Equal("1234.123", tags["fooFloat"]); + } + [Fact] public void Log_WithEmptyGuidProperty_DoesntSetTagInEvent() {