Open edmacdonald opened 3 years ago
I am experiencing a similar issue when using .AddAzureClients
from the Microsoft.Extensions.Azure
NuGet package. Did you figure out how to work around this?
I just ditched the two-stage init. I came to the conclusion it's not that important to me and creates more issues than it solves. Initialization changes infrequently, errors outside development are rare, and when they do happen I make sure they fail spectacularly and if need be I can look at a file log on the host. I don't need them sent to kinesis.
I believe I bump into the same issue - custom service that needs ILogger<T>
dependency:
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateBootstrapLogger();
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<FooService>();
builder.Host.UseSerilog((context, services, configuration) =>
{
var service = services.GetRequiredService<FooService>();
});
builder.Build().Run();
public class FooService
{
private readonly ILogger<FooService> _logger;
public FooService(ILogger<FooService> logger)
=> _logger = logger;
}
NET 6
, web application scaffolded by VS, the following packages added:
Serilog.AspNetCore 6.1.0
This gets stuck in an infinite loop like OP described. In me specific case thread dies after 252 iterations and the app never starts...
Shouldn't a bootstrap logger be used initially in such case - this would've solved the isssue I believe?
The same exact thing happens when using pre-net6 configuration via GenericHost
:
using Serilog;
Log.Logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateBootstrapLogger();
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.UseSerilog((context, services, configuration) =>
{
var service = services.GetRequiredService<FooService>();
})
.Build()
.Run();
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<FooService>();
}
public void Configure(IApplicationBuilder app) { }
}
Well, this is far far from ideal, but I've come up with builing GenericHost
first, resolving services from there and then building another GenericHost
this time with .UseSerilog()
and use built ServiceProvider there.
Note: this solution is for pre-net6
Program.cs
but I could imagine a similar approach could be taken withWebApplicationBuilder
Note: this causes a noticable performace hit on application startup, so use with caution
// ...
var serviceProvider = Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.Build()
.Services;
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup<Startup>())
.UseSerilog((context, _, configuration) =>
{
var service = serviceProvider.GetRequiredService<FooService>();
})
.Build()
.Run();
// ...
If you use the
Two-stage initialization
from here: https://github.com/serilog/serilog-aspnetcore#two-stage-initializationand configure a KinesisFirehoseSink like so...
You end up in an infinite loop because the
IAmazonKinesisFirehose
factory is looking for anILoggerFactory
.