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)" },
+ };
+ }
}