Skip to content

Commit f2d8635

Browse files
Copilotbart-vmware
andauthored
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>
1 parent a2b3763 commit f2d8635

4 files changed

Lines changed: 31 additions & 7 deletions

File tree

src/Logging/src/DynamicConsole/LoggingBuilderExtensions.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ public static ILoggingBuilder AddDynamicConsole(this ILoggingBuilder builder)
3333
UpdateConsoleLoggerProviderRegistration(builder.Services);
3434

3535
builder.AddFilter<DynamicConsoleLoggerProvider>(null, LogLevel.Trace);
36-
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DynamicConsoleLoggerProvider>());
37-
builder.Services.AddSingleton(provider => provider.GetServices<ILoggerProvider>().OfType<IDynamicLoggerProvider>().Single());
36+
builder.Services.TryAddSingleton<DynamicConsoleLoggerProvider>();
37+
builder.Services.AddSingleton<ILoggerProvider>(serviceProvider => serviceProvider.GetRequiredService<DynamicConsoleLoggerProvider>());
38+
builder.Services.AddSingleton<IDynamicLoggerProvider>(serviceProvider => serviceProvider.GetRequiredService<DynamicConsoleLoggerProvider>());
3839

3940
DisableConsoleColorsOnCloudPlatform(builder);
4041
}

src/Logging/src/DynamicSerilog/SerilogLoggingBuilderExtensions.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
using Microsoft.Extensions.Logging;
99
using Microsoft.Extensions.Options;
1010
using Serilog;
11-
using Steeltoe.Common;
1211

1312
namespace Steeltoe.Logging.DynamicSerilog;
1413

@@ -94,17 +93,17 @@ public static ILoggingBuilder AddDynamicSerilog(this ILoggingBuilder builder, Lo
9493

9594
ConfigureSerilogOptions(builder, serilogConfiguration);
9695

97-
builder.Services.TryAddEnumerable(ServiceDescriptor.Singleton<ILoggerProvider, DynamicSerilogLoggerProvider>());
98-
builder.Services.AddSingleton(provider => provider.GetServices<ILoggerProvider>().OfType<IDynamicLoggerProvider>().Single());
96+
builder.Services.TryAddSingleton<DynamicSerilogLoggerProvider>();
97+
builder.Services.AddSingleton<ILoggerProvider>(serviceProvider => serviceProvider.GetRequiredService<DynamicSerilogLoggerProvider>());
98+
builder.Services.AddSingleton<IDynamicLoggerProvider>(serviceProvider => serviceProvider.GetRequiredService<DynamicSerilogLoggerProvider>());
9999
}
100100

101101
return builder;
102102
}
103103

104104
private static bool IsSerilogDynamicLoggerProviderAlreadyRegistered(ILoggingBuilder builder)
105105
{
106-
return builder.Services.Any(descriptor =>
107-
descriptor.SafeGetImplementationType() == typeof(DynamicSerilogLoggerProvider) && descriptor.ServiceType == typeof(ILoggerProvider));
106+
return builder.Services.Any(descriptor => descriptor.ServiceType == typeof(DynamicSerilogLoggerProvider));
108107
}
109108

110109
private static void AssertNoDynamicLoggerProviderRegistered(ILoggingBuilder builder)

src/Logging/test/DynamicConsole.Test/HostBuilderTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,18 @@ public async Task DisposeTwiceSucceeds()
203203
action.Should().NotThrow();
204204
}
205205

206+
[Fact]
207+
public async Task DoesNotCrashWhenLoggingProvidersAreCleared()
208+
{
209+
WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create();
210+
builder.Logging.AddDynamicConsole();
211+
builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders());
212+
await using WebApplication host = builder.Build();
213+
214+
host.Services.GetService<IDynamicLoggerProvider>().Should().BeOfType<DynamicConsoleLoggerProvider>();
215+
host.Services.GetServices<ILoggerProvider>().OfType<DynamicConsoleLoggerProvider>().Should().BeEmpty();
216+
}
217+
206218
private sealed class OtherDynamicLoggerProvider : IDynamicLoggerProvider
207219
{
208220
public ILogger CreateLogger(string categoryName)

src/Logging/test/DynamicSerilog.Test/HostBuilderTest.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -403,6 +403,18 @@ public async Task DisposeTwiceSucceeds()
403403
action.Should().NotThrow();
404404
}
405405

406+
[Fact]
407+
public async Task DoesNotCrashWhenLoggingProvidersAreCleared()
408+
{
409+
WebApplicationBuilder builder = TestWebApplicationBuilderFactory.Create();
410+
builder.Logging.AddDynamicSerilog();
411+
builder.Services.AddLogging(loggingBuilder => loggingBuilder.ClearProviders());
412+
await using WebApplication host = builder.Build();
413+
414+
host.Services.GetService<IDynamicLoggerProvider>().Should().BeOfType<DynamicSerilogLoggerProvider>();
415+
host.Services.GetServices<ILoggerProvider>().OfType<DynamicSerilogLoggerProvider>().Should().BeEmpty();
416+
}
417+
406418
public void Dispose()
407419
{
408420
_consoleOutput.Dispose();

0 commit comments

Comments
 (0)