diff --git a/src/Sentry.Serilog/SentrySerilogOptions.cs b/src/Sentry.Serilog/SentrySerilogOptions.cs
index 144d88d806..b06432736a 100644
--- a/src/Sentry.Serilog/SentrySerilogOptions.cs
+++ b/src/Sentry.Serilog/SentrySerilogOptions.cs
@@ -40,4 +40,16 @@ public class SentrySerilogOptions : SentryOptions
/// Optional
///
public ITextFormatter? TextFormatter { get; set; }
+
+ ///
+ /// The minimum level for events passed through the sink. Ignored when is specified.
+ ///
+ ///
+ public LogEventLevel RestrictedToMinimumLevel { get; set; } = LevelAlias.Minimum;
+
+ ///
+ /// A switch allowing the pass-through minimum level to be changed at runtime.
+ ///
+ ///
+ public LoggingLevelSwitch? LevelSwitch { get; set; }
}
diff --git a/src/Sentry.Serilog/SentrySinkExtensions.cs b/src/Sentry.Serilog/SentrySinkExtensions.cs
index 7a823c3d89..ea363b4c9e 100644
--- a/src/Sentry.Serilog/SentrySinkExtensions.cs
+++ b/src/Sentry.Serilog/SentrySinkExtensions.cs
@@ -36,6 +36,8 @@ public static class SentrySinkExtensions
/// What modes to use for event automatic de-duplication.
/// Default tags to add to all events.
/// Whether to send structured logs.
+ /// The minimum level for events passed through the sink. Ignored when is specified.
+ /// A switch allowing the pass-through minimum level to be changed at runtime.
///
/// This sample shows how each item may be set from within a configuration file:
///
@@ -106,7 +108,9 @@ public static LoggerConfiguration Sentry(
ReportAssembliesMode? reportAssembliesMode = null,
DeduplicateMode? deduplicateMode = null,
Dictionary? defaultTags = null,
- bool? enableLogs = null)
+ bool? enableLogs = null,
+ LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
+ LoggingLevelSwitch? levelSwitch = null)
{
return loggerConfiguration.Sentry(o => ConfigureSentrySerilogOptions(o,
dsn,
@@ -132,7 +136,9 @@ public static LoggerConfiguration Sentry(
reportAssembliesMode,
deduplicateMode,
defaultTags,
- enableLogs));
+ enableLogs,
+ restrictedToMinimumLevel,
+ levelSwitch));
}
///
@@ -147,6 +153,8 @@ public static LoggerConfiguration Sentry(
/// Minimum log level to record a breadcrumb.
/// The Serilog format provider.
/// The Serilog text formatter.
+ /// The minimum level for events passed through the sink. Ignored when is specified.
+ /// A switch allowing the pass-through minimum level to be changed at runtime.
///
/// This sample shows how each item may be set from within a configuration file:
///
@@ -174,15 +182,18 @@ public static LoggerConfiguration Sentry(
LogEventLevel? minimumEventLevel = null,
LogEventLevel? minimumBreadcrumbLevel = null,
IFormatProvider? formatProvider = null,
- ITextFormatter? textFormatter = null
- )
+ ITextFormatter? textFormatter = null,
+ LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
+ LoggingLevelSwitch? levelSwitch = null)
{
return loggerConfiguration.Sentry(o => ConfigureSentrySerilogOptions(o,
null,
minimumEventLevel,
minimumBreadcrumbLevel,
formatProvider,
- textFormatter));
+ textFormatter,
+ restrictedToMinimumLevel: restrictedToMinimumLevel,
+ levelSwitch: levelSwitch));
}
internal static void ConfigureSentrySerilogOptions(
@@ -210,7 +221,9 @@ internal static void ConfigureSentrySerilogOptions(
ReportAssembliesMode? reportAssembliesMode = null,
DeduplicateMode? deduplicateMode = null,
Dictionary? defaultTags = null,
- bool? enableLogs = null)
+ bool? enableLogs = null,
+ LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
+ LoggingLevelSwitch? levelSwitch = null)
{
if (dsn is not null)
{
@@ -327,6 +340,9 @@ internal static void ConfigureSentrySerilogOptions(
sentrySerilogOptions.EnableLogs = enableLogs.Value;
}
+ sentrySerilogOptions.RestrictedToMinimumLevel = restrictedToMinimumLevel;
+ sentrySerilogOptions.LevelSwitch = levelSwitch;
+
// Serilog-specific items
sentrySerilogOptions.InitializeSdk = dsn is not null; // Inferred from the Sentry overload that is used
if (defaultTags?.Count > 0)
@@ -364,6 +380,6 @@ public static LoggerConfiguration Sentry(
sdkDisposable = SentrySdk.Init(options);
}
- return loggerConfiguration.Sink(new SentrySink(options, sdkDisposable));
+ return loggerConfiguration.Sink(new SentrySink(options, sdkDisposable), options.RestrictedToMinimumLevel, options.LevelSwitch);
}
}
diff --git a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt
index bb2d777e40..6374c53e3e 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt
@@ -11,8 +11,10 @@ namespace Sentry.Serilog
public SentrySerilogOptions() { }
public System.IFormatProvider? FormatProvider { get; set; }
public bool InitializeSdk { get; set; }
+ public Serilog.Core.LoggingLevelSwitch? LevelSwitch { get; set; }
public Serilog.Events.LogEventLevel MinimumBreadcrumbLevel { get; set; }
public Serilog.Events.LogEventLevel MinimumEventLevel { get; set; }
+ public Serilog.Events.LogEventLevel RestrictedToMinimumLevel { get; set; }
public Serilog.Formatting.ITextFormatter? TextFormatter { get; set; }
}
}
@@ -21,7 +23,7 @@ namespace Serilog
public static class SentrySinkExtensions
{
public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, System.Action configureOptions) { }
- public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null) { }
+ public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
public static Serilog.LoggerConfiguration Sentry(
this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
string dsn,
@@ -47,6 +49,8 @@ namespace Serilog
Sentry.ReportAssembliesMode? reportAssembliesMode = default,
Sentry.DeduplicateMode? deduplicateMode = default,
System.Collections.Generic.Dictionary? defaultTags = null,
- bool? enableLogs = default) { }
+ bool? enableLogs = default,
+ Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0,
+ Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
}
}
\ No newline at end of file
diff --git a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
index bb2d777e40..6374c53e3e 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
@@ -11,8 +11,10 @@ namespace Sentry.Serilog
public SentrySerilogOptions() { }
public System.IFormatProvider? FormatProvider { get; set; }
public bool InitializeSdk { get; set; }
+ public Serilog.Core.LoggingLevelSwitch? LevelSwitch { get; set; }
public Serilog.Events.LogEventLevel MinimumBreadcrumbLevel { get; set; }
public Serilog.Events.LogEventLevel MinimumEventLevel { get; set; }
+ public Serilog.Events.LogEventLevel RestrictedToMinimumLevel { get; set; }
public Serilog.Formatting.ITextFormatter? TextFormatter { get; set; }
}
}
@@ -21,7 +23,7 @@ namespace Serilog
public static class SentrySinkExtensions
{
public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, System.Action configureOptions) { }
- public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null) { }
+ public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
public static Serilog.LoggerConfiguration Sentry(
this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
string dsn,
@@ -47,6 +49,8 @@ namespace Serilog
Sentry.ReportAssembliesMode? reportAssembliesMode = default,
Sentry.DeduplicateMode? deduplicateMode = default,
System.Collections.Generic.Dictionary? defaultTags = null,
- bool? enableLogs = default) { }
+ bool? enableLogs = default,
+ Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0,
+ Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
}
}
\ No newline at end of file
diff --git a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
index bb2d777e40..6374c53e3e 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
@@ -11,8 +11,10 @@ namespace Sentry.Serilog
public SentrySerilogOptions() { }
public System.IFormatProvider? FormatProvider { get; set; }
public bool InitializeSdk { get; set; }
+ public Serilog.Core.LoggingLevelSwitch? LevelSwitch { get; set; }
public Serilog.Events.LogEventLevel MinimumBreadcrumbLevel { get; set; }
public Serilog.Events.LogEventLevel MinimumEventLevel { get; set; }
+ public Serilog.Events.LogEventLevel RestrictedToMinimumLevel { get; set; }
public Serilog.Formatting.ITextFormatter? TextFormatter { get; set; }
}
}
@@ -21,7 +23,7 @@ namespace Serilog
public static class SentrySinkExtensions
{
public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, System.Action configureOptions) { }
- public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null) { }
+ public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
public static Serilog.LoggerConfiguration Sentry(
this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
string dsn,
@@ -47,6 +49,8 @@ namespace Serilog
Sentry.ReportAssembliesMode? reportAssembliesMode = default,
Sentry.DeduplicateMode? deduplicateMode = default,
System.Collections.Generic.Dictionary? defaultTags = null,
- bool? enableLogs = default) { }
+ bool? enableLogs = default,
+ Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0,
+ Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
}
}
\ No newline at end of file
diff --git a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt
index bb2d777e40..6374c53e3e 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt
@@ -11,8 +11,10 @@ namespace Sentry.Serilog
public SentrySerilogOptions() { }
public System.IFormatProvider? FormatProvider { get; set; }
public bool InitializeSdk { get; set; }
+ public Serilog.Core.LoggingLevelSwitch? LevelSwitch { get; set; }
public Serilog.Events.LogEventLevel MinimumBreadcrumbLevel { get; set; }
public Serilog.Events.LogEventLevel MinimumEventLevel { get; set; }
+ public Serilog.Events.LogEventLevel RestrictedToMinimumLevel { get; set; }
public Serilog.Formatting.ITextFormatter? TextFormatter { get; set; }
}
}
@@ -21,7 +23,7 @@ namespace Serilog
public static class SentrySinkExtensions
{
public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, System.Action configureOptions) { }
- public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null) { }
+ public static Serilog.LoggerConfiguration Sentry(this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration, Serilog.Events.LogEventLevel? minimumEventLevel = default, Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default, System.IFormatProvider? formatProvider = null, Serilog.Formatting.ITextFormatter? textFormatter = null, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
public static Serilog.LoggerConfiguration Sentry(
this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
string dsn,
@@ -47,6 +49,8 @@ namespace Serilog
Sentry.ReportAssembliesMode? reportAssembliesMode = default,
Sentry.DeduplicateMode? deduplicateMode = default,
System.Collections.Generic.Dictionary? defaultTags = null,
- bool? enableLogs = default) { }
+ bool? enableLogs = default,
+ Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0,
+ Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
}
}
\ No newline at end of file
diff --git a/test/Sentry.Serilog.Tests/Sentry.Serilog.Tests.csproj b/test/Sentry.Serilog.Tests/Sentry.Serilog.Tests.csproj
index ea7b7b84c3..21bfce809c 100644
--- a/test/Sentry.Serilog.Tests/Sentry.Serilog.Tests.csproj
+++ b/test/Sentry.Serilog.Tests/Sentry.Serilog.Tests.csproj
@@ -14,6 +14,7 @@
+
diff --git a/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs b/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
index 36c3f1f802..d146bb87ed 100644
--- a/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
+++ b/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
@@ -29,6 +29,8 @@ private class Fixture
public bool InitializeSdk { get; } = false;
public LogEventLevel MinimumEventLevel { get; } = LogEventLevel.Verbose;
public LogEventLevel MinimumBreadcrumbLevel { get; } = LogEventLevel.Fatal;
+ public LogEventLevel RestrictedToMinimumLevel { get; } = LogEventLevel.Warning;
+ public LoggingLevelSwitch LevelSwitch { get; } = new(LogEventLevel.Error);
public static SentrySerilogOptions GetSut() => new();
}
@@ -98,7 +100,8 @@ public void ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChan
_fixture.SampleRate, _fixture.Release, _fixture.Environment, _fixture.MaxQueueItems,
_fixture.ShutdownTimeout, _fixture.DecompressionMethods, _fixture.RequestBodyCompressionLevel,
_fixture.RequestBodyCompressionBuffered, _fixture.Debug, _fixture.DiagnosticLevel,
- _fixture.ReportAssembliesMode, _fixture.DeduplicateMode, null, _fixture.EnableLogs);
+ _fixture.ReportAssembliesMode, _fixture.DeduplicateMode, null, _fixture.EnableLogs,
+ _fixture.RestrictedToMinimumLevel, _fixture.LevelSwitch);
// Compare individual properties
Assert.Equal(_fixture.SendDefaultPii, sut.SendDefaultPii);
@@ -123,6 +126,52 @@ public void ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChan
Assert.True(sut.InitializeSdk);
Assert.Equal(_fixture.MinimumEventLevel, sut.MinimumEventLevel);
Assert.Equal(_fixture.MinimumBreadcrumbLevel, sut.MinimumBreadcrumbLevel);
+ Assert.Equal(_fixture.RestrictedToMinimumLevel, sut.RestrictedToMinimumLevel);
+ Assert.Same(_fixture.LevelSwitch, sut.LevelSwitch);
+ }
+
+ [Fact]
+ public void Sentry_WithRestrictedToMinimumLevel_ConfigureOptions_FiltersLogsBelow()
+ {
+ // Arrange
+ var hub = Substitute.For();
+ hub.IsEnabled.Returns(true);
+ var options = new SentrySerilogOptions
+ {
+ InitializeSdk = false,
+ MinimumBreadcrumbLevel = LogEventLevel.Verbose,
+ MinimumEventLevel = LogEventLevel.Verbose,
+ RestrictedToMinimumLevel = LogEventLevel.Error,
+ };
+ var sink = new SentrySink(options, () => hub, null, new MockClock());
+ using var logger = new LoggerConfiguration()
+ .MinimumLevel.Verbose()
+ .WriteTo.Sink(sink, options.RestrictedToMinimumLevel, options.LevelSwitch)
+ .CreateLogger();
+
+ // Act
+ logger.Warning("Below threshold");
+ logger.Error("At threshold");
+
+ // Assert: Warning is filtered by Serilog before reaching the sink; only Error gets through
+ hub.Received(1).CaptureEvent(Arg.Any());
+ hub.DidNotReceive().CaptureEvent(Arg.Is(e =>
+ e.Message.Message == "Below threshold"));
+ }
+
+ [Fact]
+ public void Sentry_WithRestrictedToMinimumLevel_NoDsn_ParameterIsAccepted()
+ {
+ // Verify the no-DSN overload accepts restrictedToMinimumLevel without throwing
+ var ex = Record.Exception(() =>
+ new LoggerConfiguration()
+ .WriteTo.Sentry(
+ minimumBreadcrumbLevel: LogEventLevel.Verbose,
+ minimumEventLevel: LogEventLevel.Error,
+ restrictedToMinimumLevel: LogEventLevel.Warning)
+ .CreateLogger());
+
+ Assert.Null(ex);
}
private static void AssertEqualDeep(object expected, object actual)