Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
2fb7d37
ref(logs): make API stable (remove Experimental from Options)
Flash0ver Nov 6, 2025
cd79096
fix: MAUI sample
Flash0ver Nov 6, 2025
33aaeac
ref(logs): remove experimental MinimumLogLevel
Flash0ver Nov 6, 2025
f8a7369
Merge branch 'main' into logs/fix-configuration
Flash0ver Nov 20, 2025
1a119b5
merge: cleanup after merge
Flash0ver Nov 20, 2025
9ac70b7
fix(logs): minimum Log-Level for Structured Logs
Flash0ver Nov 25, 2025
8bc1b02
ref!: make all SentryLoggerProviders non-public
Flash0ver Nov 25, 2025
bc86bb7
example: enable Logs for Generic-Host sample
Flash0ver Nov 25, 2025
c65dcb1
feat: enable Logs for Google-Cloud-Functions
Flash0ver Nov 25, 2025
fb91a5b
ref: seal internal Configure-Options
Flash0ver Nov 25, 2025
14010ba
Merge branch 'main' into logs/fix-configuration
Flash0ver Nov 25, 2025
26d56fa
docs: add CHANGELOG entry
Flash0ver Nov 25, 2025
0b56dac
docs: add CHANGELOG entry
Flash0ver Nov 25, 2025
e8a5f86
Merge branch 'main' into logs/fix-configuration
Flash0ver Nov 26, 2025
467898f
Update CHANGELOG.md
Flash0ver Nov 26, 2025
c5012cd
test: add Configure-Logging test
Flash0ver Nov 26, 2025
fab6da5
ref: suppress null
Flash0ver Nov 26, 2025
ce4b5e1
Merge branch 'main' into logs/fix-configuration
jamescrosswell Nov 27, 2025
35b4a8f
Update samples/Sentry.Samples.Google.Cloud.Functions/Function.cs
Flash0ver Nov 28, 2025
8a05445
ref: more samples
Flash0ver Nov 28, 2025
fd9dc83
Update CHANGELOG.md
Flash0ver Nov 28, 2025
b26b3b0
docs: add comment to MAUI sample
Flash0ver Dec 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@

## Unreleased

### BREAKING CHANGES

