Skip to content

Commit 69678ce

Browse files
committed
ref(logs): allow out-of-range Log-Level
1 parent 2ae4476 commit 69678ce

File tree

4 files changed

+56
-61
lines changed

4 files changed

+56
-61
lines changed

src/Sentry/Extensibility/DiagnosticLoggerExtensions.cs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ internal static void LogDebug<TArg, TArg2>(
5858
TArg2 arg2)
5959
=> options.DiagnosticLogger?.LogIfEnabled(SentryLevel.Debug, null, message, arg, arg2);
6060

61+
/// <summary>
62+
/// Log a debug message.
63+
/// </summary>
64+
public static void LogDebug<TArg, TArg2, TArg3>(
65+
this IDiagnosticLogger logger,
66+
string message,
67+
TArg arg,
68+
TArg2 arg2,
69+
TArg3 arg3)
70+
=> logger.LogIfEnabled(SentryLevel.Debug, null, message, arg, arg2, arg3);
71+
6172
/// <summary>
6273
/// Log a debug message.
6374
/// </summary>
@@ -233,6 +244,17 @@ internal static void LogWarning<TArg, TArg2>(
233244
TArg2 arg2)
234245
=> options.DiagnosticLogger?.LogIfEnabled(SentryLevel.Warning, null, message, arg, arg2);
235246

247+
/// <summary>
248+
/// Log a warning message.
249+
/// </summary>
250+
public static void LogWarning<TArg, TArg2, TArg3>(
251+
this IDiagnosticLogger logger,
252+
string message,
253+
TArg arg,
254+
TArg2 arg2,
255+
TArg3 arg3)
256+
=> logger.LogIfEnabled(SentryLevel.Warning, null, message, arg, arg2, arg3);
257+
236258
/// <summary>
237259
/// Log a warning message.
238260
/// </summary>

