diff --git a/samples/Sentry.Samples.AspNetCore.Serilog/Program.cs b/samples/Sentry.Samples.AspNetCore.Serilog/Program.cs
index 65d3d64732..ff974a903f 100644
--- a/samples/Sentry.Samples.AspNetCore.Serilog/Program.cs
+++ b/samples/Sentry.Samples.AspNetCore.Serilog/Program.cs
@@ -1,3 +1,4 @@
+using Sentry.Serilog;
using Serilog;
using Serilog.Events;
@@ -14,28 +15,28 @@ public static WebApplication BuildWebApp(string[] args)
c.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.Console()
- // Add Sentry integration with Serilog
+ // Configure Serilog to send logs to Sentry. This only configures the sink - Sentry is initialised below.
.WriteTo.Sentry(s =>
{
// Sets the minimum log level required to add a log message as breadcrumb
s.MinimumBreadcrumbLevel = LogEventLevel.Debug;
// Set the minimum level for messages to be sent out as events to Sentry
s.MinimumEventLevel = LogEventLevel.Error;
- // When configuring Sentry's Serilog integration in combination with other integrations that
- // initialize the Sentry SDK (like ASP.NET Core or MAUI) we need to tell it not to reinitialize
- // Sentry... we just want it to set up the Serilog sink
- s.InitializeSdk = false;
}));
- // Add Sentry integration
- // It can be defined via configuration (including `appsettings.json`)
- // or coded explicitly, via parameter like:
- // .UseSentry("dsn") or .UseSentry(o => o.Dsn = ""; o.Release = "1.0"; ...)
+ // Add the Sentry integration.
+ // Most options can be defined via binding configuration (including `appsettings.json` as we do here)
+ // or coded explicitly, in the options callback below (as we do with the DSN and Serilog log context)
+ builder.WebHost.UseSentry(o =>
+ {
#if !SENTRY_DSN_DEFINED_IN_ENV
- builder.WebHost.UseSentry(SamplesShared.Dsn);
+ o.Dsn = SamplesShared.Dsn;
#else
- builder.WebHost.UseSentry(EnvironmentVariables.Dsn);
+ o.Dsn = EnvironmentVariables.Dsn;
#endif
+ // Apply properties from the Serilog LogContext to Sentry events
+ o.UseSerilog();
+ });
// The App:
var webApplication = builder.Build();
diff --git a/samples/Sentry.Samples.Serilog/Program.cs b/samples/Sentry.Samples.Serilog/Program.cs
index 59ed09548d..b4c0075c56 100644
--- a/samples/Sentry.Samples.Serilog/Program.cs
+++ b/samples/Sentry.Samples.Serilog/Program.cs
@@ -1,3 +1,4 @@
+using Sentry.Serilog;
using Serilog;
using Serilog.Context;
using Serilog.Events;
@@ -7,29 +8,35 @@ internal static class Program
{
private static void Main()
{
+ // Initialise Sentry SDK itself
+ using var _ = SentrySdk.Init(options =>
+ {
+#if !SENTRY_DSN_DEFINED_IN_ENV
+ // A DSN is required. You can set here in code, or you can set it in the SENTRY_DSN environment variable.
+ // See https://docs.sentry.io/product/sentry-basics/dsn-explainer/
+ options.Dsn = SamplesShared.Dsn;
+#endif
+
+ options.AttachStacktrace = true;
+ // send PII like the username of the user logged in to the device
+ options.SendDefaultPii = true;
+ // Apply properties from the Serilog LogContext (like MyTaskId below) to Sentry events
+ options.UseSerilog();
+ });
+
Log.Logger = new LoggerConfiguration()
.Enrich.FromLogContext()
.MinimumLevel.Debug()
.WriteTo.Console()
- // Other overloads exist, for example, configure the SDK with only the DSN or no parameters at all.
+ // Configure Serilog to send logs to Sentry
.WriteTo.Sentry(options =>
{
-#if !SENTRY_DSN_DEFINED_IN_ENV
- // A DSN is required. You can set here in code, or you can set it in the SENTRY_DSN environment variable.
- // See https://docs.sentry.io/product/sentry-basics/dsn-explainer/
- options.Dsn = SamplesShared.Dsn;
-#endif
-
// Debug and higher are stored as breadcrumbs (default os Information)
options.MinimumBreadcrumbLevel = LogEventLevel.Debug;
- // Error and higher is sent as event (default is Error)
+ // Error and higher are sent as events (default is Error)
options.MinimumEventLevel = LogEventLevel.Error;
- options.AttachStacktrace = true;
- // send PII like the username of the user logged in to the device
- options.SendDefaultPii = true;
// Optional Serilog text formatter used to format LogEvent to string. If TextFormatter is set, FormatProvider is ignored.
options.TextFormatter = new MessageTemplateTextFormatter("[{MyTaskId}] {Message}");
- // Other configuration
})
.CreateLogger();
diff --git a/src/Sentry.Serilog/SentryOptionExtensions.cs b/src/Sentry.Serilog/SentryOptionExtensions.cs
index 94dfbc5212..662ef30b87 100644
--- a/src/Sentry.Serilog/SentryOptionExtensions.cs
+++ b/src/Sentry.Serilog/SentryOptionExtensions.cs
@@ -6,16 +6,25 @@ namespace Sentry.Serilog;
public static class SentryOptionExtensions
{
///
- /// Ensures Serilog scope properties get applied to Sentry events. If you are not initialising Sentry when
- /// configuring the Sentry sink for Serilog then you should call this method in the options callback for whichever
- /// Sentry integration you are using to initialise Sentry.
+ /// Enables the Serilog integration, so that properties from the Serilog LogContext get applied to all Sentry
+ /// events.
///
- ///
- ///
- ///
- public static T ApplySerilogScopeToEvents(this T options) where T : SentryOptions
+ ///
+ /// Call this in the options callback of whichever method you use to initialise Sentry (for example
+ /// SentrySdk.Init or UseSentry). The Sentry sink for Serilog does not initialise Sentry, so it cannot
+ /// do this for you. Calling this more than once has no additional effect.
+ ///
+ /// The options used to initialise Sentry.
+ public static void UseSerilog(this SentryOptions options)
{
+ if (options.HasSerilogScopeEventProcessor())
+ {
+ return;
+ }
+
options.AddEventProcessor(new SerilogScopeEventProcessor(options));
- return options;
}
+
+ internal static bool HasSerilogScopeEventProcessor(this SentryOptions options)
+ => options.EventProcessors.Exists(processor => processor.Type == typeof(SerilogScopeEventProcessor));
}
diff --git a/src/Sentry.Serilog/SentrySerilogOptions.cs b/src/Sentry.Serilog/SentrySerilogOptions.cs
index b06432736a..65a4ee544a 100644
--- a/src/Sentry.Serilog/SentrySerilogOptions.cs
+++ b/src/Sentry.Serilog/SentrySerilogOptions.cs
@@ -1,16 +1,14 @@
namespace Sentry.Serilog;
///
-/// Sentry Options for Serilog logging
+/// Options for the Sentry sink for Serilog.
///
-///
-public class SentrySerilogOptions : SentryOptions
+///
+/// These options only configure the sink. The Sentry SDK itself is configured and initialised separately, using
+/// SentrySdk.Init or another Sentry integration (such as ASP.NET Core or MAUI).
+///
+public class SentrySerilogOptions
{
- ///
- /// Whether to initialize this SDK through this integration
- ///
- public bool InitializeSdk { get; set; } = true;
-
///
/// Minimum log level to send an event.
///
diff --git a/src/Sentry.Serilog/SentrySink.cs b/src/Sentry.Serilog/SentrySink.cs
index 9ce57c691b..bfd406045b 100644
--- a/src/Sentry.Serilog/SentrySink.cs
+++ b/src/Sentry.Serilog/SentrySink.cs
@@ -3,11 +3,9 @@ namespace Sentry.Serilog;
///
/// Sentry Sink for Serilog
///
-///
///
-internal sealed partial class SentrySink : ILogEventSink, IDisposable
+internal sealed partial class SentrySink : ILogEventSink
{
- private readonly IDisposable? _sdkDisposable;
private readonly SentrySerilogOptions _options;
internal static readonly SdkVersion NameAndVersion
@@ -29,13 +27,12 @@ internal static readonly SdkVersion NameAndVersion
private readonly Func _hubAccessor;
private readonly ISystemClock _clock;
- public SentrySink(
- SentrySerilogOptions options,
- IDisposable? sdkDisposable)
+ private volatile bool _checkedUseSerilog;
+
+ public SentrySink(SentrySerilogOptions options)
: this(
options,
() => HubAdapter.Instance,
- sdkDisposable,
SystemClock.Clock)
{
}
@@ -43,13 +40,11 @@ public SentrySink(
internal SentrySink(
SentrySerilogOptions options,
Func hubAccessor,
- IDisposable? sdkDisposable,
ISystemClock clock)
{
_options = options;
_hubAccessor = hubAccessor;
_clock = clock;
- _sdkDisposable = sdkDisposable;
}
private static AsyncLocal isReentrant = new();
@@ -58,7 +53,7 @@ public void Emit(LogEvent logEvent)
{
if (isReentrant.Value)
{
- _options.DiagnosticLogger?.LogError($"Reentrant log event detected. Logging when inside the scope of another log event can cause a StackOverflowException. LogEventInfo.Message: {logEvent.MessageTemplate.Text}");
+ _hubAccessor()?.GetSentryOptions()?.DiagnosticLogger?.LogError($"Reentrant log event detected. Logging when inside the scope of another log event can cause a StackOverflowException. LogEventInfo.Message: {logEvent.MessageTemplate.Text}");
return;
}
@@ -88,6 +83,12 @@ private void InnerEmit(LogEvent logEvent)
return;
}
+ var options = hub.GetSentryOptions();
+ if (options is not null)
+ {
+ WarnIfUseSerilogNotCalled(options);
+ }
+
var exception = logEvent.Exception;
var template = logEvent.MessageTemplate.Text;
var formatted = FormatLogEvent(logEvent);
@@ -151,16 +152,28 @@ private void InnerEmit(LogEvent logEvent)
level: logEvent.Level.ToBreadcrumbLevel());
}
- // Read the options from the Hub, rather than the Sink's Serilog-Options. In cases where Sentry's Serilog-Sink is
- // added without a DSN (i.e., without initializing the SDK) and the SDK is initialized differently (e.g., through
- // ASP.NET Core), only the Hub's Sentry-Options have the actual user-defined values configured.
- var options = hub.GetSentryOptions();
if (options is not null)
{
CaptureStructuredLog(hub, options, logEvent, formatted, template);
}
}
+ private void WarnIfUseSerilogNotCalled(SentryOptions options)
+ {
+ if (_checkedUseSerilog)
+ {
+ return;
+ }
+
+ _checkedUseSerilog = true;
+ if (!options.HasSerilogScopeEventProcessor())
+ {
+ options.LogWarning(
+ "The Sentry sink for Serilog is in use, but UseSerilog() was not called on the options used to initialise Sentry. " +
+ "Properties from the Serilog LogContext will not be applied to Sentry events.");
+ }
+ }
+
private string FormatLogEvent(LogEvent logEvent)
{
if (_options.TextFormatter is { } formatter)
@@ -188,6 +201,4 @@ private string FormatLogEvent(LogEvent logEvent)
}
}
}
-
- public void Dispose() => _sdkDisposable?.Dispose();
}
diff --git a/src/Sentry.Serilog/SentrySinkExtensions.cs b/src/Sentry.Serilog/SentrySinkExtensions.cs
index 7c164ac6b4..d35e247cf2 100644
--- a/src/Sentry.Serilog/SentrySinkExtensions.cs
+++ b/src/Sentry.Serilog/SentrySinkExtensions.cs
@@ -8,143 +8,12 @@ namespace Serilog;
[EditorBrowsable(EditorBrowsableState.Never)]
public static class SentrySinkExtensions
{
- ///
- /// Initialize Sentry and add the SentrySink for Serilog.
- ///
- /// The logger configuration .
- /// The Sentry DSN (required).
- /// Minimum log level to record a breadcrumb.
- /// Minimum log level to send an event.
- /// The Serilog format provider.
- /// The Serilog text formatter.
- /// Whether to include default Personal Identifiable information.
- /// Whether to report the as the User affected in the event.
- /// Gets or sets the name of the server running the application.
- /// Whether to send the stack trace of a event captured without an exception.
- /// Gets or sets the maximum breadcrumbs.
- /// The rate to sample events.
- /// The release version of the application.
- /// The environment the application is running.
- /// The maximum number of events to keep while the worker attempts to send them.
- /// How long to wait for events to be sent before shutdown.
- /// Decompression methods accepted.
- /// The level of which to compress the before sending to Sentry.
- /// Whether the body compression is buffered and the request 'Content-Length' known in advance.
- /// Whether to log diagnostics messages.
- /// The diagnostics level to be used.
- /// What mode to use for reporting referenced assemblies in each event sent to sentry. Defaults to
- /// What modes to use for event automatic de-duplication.
- /// Default tags to add to all events.
- /// Ignored. Structured logs are always sent. To drop logs, use and return .
- /// 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:
- ///
- /// {
- /// "Serilog": {
- /// "Using": [
- /// "Serilog",
- /// "Sentry",
- /// ],
- /// "WriteTo": [{
- /// "Name": "Sentry",
- /// "Args": {
- /// "dsn": "https://MY-DSN@sentry.io",
- /// "minimumBreadcrumbLevel": "Verbose",
- /// "minimumEventLevel": "Error",
- /// "outputTemplate": "{Timestamp:o} [{Level:u3}] ({Application}/{MachineName}/{ThreadId}) {Message}{NewLine}{Exception}",
- /// "sendDefaultPii": false,
- /// "isEnvironmentUser": false,
- /// "serverName": "MyServerName",
- /// "attachStackTrace": false,
- /// "maxBreadcrumbs": 20,
- /// "sampleRate": 0.5,
- /// "release": "0.0.1",
- /// "environment": "staging",
- /// "maxQueueItems": 100,
- /// "shutdownTimeout": "00:00:05",
- /// "decompressionMethods": "GZip",
- /// "requestBodyCompressionLevel": "NoCompression",
- /// "requestBodyCompressionBuffered": false,
- /// "debug": false,
- /// "diagnosticLevel": "Debug",
- /// "reportAssembliesMode": ReportAssembliesMode.None,
- /// "deduplicateMode": "All",
- /// "defaultTags": {
- /// "key-1", "value-1",
- /// "key-2", "value-2"
- /// }
- /// }
- /// }
- /// ]
- /// }
- /// }
- ///
- ///
- public static LoggerConfiguration Sentry(
- this LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- LogEventLevel? minimumBreadcrumbLevel = null,
- LogEventLevel? minimumEventLevel = null,
- IFormatProvider? formatProvider = null,
- ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = null,
- bool? isEnvironmentUser = null,
- string? serverName = null,
- bool? attachStackTrace = null,
- int? maxBreadcrumbs = null,
- float? sampleRate = null,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = null,
- TimeSpan? shutdownTimeout = null,
- DecompressionMethods? decompressionMethods = null,
- CompressionLevel? requestBodyCompressionLevel = null,
- bool? requestBodyCompressionBuffered = null,
- bool? debug = null,
- SentryLevel? diagnosticLevel = null,
- ReportAssembliesMode? reportAssembliesMode = null,
- DeduplicateMode? deduplicateMode = null,
- Dictionary? defaultTags = null,
- bool? enableLogs = null,
- LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
- LoggingLevelSwitch? levelSwitch = null)
- {
- return loggerConfiguration.Sentry(o => ConfigureSentrySerilogOptions(o,
- dsn,
- minimumEventLevel,
- minimumBreadcrumbLevel,
- formatProvider,
- textFormatter,
- sendDefaultPii,
- isEnvironmentUser,
- serverName,
- attachStackTrace,
- maxBreadcrumbs,
- sampleRate,
- release,
- environment,
- maxQueueItems,
- shutdownTimeout,
- decompressionMethods,
- requestBodyCompressionLevel,
- requestBodyCompressionBuffered,
- debug,
- diagnosticLevel,
- reportAssembliesMode,
- deduplicateMode,
- defaultTags,
- enableLogs,
- restrictedToMinimumLevel,
- levelSwitch));
- }
-
///
/// Adds a Sentry Sink for Serilog.
///
- /// Note this overload doesn't initialize Sentry for you, so you'll need to have already done so. Alternatively you
- /// can use use the overload of this extension method, passing a DSN string in the first argument.
+ /// This doesn't initialise Sentry. Initialise Sentry separately, using SentrySdk.Init or another Sentry
+ /// integration (such as ASP.NET Core or MAUI), and call on the
+ /// options used to do so.
///
///
/// The logger configuration .
@@ -186,49 +55,23 @@ public static LoggerConfiguration Sentry(
LoggingLevelSwitch? levelSwitch = null)
{
return loggerConfiguration.Sentry(o => ConfigureSentrySerilogOptions(o,
- null,
minimumEventLevel,
minimumBreadcrumbLevel,
formatProvider,
textFormatter,
- restrictedToMinimumLevel: restrictedToMinimumLevel,
- levelSwitch: levelSwitch));
+ restrictedToMinimumLevel,
+ levelSwitch));
}
internal static void ConfigureSentrySerilogOptions(
SentrySerilogOptions sentrySerilogOptions,
- string? dsn,
LogEventLevel? minimumEventLevel = null,
LogEventLevel? minimumBreadcrumbLevel = null,
IFormatProvider? formatProvider = null,
ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = null,
- bool? isEnvironmentUser = null,
- string? serverName = null,
- bool? attachStackTrace = null,
- int? maxBreadcrumbs = null,
- float? sampleRate = null,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = null,
- TimeSpan? shutdownTimeout = null,
- DecompressionMethods? decompressionMethods = null,
- CompressionLevel? requestBodyCompressionLevel = null,
- bool? requestBodyCompressionBuffered = null,
- bool? debug = null,
- SentryLevel? diagnosticLevel = null,
- ReportAssembliesMode? reportAssembliesMode = null,
- DeduplicateMode? deduplicateMode = null,
- Dictionary? defaultTags = null,
- bool? enableLogs = null,
LogEventLevel restrictedToMinimumLevel = LevelAlias.Minimum,
LoggingLevelSwitch? levelSwitch = null)
{
- if (dsn is not null)
- {
- sentrySerilogOptions.Dsn = dsn;
- }
-
if (minimumEventLevel.HasValue)
{
sentrySerilogOptions.MinimumEventLevel = minimumEventLevel.Value;
@@ -249,115 +92,17 @@ internal static void ConfigureSentrySerilogOptions(
sentrySerilogOptions.TextFormatter = textFormatter;
}
- if (sendDefaultPii.HasValue)
- {
- sentrySerilogOptions.SendDefaultPii = sendDefaultPii.Value;
- }
-
- if (isEnvironmentUser.HasValue)
- {
- sentrySerilogOptions.IsEnvironmentUser = isEnvironmentUser.Value;
- }
-
- if (!string.IsNullOrWhiteSpace(serverName))
- {
- sentrySerilogOptions.ServerName = serverName;
- }
-
- if (attachStackTrace.HasValue)
- {
- sentrySerilogOptions.AttachStacktrace = attachStackTrace.Value;
- }
-
- if (maxBreadcrumbs.HasValue)
- {
- sentrySerilogOptions.MaxBreadcrumbs = maxBreadcrumbs.Value;
- }
-
- if (sampleRate.HasValue)
- {
- sentrySerilogOptions.SampleRate = sampleRate;
- }
-
- if (!string.IsNullOrWhiteSpace(release))
- {
- sentrySerilogOptions.Release = release;
- }
-
- if (!string.IsNullOrWhiteSpace(environment))
- {
- sentrySerilogOptions.Environment = environment;
- }
-
- if (maxQueueItems.HasValue)
- {
- sentrySerilogOptions.MaxQueueItems = maxQueueItems.Value;
- }
-
- if (shutdownTimeout.HasValue)
- {
- sentrySerilogOptions.ShutdownTimeout = shutdownTimeout.Value;
- }
-
- if (decompressionMethods.HasValue)
- {
- sentrySerilogOptions.DecompressionMethods = decompressionMethods.Value;
- }
-
- if (requestBodyCompressionLevel.HasValue)
- {
- sentrySerilogOptions.RequestBodyCompressionLevel = requestBodyCompressionLevel.Value;
- }
-
- if (requestBodyCompressionBuffered.HasValue)
- {
- sentrySerilogOptions.RequestBodyCompressionBuffered = requestBodyCompressionBuffered.Value;
- }
-
- if (debug.HasValue)
- {
- sentrySerilogOptions.Debug = debug.Value;
- }
-
- if (diagnosticLevel.HasValue)
- {
- sentrySerilogOptions.DiagnosticLevel = diagnosticLevel.Value;
- }
-
- if (reportAssembliesMode.HasValue)
- {
- sentrySerilogOptions.ReportAssembliesMode = reportAssembliesMode.Value;
- }
-
- if (deduplicateMode.HasValue)
- {
- sentrySerilogOptions.DeduplicateMode = deduplicateMode.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)
- {
- foreach (var tag in defaultTags)
- {
- sentrySerilogOptions.DefaultTags.Add(tag.Key, tag.Value);
- }
- }
-
- // This only works when the SDK is initialized using the LoggerSinkConfiguration extensions. If the SDK is
- // initialized using some other integration then the processor will need to be added manually to whichever
- // options are used to initialize the SDK.
- if (sentrySerilogOptions.InitializeSdk)
- {
- sentrySerilogOptions.ApplySerilogScopeToEvents();
- }
}
///
- /// Add Sentry sink to Serilog.
+ /// Adds a Sentry Sink for Serilog.
+ ///
+ /// This doesn't initialise Sentry. Initialise Sentry separately, using SentrySdk.Init or another Sentry
+ /// integration (such as ASP.NET Core or MAUI), and call on the
+ /// options used to do so.
+ ///
///
/// The logger configuration.
/// The configure options callback.
@@ -368,12 +113,6 @@ public static LoggerConfiguration Sentry(
var options = new SentrySerilogOptions();
configureOptions?.Invoke(options);
- IDisposable? sdkDisposable = null;
- if (options.InitializeSdk)
- {
- sdkDisposable = SentrySdk.Init(options);
- }
-
- return loggerConfiguration.Sink(new SentrySink(options, sdkDisposable), options.RestrictedToMinimumLevel, options.LevelSwitch);
+ return loggerConfiguration.Sink(new SentrySink(options), 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 6374c53e3e..b43e743529 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet10_0.verified.txt
@@ -3,14 +3,12 @@ namespace Sentry.Serilog
{
public static class SentryOptionExtensions
{
- public static T ApplySerilogScopeToEvents(this T options)
- where T : Sentry.SentryOptions { }
+ public static void UseSerilog(this Sentry.SentryOptions options) { }
}
- public class SentrySerilogOptions : Sentry.SentryOptions
+ public class SentrySerilogOptions
{
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; }
@@ -24,33 +22,5 @@ namespace Serilog
{
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, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
- public static Serilog.LoggerConfiguration Sentry(
- this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default,
- Serilog.Events.LogEventLevel? minimumEventLevel = default,
- System.IFormatProvider? formatProvider = null,
- Serilog.Formatting.ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = default,
- bool? isEnvironmentUser = default,
- string? serverName = null,
- bool? attachStackTrace = default,
- int? maxBreadcrumbs = default,
- float? sampleRate = default,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = default,
- System.TimeSpan? shutdownTimeout = default,
- System.Net.DecompressionMethods? decompressionMethods = default,
- System.IO.Compression.CompressionLevel? requestBodyCompressionLevel = default,
- bool? requestBodyCompressionBuffered = default,
- bool? debug = default,
- Sentry.SentryLevel? diagnosticLevel = default,
- Sentry.ReportAssembliesMode? reportAssembliesMode = default,
- Sentry.DeduplicateMode? deduplicateMode = default,
- System.Collections.Generic.Dictionary? defaultTags = null,
- 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.DotNet11_0.verified.txt b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt
index 6374c53e3e..b43e743529 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet11_0.verified.txt
@@ -3,14 +3,12 @@ namespace Sentry.Serilog
{
public static class SentryOptionExtensions
{
- public static T ApplySerilogScopeToEvents(this T options)
- where T : Sentry.SentryOptions { }
+ public static void UseSerilog(this Sentry.SentryOptions options) { }
}
- public class SentrySerilogOptions : Sentry.SentryOptions
+ public class SentrySerilogOptions
{
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; }
@@ -24,33 +22,5 @@ namespace Serilog
{
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, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
- public static Serilog.LoggerConfiguration Sentry(
- this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default,
- Serilog.Events.LogEventLevel? minimumEventLevel = default,
- System.IFormatProvider? formatProvider = null,
- Serilog.Formatting.ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = default,
- bool? isEnvironmentUser = default,
- string? serverName = null,
- bool? attachStackTrace = default,
- int? maxBreadcrumbs = default,
- float? sampleRate = default,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = default,
- System.TimeSpan? shutdownTimeout = default,
- System.Net.DecompressionMethods? decompressionMethods = default,
- System.IO.Compression.CompressionLevel? requestBodyCompressionLevel = default,
- bool? requestBodyCompressionBuffered = default,
- bool? debug = default,
- Sentry.SentryLevel? diagnosticLevel = default,
- Sentry.ReportAssembliesMode? reportAssembliesMode = default,
- Sentry.DeduplicateMode? deduplicateMode = default,
- System.Collections.Generic.Dictionary? defaultTags = null,
- 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 6374c53e3e..b43e743529 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet8_0.verified.txt
@@ -3,14 +3,12 @@ namespace Sentry.Serilog
{
public static class SentryOptionExtensions
{
- public static T ApplySerilogScopeToEvents(this T options)
- where T : Sentry.SentryOptions { }
+ public static void UseSerilog(this Sentry.SentryOptions options) { }
}
- public class SentrySerilogOptions : Sentry.SentryOptions
+ public class SentrySerilogOptions
{
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; }
@@ -24,33 +22,5 @@ namespace Serilog
{
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, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
- public static Serilog.LoggerConfiguration Sentry(
- this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default,
- Serilog.Events.LogEventLevel? minimumEventLevel = default,
- System.IFormatProvider? formatProvider = null,
- Serilog.Formatting.ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = default,
- bool? isEnvironmentUser = default,
- string? serverName = null,
- bool? attachStackTrace = default,
- int? maxBreadcrumbs = default,
- float? sampleRate = default,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = default,
- System.TimeSpan? shutdownTimeout = default,
- System.Net.DecompressionMethods? decompressionMethods = default,
- System.IO.Compression.CompressionLevel? requestBodyCompressionLevel = default,
- bool? requestBodyCompressionBuffered = default,
- bool? debug = default,
- Sentry.SentryLevel? diagnosticLevel = default,
- Sentry.ReportAssembliesMode? reportAssembliesMode = default,
- Sentry.DeduplicateMode? deduplicateMode = default,
- System.Collections.Generic.Dictionary? defaultTags = null,
- 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 6374c53e3e..b43e743529 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.DotNet9_0.verified.txt
@@ -3,14 +3,12 @@ namespace Sentry.Serilog
{
public static class SentryOptionExtensions
{
- public static T ApplySerilogScopeToEvents(this T options)
- where T : Sentry.SentryOptions { }
+ public static void UseSerilog(this Sentry.SentryOptions options) { }
}
- public class SentrySerilogOptions : Sentry.SentryOptions
+ public class SentrySerilogOptions
{
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; }
@@ -24,33 +22,5 @@ namespace Serilog
{
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, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
- public static Serilog.LoggerConfiguration Sentry(
- this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default,
- Serilog.Events.LogEventLevel? minimumEventLevel = default,
- System.IFormatProvider? formatProvider = null,
- Serilog.Formatting.ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = default,
- bool? isEnvironmentUser = default,
- string? serverName = null,
- bool? attachStackTrace = default,
- int? maxBreadcrumbs = default,
- float? sampleRate = default,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = default,
- System.TimeSpan? shutdownTimeout = default,
- System.Net.DecompressionMethods? decompressionMethods = default,
- System.IO.Compression.CompressionLevel? requestBodyCompressionLevel = default,
- bool? requestBodyCompressionBuffered = default,
- bool? debug = default,
- Sentry.SentryLevel? diagnosticLevel = default,
- Sentry.ReportAssembliesMode? reportAssembliesMode = default,
- Sentry.DeduplicateMode? deduplicateMode = default,
- System.Collections.Generic.Dictionary? defaultTags = null,
- 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 6374c53e3e..b43e743529 100644
--- a/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt
+++ b/test/Sentry.Serilog.Tests/ApiApprovalTests.Run.Net4_8.verified.txt
@@ -3,14 +3,12 @@ namespace Sentry.Serilog
{
public static class SentryOptionExtensions
{
- public static T ApplySerilogScopeToEvents(this T options)
- where T : Sentry.SentryOptions { }
+ public static void UseSerilog(this Sentry.SentryOptions options) { }
}
- public class SentrySerilogOptions : Sentry.SentryOptions
+ public class SentrySerilogOptions
{
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; }
@@ -24,33 +22,5 @@ namespace Serilog
{
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, Serilog.Events.LogEventLevel restrictedToMinimumLevel = 0, Serilog.Core.LoggingLevelSwitch? levelSwitch = null) { }
- public static Serilog.LoggerConfiguration Sentry(
- this Serilog.Configuration.LoggerSinkConfiguration loggerConfiguration,
- string dsn,
- Serilog.Events.LogEventLevel? minimumBreadcrumbLevel = default,
- Serilog.Events.LogEventLevel? minimumEventLevel = default,
- System.IFormatProvider? formatProvider = null,
- Serilog.Formatting.ITextFormatter? textFormatter = null,
- bool? sendDefaultPii = default,
- bool? isEnvironmentUser = default,
- string? serverName = null,
- bool? attachStackTrace = default,
- int? maxBreadcrumbs = default,
- float? sampleRate = default,
- string? release = null,
- string? environment = null,
- int? maxQueueItems = default,
- System.TimeSpan? shutdownTimeout = default,
- System.Net.DecompressionMethods? decompressionMethods = default,
- System.IO.Compression.CompressionLevel? requestBodyCompressionLevel = default,
- bool? requestBodyCompressionBuffered = default,
- bool? debug = default,
- Sentry.SentryLevel? diagnosticLevel = default,
- Sentry.ReportAssembliesMode? reportAssembliesMode = default,
- Sentry.DeduplicateMode? deduplicateMode = default,
- System.Collections.Generic.Dictionary? defaultTags = null,
- 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/IntegrationTests.Simple.DotNet10_0.verified.txt b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet10_0.verified.txt
index 952d080225..902ed8c912 100644
--- a/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet10_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet10_0.verified.txt
@@ -41,6 +41,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -95,6 +99,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 65
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -153,6 +161,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -203,8 +215,8 @@
FileName: IntegrationTests.verify.cs,
Function: Task IntegrationTests.Simple(),
Module: null,
- LineNumber: 47,
- ColumnNumber: 17,
+ LineNumber: 53,
+ ColumnNumber: 21,
AbsolutePath: {ProjectDirectory}IntegrationTests.verify.cs,
ContextLine: null,
InApp: false,
@@ -272,6 +284,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
diff --git a/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet8_0.verified.txt b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet8_0.verified.txt
index 952d080225..902ed8c912 100644
--- a/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet8_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet8_0.verified.txt
@@ -41,6 +41,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -95,6 +99,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 65
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -153,6 +161,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -203,8 +215,8 @@
FileName: IntegrationTests.verify.cs,
Function: Task IntegrationTests.Simple(),
Module: null,
- LineNumber: 47,
- ColumnNumber: 17,
+ LineNumber: 53,
+ ColumnNumber: 21,
AbsolutePath: {ProjectDirectory}IntegrationTests.verify.cs,
ContextLine: null,
InApp: false,
@@ -272,6 +284,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
diff --git a/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet9_0.verified.txt b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet9_0.verified.txt
index 952d080225..902ed8c912 100644
--- a/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet9_0.verified.txt
+++ b/test/Sentry.Serilog.Tests/IntegrationTests.Simple.DotNet9_0.verified.txt
@@ -41,6 +41,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -95,6 +99,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 65
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -153,6 +161,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
@@ -203,8 +215,8 @@
FileName: IntegrationTests.verify.cs,
Function: Task IntegrationTests.Simple(),
Module: null,
- LineNumber: 47,
- ColumnNumber: 17,
+ LineNumber: 53,
+ ColumnNumber: 21,
AbsolutePath: {ProjectDirectory}IntegrationTests.verify.cs,
ContextLine: null,
InApp: false,
@@ -272,6 +284,10 @@
Extra: {
inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
MyTaskId: 42
+ },
+ Tags: {
+ inventory: { SmallPotion = 3, BigPotion = 0, CheeseWheels = 512 },
+ MyTaskId: 42
}
}
}
diff --git a/test/Sentry.Serilog.Tests/IntegrationTests.verify.cs b/test/Sentry.Serilog.Tests/IntegrationTests.verify.cs
index 61e3bd0cdf..614bb8b88b 100644
--- a/test/Sentry.Serilog.Tests/IntegrationTests.verify.cs
+++ b/test/Sentry.Serilog.Tests/IntegrationTests.verify.cs
@@ -9,51 +9,58 @@ public Task Simple()
{
var transport = new RecordingTransport();
- var configuration = new LoggerConfiguration();
- configuration.Enrich.FromLogContext();
- configuration.MinimumLevel.Debug();
- configuration.WriteTo.Sentry(
- _ =>
- {
- _.TracesSampleRate = 1;
- _.MinimumBreadcrumbLevel = LogEventLevel.Debug;
- _.MinimumEventLevel = LogEventLevel.Debug;
- _.Transport = transport;
- _.Dsn = ValidDsn;
- _.SendDefaultPii = true;
- _.TextFormatter = new MessageTemplateTextFormatter("[{MyTaskId}] {Message}");
- _.AttachStacktrace = false;
- _.Release = "test-release";
- });
-
- Log.Logger = configuration.CreateLogger();
- using (LogContext.PushProperty("MyTaskId", 42))
- using (LogContext.PushProperty(
- "inventory",
- new
+ using (SentrySdk.Init(
+ options =>
{
- SmallPotion = 3,
- BigPotion = 0,
- CheeseWheels = 512
+ options.TracesSampleRate = 1;
+ options.Transport = transport;
+ options.Dsn = ValidDsn;
+ options.SendDefaultPii = true;
+ options.AttachStacktrace = false;
+ options.Release = "test-release";
+ options.UseSerilog();
}))
{
- Log.Verbose("Verbose message which is not sent.");
- Log.Debug("Debug message stored as breadcrumb.");
- Log.ForContext("MyTaskId", 65).Debug("Message with a different MyTaskId");
- Log.Error("Some event that includes the previous breadcrumbs");
-
- try
- {
- throw new("Exception message");
- }
- catch (Exception exception)
+ var configuration = new LoggerConfiguration();
+ configuration.Enrich.FromLogContext();
+ configuration.MinimumLevel.Debug();
+ configuration.WriteTo.Sentry(
+ _ =>
+ {
+ _.MinimumBreadcrumbLevel = LogEventLevel.Debug;
+ _.MinimumEventLevel = LogEventLevel.Debug;
+ _.TextFormatter = new MessageTemplateTextFormatter("[{MyTaskId}] {Message}");
+ });
+
+ Log.Logger = configuration.CreateLogger();
+ using (LogContext.PushProperty("MyTaskId", 42))
+ using (LogContext.PushProperty(
+ "inventory",
+ new
+ {
+ SmallPotion = 3,
+ BigPotion = 0,
+ CheeseWheels = 512
+ }))
{
- exception.Data.Add("details", "Do work always throws.");
- Log.Fatal(exception, "Error: with exception");
+ Log.Verbose("Verbose message which is not sent.");
+ Log.Debug("Debug message stored as breadcrumb.");
+ Log.ForContext("MyTaskId", 65).Debug("Message with a different MyTaskId");
+ Log.Error("Some event that includes the previous breadcrumbs");
+
+ try
+ {
+ throw new("Exception message");
+ }
+ catch (Exception exception)
+ {
+ exception.Data.Add("details", "Do work always throws.");
+ Log.Fatal(exception, "Error: with exception");
+ }
}
- }
- Log.CloseAndFlush();
+ Log.CloseAndFlush();
+ }
return Verify(transport.Envelopes)
.UniqueForRuntimeAndVersion()
@@ -64,31 +71,34 @@ public Task Simple()
public Task LoggingInsideTheContextOfLogging()
{
var transport = new RecordingTransport();
+ var diagnosticLogger = new InMemoryDiagnosticLogger();
- var configuration = new LoggerConfiguration();
+ using (SentrySdk.Init(
+ options =>
+ {
+ options.TracesSampleRate = 1;
+ options.Transport = transport;
+ options.DiagnosticLogger = diagnosticLogger;
+ options.Dsn = ValidDsn;
+ options.Debug = true;
+ options.AttachStacktrace = false;
+ options.Release = "test-release";
+ options.UseSerilog();
+ }))
+ {
+ var configuration = new LoggerConfiguration();
+ configuration.WriteTo.Sentry(_ => { });
- var diagnosticLogger = new InMemoryDiagnosticLogger();
- configuration.WriteTo.Sentry(
- _ =>
- {
- _.TracesSampleRate = 1;
- _.Transport = transport;
- _.DiagnosticLogger = diagnosticLogger;
- _.Dsn = ValidDsn;
- _.Debug = true;
- _.AttachStacktrace = false;
- _.Release = "test-release";
- });
-
- Log.Logger = configuration.CreateLogger();
-
- SentrySdk.ConfigureScope(
- scope =>
- {
- scope.OnEvaluating += (_, _) => Log.Error("message from OnEvaluating");
- Log.Error("message");
- });
- Log.CloseAndFlush();
+ Log.Logger = configuration.CreateLogger();
+
+ SentrySdk.ConfigureScope(
+ scope =>
+ {
+ scope.OnEvaluating += (_, _) => Log.Error("message from OnEvaluating");
+ Log.Error("message");
+ });
+ Log.CloseAndFlush();
+ }
return Verify(
new
@@ -105,30 +115,33 @@ public Task LoggingInsideTheContextOfLogging()
public Task StructuredLogging()
{
var transport = new RecordingTransport();
-
- var configuration = new LoggerConfiguration();
- configuration.MinimumLevel.Debug();
var diagnosticLogger = new InMemoryDiagnosticLogger();
- configuration.WriteTo.Sentry(
- _ =>
- {
- _.MinimumEventLevel = (LogEventLevel)int.MaxValue;
- _.Transport = transport;
- _.DiagnosticLogger = diagnosticLogger;
- _.Dsn = ValidDsn;
- _.Debug = true;
- _.Environment = "test-environment";
- _.Release = "test-release";
- });
-
- Log.Logger = configuration.CreateLogger();
-
- Log.Debug("Debug message with a Scalar property: {Scalar}", 42);
- Log.Information("Information message with a Sequence property: {Sequence}", new object[] { new int[] { 41, 42, 43 } });
- Log.Warning("Warning message with a Dictionary property: {Dictionary}", new Dictionary { { "key", "value" } });
- Log.Error("Error message with a Structure property: {Structure}", (Number: 42, Text: "42"));
-
- Log.CloseAndFlush();
+
+ using (SentrySdk.Init(
+ options =>
+ {
+ options.Transport = transport;
+ options.DiagnosticLogger = diagnosticLogger;
+ options.Dsn = ValidDsn;
+ options.Debug = true;
+ options.Environment = "test-environment";
+ options.Release = "test-release";
+ options.UseSerilog();
+ }))
+ {
+ var configuration = new LoggerConfiguration();
+ configuration.MinimumLevel.Debug();
+ configuration.WriteTo.Sentry(_ => _.MinimumEventLevel = (LogEventLevel)int.MaxValue);
+
+ Log.Logger = configuration.CreateLogger();
+
+ Log.Debug("Debug message with a Scalar property: {Scalar}", 42);
+ Log.Information("Information message with a Sequence property: {Sequence}", new object[] { new int[] { 41, 42, 43 } });
+ Log.Warning("Warning message with a Dictionary property: {Dictionary}", new Dictionary { { "key", "value" } });
+ Log.Error("Error message with a Structure property: {Structure}", (Number: 42, Text: "42"));
+
+ Log.CloseAndFlush();
+ }
var envelopes = transport.Envelopes;
var logs = transport.Payloads.OfType()
diff --git a/test/Sentry.Serilog.Tests/SentryOptionExtensionsTests.cs b/test/Sentry.Serilog.Tests/SentryOptionExtensionsTests.cs
new file mode 100644
index 0000000000..209ef079fa
--- /dev/null
+++ b/test/Sentry.Serilog.Tests/SentryOptionExtensionsTests.cs
@@ -0,0 +1,25 @@
+namespace Sentry.Serilog.Tests;
+
+public class SentryOptionExtensionsTests
+{
+ [Fact]
+ public void UseSerilog_AddsSerilogScopeEventProcessor()
+ {
+ var options = new SentryOptions();
+
+ options.UseSerilog();
+
+ options.GetAllEventProcessors().OfType().Should().ContainSingle();
+ }
+
+ [Fact]
+ public void UseSerilog_CalledTwice_AddsProcessorOnce()
+ {
+ var options = new SentryOptions();
+
+ options.UseSerilog();
+ options.UseSerilog();
+
+ options.GetAllEventProcessors().OfType().Should().ContainSingle();
+ }
+}
diff --git a/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs b/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
index ce2e2e1f46..fcbcf55d18 100644
--- a/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
+++ b/test/Sentry.Serilog.Tests/SentrySerilogSinkExtensionsTests.cs
@@ -1,33 +1,16 @@
+using Serilog.Formatting;
+
namespace Sentry.Serilog.Tests;
public class SentrySerilogSinkExtensionsTests
{
private class Fixture
{
- public SentrySerilogOptions Options { get; } = new();
-
- // Parameter values that are NOT set to the default values in SentryOptions or SentrySerilogOptions
- public bool SendDefaultPii { get; } = true;
- public bool IsEnvironmentUser { get; } = false;
- public string ServerName { get; } = nameof(ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChangesToObject);
- public bool AttachStackTrace { get; } = true;
- public int MaxBreadcrumbs { get; } = 9;
- public float SampleRate { get; } = 0.4f;
- public string Release { get; } = nameof(ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChangesToObject);
- public string Environment { get; } = nameof(ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChangesToObject);
- public string Dsn { get; } = ValidDsn;
- public int MaxQueueItems { get; } = 17;
- public TimeSpan ShutdownTimeout { get; } = TimeSpan.FromDays(1.3);
- public DecompressionMethods DecompressionMethods { get; } = DecompressionMethods.Deflate & DecompressionMethods.GZip;
- public CompressionLevel RequestBodyCompressionLevel { get; } = CompressionLevel.NoCompression;
- public bool RequestBodyCompressionBuffered { get; } = false;
- public bool Debug { get; } = true;
- public SentryLevel DiagnosticLevel { get; } = SentryLevel.Warning;
- public ReportAssembliesMode ReportAssembliesMode { get; } = ReportAssembliesMode.None;
- public DeduplicateMode DeduplicateMode { get; } = DeduplicateMode.SameExceptionInstance;
- public bool InitializeSdk { get; } = false;
+ // Parameter values that are NOT set to the default values in SentrySerilogOptions
public LogEventLevel MinimumEventLevel { get; } = LogEventLevel.Verbose;
public LogEventLevel MinimumBreadcrumbLevel { get; } = LogEventLevel.Fatal;
+ public IFormatProvider FormatProvider { get; } = CultureInfo.InvariantCulture;
+ public ITextFormatter TextFormatter { get; } = new MessageTemplateTextFormatter("[{MyTaskId}] {Message}");
public LogEventLevel RestrictedToMinimumLevel { get; } = LogEventLevel.Warning;
public LoggingLevelSwitch LevelSwitch { get; } = new(LogEventLevel.Error);
@@ -37,38 +20,13 @@ private class Fixture
private readonly Fixture _fixture = new();
[Fact]
- public void ConfigureSentrySerilogOptions_WithDsn_InitializeSdk()
- {
- var sut = Fixture.GetSut();
-
- // Make the call with only the required parameter
- SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, _fixture.Dsn);
-
- // Compare. I'm not sure how to deep compare--I don't see a nuget ref to that type
- // of functionality and I'm hesitant to introduce new technologies with such a
- // small commit.
- _fixture.Options.Dsn = _fixture.Dsn;
- AssertEqualDeep(_fixture.Options, sut);
- Assert.True(sut.InitializeSdk);
- }
-
- [Fact]
- public void ConfigureSentrySerilogOptions_NoDsn_DontInitializeSdk()
+ public void ConfigureSentrySerilogOptions_NoParameters_LeavesDefaults()
{
var sut = Fixture.GetSut();
- // Make the call with only the required parameter
- SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, null, minimumEventLevel: _fixture.MinimumEventLevel,
- minimumBreadcrumbLevel: _fixture.MinimumBreadcrumbLevel);
+ SentrySinkExtensions.ConfigureSentrySerilogOptions(sut);
- // Compare. I'm not sure how to deep compare--I don't see a nuget ref to that type
- // of functionality and I'm hesitant to introduce new technologies with such a
- // small commit.
- _fixture.Options.InitializeSdk = false; // Since we're not passing in a DSN... would use a different overload otherwise
- _fixture.Options.MinimumEventLevel = _fixture.MinimumEventLevel;
- _fixture.Options.MinimumBreadcrumbLevel = _fixture.MinimumBreadcrumbLevel;
- AssertEqualDeep(_fixture.Options, sut);
- Assert.False(sut.InitializeSdk);
+ AssertEqualDeep(new SentrySerilogOptions(), sut);
}
[Fact]
@@ -76,16 +34,15 @@ public void ConfigureSentrySerilogOptions_WithMultipleParameters_MakesAppropriat
{
var sut = Fixture.GetSut();
- SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, _fixture.Dsn, sendDefaultPii: _fixture.SendDefaultPii,
- decompressionMethods: _fixture.DecompressionMethods, reportAssembliesMode: _fixture.ReportAssembliesMode, sampleRate: _fixture.SampleRate);
+ SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, minimumEventLevel: _fixture.MinimumEventLevel,
+ minimumBreadcrumbLevel: _fixture.MinimumBreadcrumbLevel);
- // Assert
- _fixture.Options.Dsn = _fixture.Dsn;
- _fixture.Options.SendDefaultPii = _fixture.SendDefaultPii;
- _fixture.Options.DecompressionMethods = _fixture.DecompressionMethods;
- _fixture.Options.ReportAssembliesMode = _fixture.ReportAssembliesMode;
- _fixture.Options.SampleRate = _fixture.SampleRate;
- AssertEqualDeep(_fixture.Options, sut);
+ var expected = new SentrySerilogOptions
+ {
+ MinimumEventLevel = _fixture.MinimumEventLevel,
+ MinimumBreadcrumbLevel = _fixture.MinimumBreadcrumbLevel
+ };
+ AssertEqualDeep(expected, sut);
}
[Fact]
@@ -93,37 +50,14 @@ public void ConfigureSentrySerilogOptions_WithAllParameters_MakesAppropriateChan
{
var sut = Fixture.GetSut();
- SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, _fixture.Dsn, _fixture.MinimumEventLevel,
- _fixture.MinimumBreadcrumbLevel, null, null, _fixture.SendDefaultPii,
- _fixture.IsEnvironmentUser, _fixture.ServerName, _fixture.AttachStackTrace, _fixture.MaxBreadcrumbs,
- _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, null,
+ SentrySinkExtensions.ConfigureSentrySerilogOptions(sut, _fixture.MinimumEventLevel,
+ _fixture.MinimumBreadcrumbLevel, _fixture.FormatProvider, _fixture.TextFormatter,
_fixture.RestrictedToMinimumLevel, _fixture.LevelSwitch);
- // Compare individual properties
- Assert.Equal(_fixture.SendDefaultPii, sut.SendDefaultPii);
- Assert.Equal(_fixture.IsEnvironmentUser, sut.IsEnvironmentUser);
- Assert.Equal(_fixture.ServerName, sut.ServerName);
- Assert.Equal(_fixture.AttachStackTrace, sut.AttachStacktrace);
- Assert.Equal(_fixture.MaxBreadcrumbs, sut.MaxBreadcrumbs);
- Assert.Equal(_fixture.SampleRate, sut.SampleRate);
- Assert.Equal(_fixture.Release, sut.Release);
- Assert.Equal(_fixture.Environment, sut.Environment);
- Assert.Equal(_fixture.Dsn, sut.Dsn);
- Assert.Equal(_fixture.MaxQueueItems, sut.MaxQueueItems);
- Assert.Equal(_fixture.ShutdownTimeout, sut.ShutdownTimeout);
- Assert.Equal(_fixture.DecompressionMethods, sut.DecompressionMethods);
- Assert.Equal(_fixture.RequestBodyCompressionLevel, sut.RequestBodyCompressionLevel);
- Assert.Equal(_fixture.RequestBodyCompressionBuffered, sut.RequestBodyCompressionBuffered);
- Assert.Equal(_fixture.Debug, sut.Debug);
- Assert.Equal(_fixture.DiagnosticLevel, sut.DiagnosticLevel);
- Assert.Equal(_fixture.ReportAssembliesMode, sut.ReportAssembliesMode);
- Assert.Equal(_fixture.DeduplicateMode, sut.DeduplicateMode);
- Assert.True(sut.InitializeSdk);
Assert.Equal(_fixture.MinimumEventLevel, sut.MinimumEventLevel);
Assert.Equal(_fixture.MinimumBreadcrumbLevel, sut.MinimumBreadcrumbLevel);
+ Assert.Same(_fixture.FormatProvider, sut.FormatProvider);
+ Assert.Same(_fixture.TextFormatter, sut.TextFormatter);
Assert.Equal(_fixture.RestrictedToMinimumLevel, sut.RestrictedToMinimumLevel);
Assert.Same(_fixture.LevelSwitch, sut.LevelSwitch);
}
@@ -136,12 +70,11 @@ public void Sentry_WithRestrictedToMinimumLevel_ConfigureOptions_FiltersLogsBelo
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());
+ var sink = new SentrySink(options, () => hub, new MockClock());
using var logger = new LoggerConfiguration()
.MinimumLevel.Verbose()
.WriteTo.Sink(sink, options.RestrictedToMinimumLevel, options.LevelSwitch)
@@ -158,9 +91,8 @@ public void Sentry_WithRestrictedToMinimumLevel_ConfigureOptions_FiltersLogsBelo
}
[Fact]
- public void Sentry_WithRestrictedToMinimumLevel_NoDsn_ParameterIsAccepted()
+ public void Sentry_WithRestrictedToMinimumLevel_ParameterIsAccepted()
{
- // Verify the no-DSN overload accepts restrictedToMinimumLevel without throwing
var ex = Record.Exception(() =>
new LoggerConfiguration()
.WriteTo.Sentry(
diff --git a/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs b/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs
index 5a0d40fe58..b5011db15f 100644
--- a/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs
+++ b/test/Sentry.Serilog.Tests/SentrySinkTests.Structured.cs
@@ -21,7 +21,7 @@ public void Emit_StructuredLogging_CapturesLog()
[Theory]
[InlineData(false)]
[InlineData(true)]
- public void Emit_StructuredLogging_UseHubOptionsOverSinkOptions(bool isEnabled)
+ public void Emit_StructuredLogging_RequiresHubOptions(bool isEnabled)
{
InMemorySentryStructuredLogger capturer = new();
_fixture.Hub.Logger.Returns(capturer);
@@ -66,8 +66,8 @@ public void Emit_StructuredLogging_LogEvent(bool withActiveSpan)
{
InMemorySentryStructuredLogger capturer = new();
_fixture.Hub.Logger.Returns(capturer);
- _fixture.Options.Environment = "test-environment";
- _fixture.Options.Release = "test-release";
+ _fixture.SentryOptions.Environment = "test-environment";
+ _fixture.SentryOptions.Release = "test-release";
if (withActiveSpan)
{
diff --git a/test/Sentry.Serilog.Tests/SentrySinkTests.cs b/test/Sentry.Serilog.Tests/SentrySinkTests.cs
index 274b715092..85c52b7b77 100644
--- a/test/Sentry.Serilog.Tests/SentrySinkTests.cs
+++ b/test/Sentry.Serilog.Tests/SentrySinkTests.cs
@@ -5,25 +5,30 @@ public partial class SentrySinkTests
private class Fixture
{
public SentrySerilogOptions Options { get; set; } = new();
+ public InMemoryDiagnosticLogger DiagnosticLogger { get; } = new();
+ public SentryOptions SentryOptions { get; }
public IHub Hub { get; set; } = Substitute.For();
public Func HubAccessor { get; set; }
- public IDisposable SdkDisposeHandle { get; set; } = Substitute.For();
public Scope Scope { get; } = new(new SentryOptions());
public Fixture()
{
+ SentryOptions = new SentryOptions
+ {
+ Debug = true,
+ DiagnosticLogger = DiagnosticLogger
+ };
Hub.IsEnabled.Returns(true);
Hub.Logger.Returns(new InMemorySentryStructuredLogger());
HubAccessor = () => Hub;
Hub.SubstituteConfigureScope(Scope);
- SentryClientExtensions.SentryOptionsForTestingOnly = Options;
+ SentryClientExtensions.SentryOptionsForTestingOnly = SentryOptions;
}
public SentrySink GetSut()
=> new(
Options,
HubAccessor,
- SdkDisposeHandle,
new MockClock());
}
@@ -218,27 +223,46 @@ public void Emit_Properties_AsExtra()
}
[Fact]
- public void Close_DisposesSdk()
+ public void Emit_UseSerilogNotCalled_LogsWarningOnce()
{
var sut = _fixture.GetSut();
var evt = new LogEvent(DateTimeOffset.UtcNow, LogEventLevel.Error, null, MessageTemplate.Empty,
Enumerable.Empty());
sut.Emit(evt);
+ sut.Emit(evt);
- _fixture.SdkDisposeHandle.DidNotReceive().Dispose();
+ _fixture.DiagnosticLogger.Entries
+ .Where(e => e.Level == SentryLevel.Warning && e.Message.Contains("UseSerilog()"))
+ .Should().ContainSingle();
+ }
- sut.Dispose();
+ [Fact]
+ public void Emit_UseSerilogCalled_NoWarning()
+ {
+ _fixture.SentryOptions.UseSerilog();
+ var sut = _fixture.GetSut();
- _fixture.SdkDisposeHandle.Received(1).Dispose();
+ var evt = new LogEvent(DateTimeOffset.UtcNow, LogEventLevel.Error, null, MessageTemplate.Empty,
+ Enumerable.Empty());
+ sut.Emit(evt);
+
+ _fixture.DiagnosticLogger.Entries
+ .Should().NotContain(e => e.Message.Contains("UseSerilog()"));
}
[Fact]
- public void Close_NoDisposeHandleProvided_DoesNotThrow()
+ public void Emit_DisabledHub_NoWarning()
{
- _fixture.SdkDisposeHandle = null;
+ _fixture.Hub.IsEnabled.Returns(false);
var sut = _fixture.GetSut();
- sut.Dispose();
+
+ var evt = new LogEvent(DateTimeOffset.UtcNow, LogEventLevel.Error, null, MessageTemplate.Empty,
+ Enumerable.Empty());
+ sut.Emit(evt);
+
+ _fixture.DiagnosticLogger.Entries
+ .Should().NotContain(e => e.Message.Contains("UseSerilog()"));
}
[Fact]
diff --git a/test/Sentry.Serilog.Tests/SerilogAspNetSentrySdkTestFixture.cs b/test/Sentry.Serilog.Tests/SerilogAspNetSentrySdkTestFixture.cs
index ee332aa46b..6be339c065 100644
--- a/test/Sentry.Serilog.Tests/SerilogAspNetSentrySdkTestFixture.cs
+++ b/test/Sentry.Serilog.Tests/SerilogAspNetSentrySdkTestFixture.cs
@@ -32,7 +32,7 @@ protected override void ConfigureBuilder(WebHostBuilder builder)
builder.ConfigureLogging(loggingBuilder =>
{
var logger = new LoggerConfiguration()
- .WriteTo.Sentry(ValidDsn)
+ .WriteTo.Sentry()
.CreateLogger();
loggingBuilder.AddSerilog(logger);
});