- Remove `SentryLoggingOptions.ExperimentalLogging.MinimumLogLevel`. _Structured Logs_ can now be configured via the `"Sentry"` logging provider (e.g. in `appsettings.json` and `appsettings.{HostEnvironment}.json`) ([#4700](https://github.com/getsentry/sentry-dotnet/pull/4700))
- All logging provider types are _internal_ now in order to ensure configuration as intended ([#4700](https://github.com/getsentry/sentry-dotnet/pull/4700))

### Features

- Add support for _Structured Logs_ in `Sentry.Google.Cloud.Functions` ([#4700](https://github.com/getsentry/sentry-dotnet/pull/4700))

### Fixes

- Minimum Log-Level for _Structured Logs_, _Breadcrumbs_ and _Events_ in all Logging-Integrations ([#4700](https://github.com/getsentry/sentry-dotnet/pull/4700))
- for `Sentry.Extensions.Logging`, `Sentry.AspNetCore`, `Sentry.Maui` and `Sentry.Google.Cloud.Functions`
- the Logger-Provider for _Breadcrumbs_ and _Events_ ignores Logging-Configuration (e.g. via `appsettings.json`)
- use the intended `SentryLoggingOptions.MinimumBreadcrumbLevel`, `SentryLoggingOptions.MinimumEventLevel`, or add filter functions via `SentryLoggingOptionsExtensions.AddLogEntryFilter`
- the Logger-Provider for _Structured Logs_ respects Logging-Configuration (e.g. via `appsettings.json`)
- when enabled by `SentryOptions.EnableLogs`
- Avoid appending `/NODEFAULTLIB:MSVCRT` to NativeAOT linker arguments on Windows when targetting non-Windows platforms (Android, Browser) ([#4760](https://github.com/getsentry/sentry-dotnet/pull/4760))

## 6.0.0-rc.2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ public void Setup()
{
Dsn = DsnSamples.ValidDsn,
EnableLogs = true,
ExperimentalLogging =
{
MinimumLogLevel = LogLevel.Information,
}
};
options.SetBeforeSendLog((SentryLog log) =>
{
Expand Down
7 changes: 6 additions & 1 deletion samples/Sentry.Samples.AspNetCore.Basic/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,12 @@
options.Debug = true;
#endif

// This option enables Logs sent to Sentry.
// Configure the minimum Log Level of Breadcrumbs and Events
options.MinimumBreadcrumbLevel = LogLevel.Information;
options.MinimumEventLevel = LogLevel.Error;

// This option enables Logs sent to Sentry
// Configure the minimum Log Level of Structured-Logs via e.g. "appsettings.json" and "appsettings.{HostEnvironment}.json"
options.EnableLogs = true;
});

Expand Down
14 changes: 14 additions & 0 deletions samples/Sentry.Samples.AspNetCore.Basic/appsettings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
"Sentry": {
"LogLevel": {
"Default": "Trace"
}
}
},
"AllowedHosts": "*"
}
10 changes: 9 additions & 1 deletion samples/Sentry.Samples.AspNetCore.Grpc/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,20 @@
"DiagnosticLevel": "Error",
"DefaultTags": {
"default-key-in-config": "default-value"
}
},
// Record log messages as Structured Logs (configure via "Logging" section)
"EnableLogs": true
},
"Logging": {
"IncludeScopes": false,
"LogLevel": {
"Default": "Trace"
},
// Configure the "Sentry" provider for Structured Logs
"Sentry": {
"LogLevel": {
"Default": "Information"
}
}
},
"Kestrel": {
Expand Down
10 changes: 9 additions & 1 deletion samples/Sentry.Samples.AspNetCore.Mvc/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,20 @@
"DiagnosticLevel": "Error",
"DefaultTags": {
"default-key-in-config": "default-value"
}
},
// Record log messages as Structured Logs (configure via "Logging" section)
"EnableLogs": true
},
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
},
// Configure the "Sentry" provider for Structured Logs
"Sentry": {
"LogLevel": {
"Default": "Warning"
}
}
},
"AllowedHosts": "*"
Expand Down
2 changes: 2 additions & 0 deletions samples/Sentry.Samples.GenericHost/SampleHostedService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ internal class SampleHostedService(IHub hub, ILogger<SampleHostedService> logger
{
public Task StartAsync(CancellationToken cancellationToken)
{
// Configure structured logging via appsettings.json (Logging:Sentry:LogLevel:)
logger.LogTrace("LogLevel.Trace is not configured to be sent as structured log");
// Logging integration by default keeps informational logs as Breadcrumb
logger.LogInformation("Starting sample hosted service. This goes as a breadcrumb");
// You can also add breadcrumb directly through Sentry.Hub:
Expand Down
8 changes: 7 additions & 1 deletion samples/Sentry.Samples.GenericHost/appsettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,18 @@
"Logging": {
"LogLevel": {
"Default": "Trace"
},
"Sentry": {
"LogLevel": {
"Default": "Information" // Configure structured logs
}
}
},
"Sentry": {
//"Dsn": "TODO: Configure your DSN here and uncomment this line",
"MinimumBreadcrumbLevel": "Debug",
"MinimumEventLevel": "Warning",
"SendDefaultPii": true // Send user name and machine name
"SendDefaultPii": true, // Send user name and machine name
"EnableLogs": true // Send structured logs
}
}
7 changes: 7 additions & 0 deletions samples/Sentry.Samples.Google.Cloud.Functions/Function.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,18 @@
public class Function : IHttpFunction
{
private readonly ILogger<Function> _logger;

public Function(ILogger<Function> logger) => _logger = logger;

public Task HandleAsync(HttpContext context)
{
// Configure structured logging via appsettings.json (Logging:Sentry:LogLevel:)
_logger.LogTrace("LogLevel.Trace is not configured to be sent as structured log");

// Logging integration by default keeps informational logs as Breadcrumb
_logger.LogInformation("Useful info that is added to the breadcrumb list.");

// Results in an Event/Error in Sentry, including the Breadcrumb from above
throw new Exception("Bad function");
}
}
13 changes: 12 additions & 1 deletion samples/Sentry.Samples.Google.Cloud.Functions/appsettings.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,19 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug"
},
"Sentry": {
"LogLevel": {
"Default": "Information"
}
}
},
"Sentry": {
//"Dsn": "TODO: Configure your DSN here and uncomment this line",
"MaxRequestBodySize": "Always",
"SendDefaultPii": true,
"EnableTracing": true
"EnableTracing": true,
"EnableLogs" : true
}
}
4 changes: 2 additions & 2 deletions samples/Sentry.Samples.ME.Logging/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
// Optionally configure options: The default values are:
options.MinimumBreadcrumbLevel = LogLevel.Information; // It requires at least this level to store breadcrumb
options.MinimumEventLevel = LogLevel.Error; // This level or above will result in event sent to Sentry
options.ExperimentalLogging.MinimumLogLevel = LogLevel.Trace; // This level or above will result in log sent to Sentry

// This option enables Logs sent to Sentry.
options.EnableLogs = true;
Expand All @@ -33,12 +32,13 @@
return log;
});

