diff --git a/.generated.NoMobile.slnx b/.generated.NoMobile.slnx index 4a47f6ecab..4742240f65 100644 --- a/.generated.NoMobile.slnx +++ b/.generated.NoMobile.slnx @@ -89,6 +89,7 @@ + diff --git a/Sentry-CI-Build-Linux-NoMobile.slnf b/Sentry-CI-Build-Linux-NoMobile.slnf index ce4e8725db..1e150ccacc 100644 --- a/Sentry-CI-Build-Linux-NoMobile.slnf +++ b/Sentry-CI-Build-Linux-NoMobile.slnf @@ -9,6 +9,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/Sentry-CI-Build-Linux.slnf b/Sentry-CI-Build-Linux.slnf index 843d20b98f..51e1b0f221 100644 --- a/Sentry-CI-Build-Linux.slnf +++ b/Sentry-CI-Build-Linux.slnf @@ -10,6 +10,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/Sentry-CI-Build-Windows-arm64.slnf b/Sentry-CI-Build-Windows-arm64.slnf index 164adcf65d..e57d3e4d8b 100644 --- a/Sentry-CI-Build-Windows-arm64.slnf +++ b/Sentry-CI-Build-Windows-arm64.slnf @@ -11,6 +11,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/Sentry-CI-Build-Windows.slnf b/Sentry-CI-Build-Windows.slnf index b14e45d2c4..66699079f9 100644 --- a/Sentry-CI-Build-Windows.slnf +++ b/Sentry-CI-Build-Windows.slnf @@ -11,6 +11,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/Sentry-CI-Build-macOS.slnf b/Sentry-CI-Build-macOS.slnf index bce6cf8fec..5a418b6c8c 100644 --- a/Sentry-CI-Build-macOS.slnf +++ b/Sentry-CI-Build-macOS.slnf @@ -12,6 +12,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/Sentry.slnx b/Sentry.slnx index 4a47f6ecab..4742240f65 100644 --- a/Sentry.slnx +++ b/Sentry.slnx @@ -89,6 +89,7 @@ + diff --git a/SentryAspNetCore.slnf b/SentryAspNetCore.slnf index ccd8904461..b64b079722 100644 --- a/SentryAspNetCore.slnf +++ b/SentryAspNetCore.slnf @@ -7,6 +7,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/SentryNoMobile.slnf b/SentryNoMobile.slnf index 206615ce08..9e2060f47b 100644 --- a/SentryNoMobile.slnf +++ b/SentryNoMobile.slnf @@ -9,6 +9,7 @@ "samples\\Sentry.Samples.AspNetCore.Blazor.Wasm\\Sentry.Samples.AspNetCore.Blazor.Wasm.csproj", "samples\\Sentry.Samples.AspNetCore.Grpc\\Sentry.Samples.AspNetCore.Grpc.csproj", "samples\\Sentry.Samples.AspNetCore.Mvc\\Sentry.Samples.AspNetCore.Mvc.csproj", + "samples\\Sentry.Samples.AspNetCore.NLog\\Sentry.Samples.AspNetCore.NLog.csproj", "samples\\Sentry.Samples.AspNetCore.Serilog\\Sentry.Samples.AspNetCore.Serilog.csproj", "samples\\Sentry.Samples.AspNetCore.WebAPI.Profiling\\Sentry.Samples.AspNetCore.WebAPI.Profiling.csproj", "samples\\Sentry.Samples.Aws.Lambda.AspNetCoreServer\\Sentry.Samples.Aws.Lambda.AspNetCoreServer.csproj", diff --git a/samples/Sentry.Samples.AspNetCore.NLog/Program.cs b/samples/Sentry.Samples.AspNetCore.NLog/Program.cs new file mode 100644 index 0000000000..ca75222ccf --- /dev/null +++ b/samples/Sentry.Samples.AspNetCore.NLog/Program.cs @@ -0,0 +1,55 @@ +using NLog; +using NLog.Config; +using NLog.Targets; +using NLog.Web; +using Sentry.NLog; + +// Configure NLog to send logs to Sentry. This only adds the Sentry target: the SDK is initialized by UseSentry below. +var sentryTarget = new SentryTarget(new SentryNLogOptions +{ + // Warn and higher are added as breadcrumbs (default is Info) + MinimumBreadcrumbLevel = NLog.LogLevel.Warn, + // Error and higher are sent as events (default is Error) + MinimumEventLevel = NLog.LogLevel.Error, +}); + +var nlogConfig = new LoggingConfiguration(); +nlogConfig.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, new ColoredConsoleTarget("console")); +// Every entry that reaches the Sentry target is sent as a structured log, so this rule sets the minimum level for logs. +// Info and higher are sent as logs. Breadcrumbs and events can only use entries that pass this rule. +nlogConfig.AddRule(NLog.LogLevel.Info, NLog.LogLevel.Fatal, sentryTarget); +LogManager.Configuration = nlogConfig; + +var builder = WebApplication.CreateBuilder(args); + +// Send ILogger entries through NLog. ReplaceLoggerFactory stops the ILogger providers that UseSentry adds from also +// capturing every entry, so each one reaches Sentry once, through the NLog target, whatever order these calls are in. +builder.Host.UseNLog(new NLogAspNetCoreOptions { ReplaceLoggerFactory = true }); + +builder.UseSentry(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; +#else + options.Dsn = EnvironmentVariables.Dsn; +#endif +}); + +var app = builder.Build(); + +app.MapGet("/", (ILogger logger) => +{ + logger.LogDebug("Below the Sentry rule's minimum level, so not sent to Sentry"); + logger.LogInformation("Sent as a log"); + logger.LogWarning("Sent as a log and added as a breadcrumb"); + logger.LogError("Sent as a log and as an event, which includes the breadcrumb above"); + return "Logged through ILogger at each level. Check Sentry for the logs and the event."; +}); + +app.MapGet("/throw", () => { throw new Exception("An exception thrown from the ASP.NET Core pipeline"); }); + +app.Run(); + +LogManager.Shutdown(); diff --git a/samples/Sentry.Samples.AspNetCore.NLog/Properties/launchSettings.json b/samples/Sentry.Samples.AspNetCore.NLog/Properties/launchSettings.json new file mode 100644 index 0000000000..a13893590a --- /dev/null +++ b/samples/Sentry.Samples.AspNetCore.NLog/Properties/launchSettings.json @@ -0,0 +1,12 @@ +{ + "profiles": { + "Sentry.Samples.AspNetCore.NLog": { + "commandName": "Project", + "launchBrowser": true, + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + }, + "applicationUrl": "http://localhost:5164" + } + } +} diff --git a/samples/Sentry.Samples.AspNetCore.NLog/Sentry.Samples.AspNetCore.NLog.csproj b/samples/Sentry.Samples.AspNetCore.NLog/Sentry.Samples.AspNetCore.NLog.csproj new file mode 100644 index 0000000000..629da0c982 --- /dev/null +++ b/samples/Sentry.Samples.AspNetCore.NLog/Sentry.Samples.AspNetCore.NLog.csproj @@ -0,0 +1,16 @@ + + + + net11.0 + + + + + + + + + + + + diff --git a/src/Sentry.Extensions.Logging/LoggingBuilderExtensions.cs b/src/Sentry.Extensions.Logging/LoggingBuilderExtensions.cs index 7543721fbf..155e2b3ba3 100644 --- a/src/Sentry.Extensions.Logging/LoggingBuilderExtensions.cs +++ b/src/Sentry.Extensions.Logging/LoggingBuilderExtensions.cs @@ -21,9 +21,9 @@ public static class LoggingBuilderExtensions /// Adds the Sentry logging integration. /// /// - /// In an app that calls UseSentry, which already adds the logging integration, this has no effect unless the - /// app removed Sentry's logger providers, for example with ClearProviders(). It then adds back the providers - /// that UseSentry added, which use the host's Sentry options. + /// Apps that call UseSentry don't need this, because UseSentry already adds the logging integration. + /// If your app calls ClearProviders() after calling UseSentry that would also remove Sentry's logging + /// integration - in which case this method can be used to add Sentry's providers back again. /// /// The builder. public static ILoggingBuilder AddSentry(this ILoggingBuilder builder) @@ -44,10 +44,10 @@ public static ILoggingBuilder AddSentry(this ILoggingBuilder builder, string dsn /// Adds the Sentry logging integration. /// /// - /// In an app that calls UseSentry, which already adds the logging integration, this has no effect unless the - /// app removed Sentry's logger providers, for example with ClearProviders(). It then adds back the providers - /// that UseSentry added, which use the host's Sentry options, so is - /// ignored. + /// Apps that call UseSentry don't need this, because UseSentry already adds the logging integration. + /// If your app calls ClearProviders() after calling UseSentry that would also remove Sentry's logging + /// integration - in which case this method can be used to add Sentry's providers back again. The providers it adds + /// back use the host's Sentry options, so is ignored. /// /// The builder. /// The options configuration. diff --git a/src/Sentry.Extensions.Logging/SentryLoggingOptions.cs b/src/Sentry.Extensions.Logging/SentryLoggingOptions.cs index 817656d5c6..48284d6d7e 100644 --- a/src/Sentry.Extensions.Logging/SentryLoggingOptions.cs +++ b/src/Sentry.Extensions.Logging/SentryLoggingOptions.cs @@ -28,10 +28,10 @@ public class SentryLoggingOptions "logging through the host's Sentry options."; internal const string HostLoggerProvidersRemoved = - "Sentry's logger providers were removed after UseSentry added them, for example by ClearProviders(), so log " + - "entries from ILogger don't reach Sentry. Call AddSentry() on the logging builder after ClearProviders(), " + - "for example builder.Logging.AddSentry(), to add them back. If you send logs to Sentry through another " + - "integration, such as NLog, Serilog or log4net, you can ignore this."; + "Sentry's logger providers were removed after UseSentry added them, for example by ClearProviders(). If " + + "ILogger entries reach Sentry through another integration, such as NLog, Serilog or log4net, this is " + + "expected (it prevents duplicates being sent to Sentry). Otherwise if ILogger entries don't reach Sentry, you can " + + "call AddSentry() on the logging builder after ClearProviders()."; /// /// Not supported. The logging integration no longer initializes the SDK.