From a2b376398b2dd793ea9fd51b5250468d4a95eb5f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 10:45:19 +0000 Subject: [PATCH 1/4] Initial plan From f2d86353a1067fe638241414424be196f41dbae2 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 11:15:57 +0000 Subject: [PATCH 2/4] Fix crash when logging providers are cleared after AddDynamicConsole/AddDynamicSerilog Register the concrete provider type as a standalone singleton so that IDynamicLoggerProvider remains resolvable even when ClearProviders() is called after the dynamic logging setup. Previously, IDynamicLoggerProvider was resolved via a factory that searched through ILoggerProvider services using .Single(), which threw when ClearProviders() removed them. Agent-Logs-Url: https://github.com/SteeltoeOSS/Steeltoe/sessions/9b9035c5-5b65-49bc-b0dd-a2e9cdd0fd14 Co-authored-by: bart-vmware <104792814+bart-vmware@users.noreply.github.com> --- .../src/DynamicConsole/LoggingBuilderExtensions.cs | 5 +++-- .../SerilogLoggingBuilderExtensions.cs | 9 ++++----- .../test/DynamicConsole.Test/HostBuilderTest.cs | 12 ++++++++++++ .../test/DynamicSerilog.Test/HostBuilderTest.cs | 12 ++++++++++++ 4 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs b/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs index 9bb66887ef..5a193615d0 100644 --- a/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs +++ b/src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs @@ -33,8 +33,9 @@ public static ILoggingBuilder AddDynamicConsole(this ILoggingBuilder builder) UpdateConsoleLoggerProviderRegistration(builder.Services); builder.AddFilter(null, LogLevel.Trace); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - builder.Services.AddSingleton(provider => provider.GetServices().OfType().Single()); + builder.Services.TryAddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); DisableConsoleColorsOnCloudPlatform(builder); } diff --git a/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs b/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs index c01090d0ca..0041a8c83f 100644 --- a/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs +++ b/src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs @@ -8,7 +8,6 @@ using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using Serilog; -using Steeltoe.Common; namespace Steeltoe.Logging.DynamicSerilog; @@ -94,8 +93,9 @@ public static ILoggingBuilder AddDynamicSerilog(this ILoggingBuilder builder, Lo ConfigureSerilogOptions(builder, serilogConfiguration); - builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton()); - builder.Services.AddSingleton(provider => provider.GetServices().OfType().Single()); + builder.Services.TryAddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); } return builder; @@ -103,8 +103,7 @@ public static ILoggingBuilder AddDynamicSerilog(this ILoggingBuilder builder, Lo private static bool IsSerilogDynamicLoggerProviderAlreadyRegistered(ILoggingBuilder builder) { - return builder.Services.Any(descriptor => - descriptor.SafeGetImplementationType() == typeof(DynamicSerilogLoggerProvider) && descriptor.ServiceType == typeof(ILoggerProvider)); + return builder.Services.Any(descriptor => descriptor.ServiceType == typeof(DynamicSerilogLoggerProvider)); } private static void AssertNoDynamicLoggerProviderRegistered(ILoggingBuilder builder) diff --git a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs index 0244891b5d..fe2c57c6e2 100644 --- a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs @@ -203,6 +203,18 @@ public async Task DisposeTwiceSucceeds() action.Should().NotThrow(); } + [Fact] + public async Task DoesNotCrashWhenLoggingProvidersAreCleared() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Logging.AddDynamicConsole(); + builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders()); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().BeEmpty(); + } + private sealed class OtherDynamicLoggerProvider : IDynamicLoggerProvider { public ILogger CreateLogger(string categoryName) diff --git a/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs b/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs index 151b001ca2..714f1c7fc1 100644 --- a/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs @@ -403,6 +403,18 @@ public async Task DisposeTwiceSucceeds() action.Should().NotThrow(); } + [Fact] + public async Task DoesNotCrashWhenLoggingProvidersAreCleared() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Logging.AddDynamicSerilog(); + builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders()); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().BeEmpty(); + } + public void Dispose() { _consoleOutput.Dispose(); From 7b476712f979c0e2bcac0e3904165b7d0d85583f Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 12:00:08 +0000 Subject: [PATCH 3/4] Add test verifying third-party IDynamicLoggerProvider extensibility Agent-Logs-Url: https://github.com/SteeltoeOSS/Steeltoe/sessions/daa346d0-4279-4e7d-b1b1-e906e2e04020 Co-authored-by: bart-vmware <104792814+bart-vmware@users.noreply.github.com> --- .../test/DynamicConsole.Test/HostBuilderTest.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs index fe2c57c6e2..b294e09a16 100644 --- a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs @@ -53,6 +53,17 @@ public async Task DoesNotRegisterWhenOtherDynamicProviderIsAlreadyRegistered() host.Services.GetServices().Should().NotContain(provider => provider is DynamicConsoleLoggerProvider); } + [Fact] + public async Task CanUseThirdPartyDynamicLoggerProvider() + { + WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); + builder.Services.AddSingleton(); + builder.Logging.AddDynamicConsole(); + await using WebApplication host = builder.Build(); + + host.Services.GetService().Should().BeOfType(); + } + [Fact] public async Task CanChangeMinimumLogLevels() { From 9480d4fa961ab69d517a639be3f73321188a152e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 16 Apr 2026 13:32:28 +0000 Subject: [PATCH 4/4] Update CanUseThirdPartyDynamicLoggerProvider test to also assert ILoggerProvider behavior Agent-Logs-Url: https://github.com/SteeltoeOSS/Steeltoe/sessions/0abdafc7-d2c6-4eea-bb74-cf1283bd7ed7 Co-authored-by: bart-vmware <104792814+bart-vmware@users.noreply.github.com> --- src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs index b294e09a16..c96a1a5bf5 100644 --- a/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs +++ b/src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs @@ -6,6 +6,7 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; +using Microsoft.Extensions.Logging.Abstractions; using Microsoft.Extensions.Logging.Console; using Microsoft.Extensions.Options; using Steeltoe.Common.Logging; @@ -57,11 +58,15 @@ public async Task DoesNotRegisterWhenOtherDynamicProviderIsAlreadyRegistered() public async Task CanUseThirdPartyDynamicLoggerProvider() { WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create(); - builder.Services.AddSingleton(); + builder.Services.AddSingleton(); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); + builder.Services.AddSingleton(serviceProvider => serviceProvider.GetRequiredService()); builder.Logging.AddDynamicConsole(); await using WebApplication host = builder.Build(); host.Services.GetService().Should().BeOfType(); + host.Services.GetServices().OfType().Should().ContainSingle(); + host.Services.GetServices().Should().NotContain(provider => provider is DynamicConsoleLoggerProvider); } [Fact] @@ -230,7 +235,7 @@ private sealed class OtherDynamicLoggerProvider : IDynamicLoggerProvider { public ILogger CreateLogger(string categoryName) { - throw new NotSupportedException(); + return NullLogger.Instance; } public ICollection GetLogLevels()