// TODO: AddLogEntryFilter
// Don't keep as a breadcrumb or send events for messages of level less than Critical with exception of type DivideByZeroException
options.AddLogEntryFilter((_, level, _, exception) => level < LogLevel.Critical && exception is DivideByZeroException);

options.ConfigureScope(s => s.SetTag("RootScope", "sent with all events"));
});
// Don't send logs for messages of level less than Warning for category Program
builder.AddFilter(typeof(Program).FullName, LogLevel.Warning);
});
var logger = loggerFactory.CreateLogger<Program>();

Expand Down
4 changes: 4 additions & 0 deletions samples/Sentry.Samples.Maui/MauiProgram.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System.Diagnostics;
using Microsoft.Extensions.Logging;
using Sentry.Maui;

namespace Sentry.Samples.Maui;
Expand Down Expand Up @@ -77,6 +78,9 @@ public static MauiApp CreateMauiApp()
fonts.AddFont("OpenSans-Semibold.ttf", "OpenSansSemibold");
});

builder.Logging.AddFilter(null, LogLevel.Warning);
builder.Logging.AddFilter("Sentry.Samples.Maui", LogLevel.Information);

// For this sample, we'll also register the main page for DI so we can inject a logger there.
builder.Services.AddTransient<MainPage>();

Expand Down
10 changes: 8 additions & 2 deletions src/Sentry.AspNetCore/SentryAspNetCoreLoggerProvider.cs
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Sentry.Extensions.Logging;
using Sentry.Infrastructure;

namespace Sentry.AspNetCore;

