diff --git a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs index 90f6df853a..17d1cfe99f 100644 --- a/src/Sentry/Internal/DefaultSentryStructuredLogger.cs +++ b/src/Sentry/Internal/DefaultSentryStructuredLogger.cs @@ -71,7 +71,12 @@ private protected override void CaptureLog(SentryLogLevel level, string template var scope = _hub.GetScope(); log.SetDefaultAttributes(_options, scope?.Sdk ?? SdkVersion.Instance); - CaptureLog(log); + var captured = CaptureLog(log); + + if (captured && _options.Debug) + { + WriteToConsole(log); + } } /// @@ -109,4 +114,19 @@ public void Dispose() { _batchProcessor.Dispose(); } + + private static void WriteToConsole(SentryLog log) + { + Debug.Assert(!log.TryGetAttribute("sentry.origin", out string? origin), $"Logs should only be printed to the Console when captured via the Sentry Logger APIs and not through any integration: {origin}"); + + var capacity = 10 + 2 + log.Message.Length; + var text = new StringBuilder(capacity); + text.Append(log.Level.ToText().PadLeft(10)); + text.Append(": "); + text.Append(log.Message); + + Debug.Assert(text.Length == capacity, $"Wrong assumption of capacity: Expected: {capacity}; Actual: {text.Length}"); + + Console.WriteLine(text.ToString()); + } } diff --git a/src/Sentry/SentryLogLevel.cs b/src/Sentry/SentryLogLevel.cs index f76a617571..9a55f72a9e 100644 --- a/src/Sentry/SentryLogLevel.cs +++ b/src/Sentry/SentryLogLevel.cs @@ -128,4 +128,25 @@ static SentryLogLevel Overflow(int value, IDiagnosticLogger? logger) return SentryLogLevel.Fatal; } } + + internal static string ToText(this SentryLogLevel level) + { + return (int)level switch + { + <= 0 => "trace(<1)", + 1 => "trace", + >= 2 and <= 4 => $"trace({(int)level})", + 5 => "debug", + >= 6 and <= 8 => $"debug({(int)level})", + 9 => "info", + >= 10 and <= 12 => $"info({(int)level})", + 13 => "warn", + >= 14 and <= 16 => $"warn({(int)level})", + 17 => "error", + >= 18 and <= 20 => $"error({(int)level})", + 21 => "fatal", + >= 22 and <= 24 => $"fatal({(int)level})", + >= 25 => "fatal(>24)", + }; + } } diff --git a/test/Sentry.Tests/SentryLogLevelTests.cs b/test/Sentry.Tests/SentryLogLevelTests.cs index 36b557ea08..471a0b0573 100644 --- a/test/Sentry.Tests/SentryLogLevelTests.cs +++ b/test/Sentry.Tests/SentryLogLevelTests.cs @@ -149,4 +149,48 @@ public static TheoryData Create() { 24, SentryLogLevel.Fatal }, }; } + + [Theory] + [MemberData(nameof(Convert))] + public void Convert_FromSentryLogLevel_ToString(int level, string expected) + { + var @enum = (SentryLogLevel)level; + + var actual = @enum.ToText(); + + Assert.Equal(expected, actual); + } + + public static TheoryData Convert() + { + return new TheoryData + { + { 0, "trace(<1)" }, + { 1, "trace" }, + { 2, "trace(2)" }, + { 3, "trace(3)" }, + { 4, "trace(4)" }, + { 5, "debug" }, + { 6, "debug(6)" }, + { 7, "debug(7)" }, + { 8, "debug(8)" }, + { 9, "info" }, + { 10, "info(10)" }, + { 11, "info(11)" }, + { 12, "info(12)" }, + { 13, "warn" }, + { 14, "warn(14)" }, + { 15, "warn(15)" }, + { 16, "warn(16)" }, + { 17, "error" }, + { 18, "error(18)" }, + { 19, "error(19)" }, + { 20, "error(20)" }, + { 21, "fatal" }, + { 22, "fatal(22)" }, + { 23, "fatal(23)" }, + { 24, "fatal(24)" }, + { 25, "fatal(>24)" }, + }; + } }