src/Sentry/SentryLog.cs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ namespace Sentry;
1313
public sealed class SentryLog : ISentryJsonSerializable
1414
{
1515
private readonly Dictionary<string, SentryAttribute> _attributes;
16-
private readonly SentryLogLevel _level;
1716

1817
[SetsRequiredMembers]
1918
internal SentryLog(DateTimeOffset timestamp, SentryId traceId, SentryLogLevel level, string message)
@@ -47,15 +46,7 @@ internal SentryLog(DateTimeOffset timestamp, SentryId traceId, SentryLogLevel le
4746
/// <para>This API is experimental and it may change in the future.</para>
4847
/// </summary>
4948
[Experimental(DiagnosticId.ExperimentalFeature)]
50-
public required SentryLogLevel Level
51-
{
52-
get => _level;
53-
init
54-
{
55-
SentryLogLevelExtensions.ThrowIfOutOfRange(value);
56-
_level = value;
57-
}
58-
}
49+
public required SentryLogLevel Level { get; init; }
5950

6051
/// <summary>
6152
/// The formatted log message.
@@ -236,7 +227,7 @@ public void WriteTo(Utf8JsonWriter writer, IDiagnosticLogger? logger)
236227

237228
writer.WriteNumber("timestamp", Timestamp.ToUnixTimeSeconds());
238229

239-
var (severityText, severityNumber) = Level.ToSeverityTextAndOptionalSeverityNumber();
230+
var (severityText, severityNumber) = Level.ToSeverityTextAndOptionalSeverityNumber(logger);
240231
writer.WriteString("level", severityText);
241232

242233
writer.WriteString("body", Message);

src/Sentry/SentryLogLevel.cs

Lines changed: 10 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using Sentry.Extensibility;
12
using Sentry.Infrastructure;
23

34
namespace Sentry;
@@ -39,10 +40,11 @@ public enum SentryLogLevel
3940
[Experimental(DiagnosticId.ExperimentalFeature)]
4041
internal static class SentryLogLevelExtensions
4142
{
42-
internal static (string, int?) ToSeverityTextAndOptionalSeverityNumber(this SentryLogLevel level)
43+
internal static (string, int?) ToSeverityTextAndOptionalSeverityNumber(this SentryLogLevel level, IDiagnosticLogger? logger)
4344
{
4445
return (int)level switch
4546
{
47+
<= 0 => Underflow(level, logger),
4648
1 => ("trace", null),
4749
>= 2 and <= 4 => ("trace", (int)level),
4850
5 => ("debug", null),
@@ -55,27 +57,19 @@ internal static (string, int?) ToSeverityTextAndOptionalSeverityNumber(this Sent
5557
>= 18 and <= 20 => ("error", (int)level),
5658
21 => ("fatal", null),
5759
>= 22 and <= 24 => ("fatal", (int)level),
58-
_ => ThrowOutOfRange<(string, int?)>(level, nameof(level)),
60+
>= 25 => Overflow(level, logger),
5961
};
6062
}
6163

62-
internal static void ThrowIfOutOfRange(SentryLogLevel level, [CallerArgumentExpression(nameof(level))] string? paramName = null)
64+
private static (string, int?) Underflow(SentryLogLevel level, IDiagnosticLogger? logger)
6365
{
64-
if ((int)level is < 1 or > 24)
65-
{
66-
ThrowOutOfRange(level, paramName);
67-
}
68-
}
69-
70-
[DoesNotReturn]
71-
private static void ThrowOutOfRange(SentryLogLevel level, string? paramName)
72-
{
73-
throw new ArgumentOutOfRangeException(paramName, level, "Severity must be between 1 (inclusive) and 24 (inclusive).");
66+
logger?.LogDebug("Log level {0} out of range ... clamping to minimum value {1} ({2})", level, 1, "trace");
67+
return ("trace", 1);
7468
}
7569

76-
[DoesNotReturn]
77-
private static T ThrowOutOfRange<T>(SentryLogLevel level, string? paramName)
70+
private static (string, int?) Overflow(SentryLogLevel level, IDiagnosticLogger? logger)
7871
{
79-
throw new ArgumentOutOfRangeException(paramName, level, "Severity must be between 1 (inclusive) and 24 (inclusive).");
72+
logger?.LogDebug("Log level {0} out of range ... clamping to maximum value {1} ({2})", level, 24, "fatal");
73+
return ("fatal", 24);
8074
}
8175
}

test/Sentry.Tests/SentryLogLevelTests.cs

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -5,57 +5,45 @@ namespace Sentry.Tests;
55
/// </summary>
66
public class SentryLogLevelTests
77
{
8+
private readonly InMemoryDiagnosticLogger _logger;
9+
10+
public SentryLogLevelTests()
11+
{
12+
_logger = new InMemoryDiagnosticLogger();
13+
}
14+
815
[Theory]
916
[MemberData(nameof(SeverityTextAndSeverityNumber))]
1017
public void SeverityTextAndSeverityNumber_WithinRange_MatchesProtocol(int level, string text, int? number)
1118
{
1219
var @enum = (SentryLogLevel)level;
1320

14-
var (severityText, severityNumber) = @enum.ToSeverityTextAndOptionalSeverityNumber();
21+
var (severityText, severityNumber) = @enum.ToSeverityTextAndOptionalSeverityNumber(_logger);
1522

1623
Assert.Multiple(
1724
() => Assert.Equal(text, severityText),
1825
() => Assert.Equal(number, severityNumber));
26+
Assert.Empty(_logger.Entries);
1927
}
2028

2129
[Theory]
22-
[InlineData(0)]
23-
[InlineData(25)]
24-
public void SeverityTextAndSeverityNumber_OutOfRange_ThrowOutOfRange(int level)
30+
[InlineData(0, "trace", 1, "minimum")]
31+
[InlineData(25, "fatal", 24, "maximum")]
32+
public void SeverityTextAndSeverityNumber_OutOfRange_ClampValue(int level, string text, int? number, string clamp)
2533
{
2634
var @enum = (SentryLogLevel)level;
2735

28-
var exception = Assert.Throws<ArgumentOutOfRangeException>("level", () => @enum.ToSeverityTextAndOptionalSeverityNumber());
29-
Assert.StartsWith("Severity must be between 1 (inclusive) and 24 (inclusive).", exception.Message);
30-
Assert.Equal(level, (int)exception.ActualValue!);
31-
}
32-
33-
[Fact]
34-
public void ThrowOutOfRange_WithinRange_DoesNotThrow()
35-
{
36-
var range = Enumerable.Range(1, 24);
36+
var (severityText, severityNumber) = @enum.ToSeverityTextAndOptionalSeverityNumber(_logger);
3737

38-
var count = 0;
39-
foreach (var item in range)
40-
{
41-
var level = (SentryLogLevel)item;
42-
SentryLogLevelExtensions.ThrowIfOutOfRange(level);
43-
count++;
44-
}
45-
46-
Assert.Equal(24, count);
47-
}
48-
49-
[Theory]
50-
[InlineData(0)]
51-
[InlineData(25)]
52-
public void ThrowOutOfRange_OutOfRange_Throws(int level)
53-
{
54-
var @enum = (SentryLogLevel)level;
55-
56-
var exception = Assert.Throws<ArgumentOutOfRangeException>("@enum", () => SentryLogLevelExtensions.ThrowIfOutOfRange(@enum));
57-
Assert.StartsWith("Severity must be between 1 (inclusive) and 24 (inclusive).", exception.Message);
58-
Assert.Equal(level, (int)exception.ActualValue!);
38+
Assert.Multiple(
39+
() => Assert.Equal(text, severityText),
40+
() => Assert.Equal(number, severityNumber));
41+
var entry = Assert.Single(_logger.Entries);
42+
Assert.Multiple(
43+
() => Assert.Equal(SentryLevel.Debug, entry.Level),
44+
() => Assert.Equal($$"""Log level {0} out of range ... clamping to {{clamp}} value {1} ({2})""", entry.Message),
45+
() => Assert.Null(entry.Exception),
46+
() => Assert.Equal([@enum, number, text], entry.Args));
5947
}
6048

6149
public static TheoryData<int, string, int?> SeverityTextAndSeverityNumber()

0 commit comments

Comments
 (0)