/// <summary>
/// Logger provider for Sentry.
/// Sentry Logger Provider for <see cref="Breadcrumb"/> and <see cref="SentryEvent"/>.
/// </summary>
[ProviderAlias("Sentry")]
public class SentryAspNetCoreLoggerProvider : SentryLoggerProvider
internal sealed class SentryAspNetCoreLoggerProvider : SentryLoggerProvider
{
/// <summary>
/// Creates a new instance of <see cref="SentryAspNetCoreLoggerProvider"/>
Expand All @@ -17,4 +18,9 @@ public SentryAspNetCoreLoggerProvider(IOptions<SentryAspNetCoreOptions> options,
: base(options, hub)
{
}

internal SentryAspNetCoreLoggerProvider(SentryAspNetCoreOptions options, IHub hub, ISystemClock clock)
: base(hub, clock, options)
{
}
}
4 changes: 2 additions & 2 deletions src/Sentry.AspNetCore/SentryAspNetCoreOptionsSetup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ namespace Sentry.AspNetCore;
/// Sets up ASP.NET Core option for Sentry.
/// </summary>
#if NETSTANDARD2_0
public class SentryAspNetCoreOptionsSetup : ConfigureFromConfigurationOptions<SentryAspNetCoreOptions>
internal sealed class SentryAspNetCoreOptionsSetup : ConfigureFromConfigurationOptions<SentryAspNetCoreOptions>
{
/// <summary>
/// Creates a new instance of <see cref="SentryAspNetCoreOptionsSetup"/>.
Expand All @@ -32,7 +32,7 @@ public override void Configure(SentryAspNetCoreOptions options)
}

#else
public class SentryAspNetCoreOptionsSetup : IConfigureOptions<SentryAspNetCoreOptions>
internal sealed class SentryAspNetCoreOptionsSetup : IConfigureOptions<SentryAspNetCoreOptions>
{
private readonly IConfiguration _config;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
namespace Sentry.AspNetCore;

/// <summary>
/// Structured Logger Provider for Sentry.
/// Sentry Logger Provider for <see cref="SentryLog"/>.
/// </summary>
[ProviderAlias("SentryLogs")]
[ProviderAlias("Sentry")]
internal sealed class SentryAspNetCoreStructuredLoggerProvider : SentryStructuredLoggerProvider
{
public SentryAspNetCoreStructuredLoggerProvider(IOptions<SentryAspNetCoreOptions> options, IHub hub)
Expand Down
11 changes: 6 additions & 5 deletions src/Sentry.AspNetCore/SentryWebHostBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,14 +95,15 @@ public static IWebHostBuilder UseSentry(
_ = logging.Services.AddSingleton<ILoggerProvider, SentryAspNetCoreLoggerProvider>();
_ = logging.Services.AddSingleton<ILoggerProvider, SentryAspNetCoreStructuredLoggerProvider>();

_ = logging.AddFilter<SentryAspNetCoreLoggerProvider>(
"Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware",
LogLevel.None);
_ = logging.AddFilter<SentryAspNetCoreStructuredLoggerProvider>(static (string? categoryName, LogLevel logLevel) =>
// Add a delegate rule in order to ignore Configuration like "appsettings.json" and "appsettings.{HostEnvironment}.json"
_ = logging.AddFilter<SentryAspNetCoreLoggerProvider>(static (string? categoryName, LogLevel logLevel) =>
{
return categoryName is null
|| (categoryName != "Sentry.ISentryClient" && categoryName != "Sentry.AspNetCore.SentryMiddleware");
|| categoryName != "Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware";
});
// Add non-delegate rules in order to respect Configuration like "appsettings.json" and "appsettings.{HostEnvironment}.json"
_ = logging.AddFilter<SentryAspNetCoreStructuredLoggerProvider>("Sentry.ISentryClient", LogLevel.None);
_ = logging.AddFilter<SentryAspNetCoreStructuredLoggerProvider>("Sentry.AspNetCore.SentryMiddleware", LogLevel.None);

var sentryBuilder = logging.Services.AddSentry();
configureSentry?.Invoke(context, sentryBuilder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,11 @@ internal class BindableSentryLoggingOptions : BindableSentryOptions
public LogLevel? MinimumEventLevel { get; set; }
public bool? InitializeSdk { get; set; }

public BindableSentryLoggingExperimentalOptions ExperimentalLogging { get; set; } = new();

internal sealed class BindableSentryLoggingExperimentalOptions
{
public LogLevel? MinimumLogLevel { get; set; }
}

public void ApplyTo(SentryLoggingOptions options)
{
base.ApplyTo(options);
options.MinimumBreadcrumbLevel = MinimumBreadcrumbLevel ?? options.MinimumBreadcrumbLevel;
options.MinimumEventLevel = MinimumEventLevel ?? options.MinimumEventLevel;
options.InitializeSdk = InitializeSdk ?? options.InitializeSdk;

options.ExperimentalLogging.MinimumLogLevel = ExperimentalLogging.MinimumLogLevel ?? options.ExperimentalLogging.MinimumLogLevel;
}
}
8 changes: 2 additions & 6 deletions src/Sentry.Extensions.Logging/LoggingBuilderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,8 @@ internal static ILoggingBuilder AddSentry<TOptions>(
builder.AddFilter<SentryLoggerProvider>(_ => true);

// Logs from the SentryLogger should not flow to the SentryStructuredLogger as this may cause recursive invocations.
// Filtering of logs is handled in SentryStructuredLogger, using SentryOptions.MinimumLogLevel
builder.AddFilter<SentryStructuredLoggerProvider>(static (string? categoryName, LogLevel logLevel) =>
{
return categoryName is null
|| categoryName != "Sentry.ISentryClient";
});
// Filtering of structured logs is handled by Microsoft.Extensions.Configuration and Microsoft.Extensions.Options.
builder.AddFilter<SentryStructuredLoggerProvider>("Sentry.ISentryClient", LogLevel.None);

return builder;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Sentry.Extensions.Logging/SentryLoggerProvider.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@
namespace Sentry.Extensions.Logging;

/// <summary>
/// Sentry Logger Provider.
/// Sentry Logger Provider for <see cref="Breadcrumb"/> and <see cref="SentryEvent"/>.
/// </summary>
[ProviderAlias("Sentry")]
public class SentryLoggerProvider : ILoggerProvider
internal class SentryLoggerProvider : ILoggerProvider
{
private readonly ISystemClock _clock;
private readonly SentryLoggingOptions _options;
Expand Down
35 changes: 0 additions & 35 deletions src/Sentry.Extensions.Logging/SentryLoggingOptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,39 +50,4 @@ public class SentryLoggingOptions : SentryOptions
/// List of callbacks to be invoked when initializing the SDK
/// </summary>
internal Action<Scope>[] ConfigureScopeCallbacks { get; set; } = Array.Empty<Action<Scope>>();

/// <summary>
/// Experimental Sentry Logging features.
/// </summary>
/// <remarks>
/// This and related experimental APIs may change in the future.
/// </remarks>
[Experimental(Infrastructure.DiagnosticId.ExperimentalFeature)]
public SentryLoggingExperimentalOptions ExperimentalLogging { get; set; } = new();

/// <summary>
/// Experimental Sentry Logging options.
/// </summary>
/// <remarks>
/// This and related experimental APIs may change in the future.
/// </remarks>
[Experimental(Infrastructure.DiagnosticId.ExperimentalFeature)]
public sealed class SentryLoggingExperimentalOptions
{
internal SentryLoggingExperimentalOptions()
{
}

/// <summary>
/// Gets or sets the minimum log level.
/// <para>This API is experimental and it may change in the future.</para>
/// </summary>
/// <remarks>
/// Logs with this level or higher will be stored as <see cref="SentryLog"/>.
/// </remarks>
/// <value>
/// The minimum log level.
/// </value>
public LogLevel MinimumLogLevel { get; set; } = LogLevel.Trace;
}
}
Loading
Loading