Skip to content

Sentry Structured Logging for .NET #4132

Closed
3 of 3 issues completed
Closed

Description

@AbhiPrasad

https://develop.sentry.dev/sdk/telemetry/logs/

Sentry is adding support for structured logging. Let's add it to the .NET SDK!

  1. Define the logs protocol and log envelope item in the SDK
  2. Add the Public API (SDK options and methods) as per the docs
  3. Make sure the the SDK follows the documented behavior
  4. Attach default attributes to the SDK as per docs
  5. Instrument popular logging libraries to send logs to Sentry. SDK maintainers can best decide what they should support, but we should definitely support the same integrations that we do in the SDK (NLog, Serilog, etc.)
  6. Create a GH discussion that contains instructions for setting up the SDK in your repo. Eventually this will be moved into the primary docs. See the JS SDK's GH discussion for inspiration.

Activity

  1. bruno-garcia commented on Apr 23, 2025

    @bruno-garcia
    Member

    The idea is to:

    1. Ship the barebone Sentry API into the core Sentry package
    2. Make this work from Microsoft.Extensions.Logging
    3. Make this work from Serilog
    4. Make this work from NLog
    5. Make this work from log4net

    I'll dare to say that no one in .NET will use "Sentry's logging API". I know I wouldn't. But that's not the point.
    The point is to have the API in the main SDK, so that the logging libraries integrations only pipe data to it.

    The order above allows us to try/test things incrementally.
    Once we get to n2, we can add it to nuget-trends and symbol-collector for dogfooding.

    All our current logging integrations do:

    1. Check level, if higher than MininumEventLevel it records an event
    2. Check level, if higher than MinimumBreadcrumbLevel it adds a breadcrumb

    e.g:

    public void Log<TState>(
    LogLevel logLevel,
    EventId eventId,
    TState state,
    Exception? exception,
    Func<TState, Exception?, string>? formatter)
    {
    if (!IsEnabled(logLevel))
    {
    return;
    }
    var message = formatter?.Invoke(state, exception);
    if (ShouldCaptureEvent(logLevel, eventId, exception))
    {
    var @event = CreateEvent(logLevel, eventId, state, exception, message, CategoryName);
    _ = _hub.CaptureEvent(@event);
    // Capturing exception events adds a breadcrumb automatically... we don't want to add another one
    if (exception != null)
    {
    return;
    }
    }
    if (ShouldAddBreadcrumb(logLevel, eventId, exception))
    {
    var data = eventId.ToDictionaryOrNull();
    if (exception != null && message != null)
    {
    // Exception.Message won't be used as Breadcrumb message
    // Avoid losing it by adding as data:
    data ??= new Dictionary<string, string>();
    data.Add("exception_message", exception.Message);
    }
    _hub.AddBreadcrumb(
    _clock,
    (message ?? exception?.Message)!,
    CategoryName,
    null,
    data,
    logLevel.ToBreadcrumbLevel());
    }
    }

    The crumb goes after, so that in a subsequent event, it will include the breadcrumb of the previous event.

    This works well for error monitoring. But with the new logging integration, we'll send all logs to Sentry.
    The new logging could be a new logger class, that's added in of logging is enabled. Since little is shared from the current logger described above, and the new one.

  2. Flash0ver commented on May 15, 2025

    @Flash0ver
    Contributor

    Sentry Structured Logging for .NET

  3. wondertalik commented on May 20, 2025

    @wondertalik

    Hey,

    Thanks for this feature that are you working on. Any plans to adapt opentelemetry for logs as you did for tracing?

  4. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on May 20, 2025
  5. AbhiPrasad commented on May 20, 2025

    @AbhiPrasad
    Author

    Hey @wondertalik - thanks for your interest! At the current moment we are focusing on adding logs support via the Sentry SDKs. We'll evaluate OpenTelemetry support in the future. Our logs schema is a superset of the OpenTelemetry schema, so we are already compatible with OpenTelemetry.

  6. 160 remaining items

  7. mvdgun commented on Dec 4, 2025

    @mvdgun

    Hi there, awesome work on the Sentry log integration so far!

    In my apps I have a logging section in the appsettings.json file. However, I still see many log messages that I don't expect based on the configuration below in Sentry. Do I need to configure the log level separately in the Sentry SDK? I did see a SentryLoggingOptions.ExperimentalLogging.MinimumLogLevel property. Are we expected to set that property instead of the built-in log level settings in ASP.NET Core?

      "Logging": {
        "LogLevel": {
          "MyApp": "Trace",
          "Default": "Warning",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      }
    
  8. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Dec 4, 2025
  9. Flash0ver commented on Dec 4, 2025

    @Flash0ver
    Contributor

    With 5.x yes ... there is indeed the option SentryLoggingOptions.ExperimentalLogging.MinimumLogLevel.
    However, this solution does not allow for per-category-name based granularity.
    This option is (very soon: was) a workaround.

    With the upcoming 6.0.0 (next couple of days), this option will be gone and our Microsoft.Extensions.Logging for Sentry Structured Logs will properly respect Configuration like appsettings.json, appsettings.{HostEnvironment}.json and also programmatic Configuration like builder.Logging.AddFilter(null, LogLevel) and builder.Logging.AddFilter("My.Category.Name", LogLevel).

    The reason we had to do this in a major version is that there is a behavioral breaking change involved, as we noticed inconsistencies during implementation.
    For more details on that see #4700.
    The TL;DR; is:

    • 6.0.0 is fixing inconsistencies of filtering within all of Sentry's Microsoft.Extensions.Logging-based integrations, to be not only as originally intended, but also idiomatic across the ecosystem
      • Breadcrumbs are filtered by
        1. SentryLoggingOptions.MinimumBreadcrumbLevel
        2. SentryLoggingOptions.AddLogEntryFilter
        3. SentryOptions.SetBeforeBreadcrumb
      • Events are filtered by
        1. SentryLoggingOptions.MinimumEventLevel
        2. SentryLoggingOptions.AddLogEntryFilter
        3. SentryOptions.SetBeforeSend
      • Logs are filtered by
        1. Configuration as mentioned above
        2. SentryOptions.SetBeforeSendLog
  10. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Dec 4, 2025
  11. Syed-RI commented on Dec 17, 2025

    @Syed-RI

    With 5.x yes ... there is indeed the option SentryLoggingOptions.ExperimentalLogging.MinimumLogLevel. However, this solution does not allow for per-category-name based granularity. This option is (very soon: was) a workaround.

    With the upcoming 6.0.0 (next couple of days), this option will be gone and our Microsoft.Extensions.Logging for Sentry Structured Logs will properly respect Configuration like appsettings.json, appsettings.{HostEnvironment}.json and also programmatic Configuration like builder.Logging.AddFilter(null, LogLevel) and builder.Logging.AddFilter("My.Category.Name", LogLevel).

    The reason we had to do this in a major version is that there is a behavioral breaking change involved, as we noticed inconsistencies during implementation. For more details on that see #4700. The TL;DR; is:

    • 6.0.0 is fixing inconsistencies of filtering within all of Sentry's Microsoft.Extensions.Logging-based integrations, to be not only as originally intended, but also idiomatic across the ecosystem

      • Breadcrumbs are filtered by

        1. SentryLoggingOptions.MinimumBreadcrumbLevel
        2. SentryLoggingOptions.AddLogEntryFilter
        3. SentryOptions.SetBeforeBreadcrumb
      • Events are filtered by

        1. SentryLoggingOptions.MinimumEventLevel
        2. SentryLoggingOptions.AddLogEntryFilter
        3. SentryOptions.SetBeforeSend
      • Logs are filtered by

        1. Configuration as mentioned above
        2. SentryOptions.SetBeforeSendLog

    Can we still set a minimum log level for MAUI App? or we have to keep using SentryOptions.SetBeforeSendLog ?
    For context, prior to version 6 we were doing

    options.Experimental.EnableLogs = true;
    options.ExperimentalLogging.MinimumLogLevel = Microsoft.Extensions.Logging.LogLevel.Information;

    I that correct?

    And Im assuming now we have to do

    builder.Logging.AddFilter(null, LogLevel.Information);
  12. moved this to Waiting for: Product Owner in GitHub Issues with 👀 3on Dec 17, 2025
  13. Flash0ver commented on Dec 23, 2025

    @Flash0ver
    Contributor

    TL;DR: correct!

    Yes, as of Sentry v6.0.0 the minimum log level is now configured idiomatically via the Microsoft.Extensions.Logging infrastructure.
    SentryOptions.SetBeforeSendLog is no longer necessary to filter logs per Log-Level and/or per Category. But you may still use it to drop and/or scrub logs based on other Attributes.
    And SentryLoggingOptions.ExperimentalLogging.MinimumLogLevel is no longer available.

    Although .NET MAUI does not support appsettings.{Environment}.json out of the box, you could set it up yourself (with some caveats). But all other means of configuration do work out of the box, like AddFilter you mentioned, configuring the minimum log level on a per-Category basis.

    e.g.

    builder.Logging
      .AddFilter(null, LogLevel.Warning)
      .AddFilter("System", LogLevel.Error)
      .AddFilter("Microsoft", LogLevel.Error)
      .AddFilter("MyCategory", LogLevel.Information);
  14. moved this from Waiting for: Product Owner to No status in GitHub Issues with 👀 3on Dec 23, 2025
  15. Flash0ver commented on Dec 23, 2025

    @Flash0ver
    Contributor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

.NETPull requests that update .net codeFeatureNew feature or requestLogs

Projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions