'Serilog without using bootstrap/2-stage initialization
Serilog's AspNetCore package supports 2-stage initialization, by creating a logger configuration in the application Main method (calling CreateBootstrapLogger()) and then replacing that later in the Startup file (calling CreateLogger).
Hypothetically (or, you know, not hypothetically), will there be any problem if we're following this pattern, but aren't calling CreateBootstrapLogger() in the application Main method? Instead, we call CreateLogger in Main, then call CreateLogger again in Startup.cs and configure all the sinks, etc. that need access to application configuration.
We're trying to debug memory leak that we've never been able to reproduce locally. It's very possible that it's caused by one of the sinks we're using, or even something else entirely, but I'm trying to rule out mistakes with setting up Serilog.
We're seeing logs in the way we're expecting, so it's not that things aren't working at all...we just get regular out-of-memory issues that coincide with high logging activity.
To be very clear, this is what our setup looks like:
In Program.cs:
public class Program
{
public static void Main(string[] args)
{
// Set up initial logging. This will later be overwritten with more config in Startup.cs, once application configuration is available.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.MinimumLevel.Override("Microsoft", LogEventLevel.Information)
.Enrich.FromLogContext()
.WriteTo.Debug()
.CreateLogger();
try
{
Log.Information("Starting web host");
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.UseSerilog()
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.ConfigureKestrel(serverOptions =>
{
// Set properties and call methods on options
})
.UseStartup<Startup>();
});
}
Then, in the constructor of Startup.cs (which has the Configuration object injected):
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Information()
.MinimumLevel.Override("Microsoft", LogEventLevel.Fatal)
.Enrich.FromLogContext()
.WriteTo.Async(a => a.AzureBlobStorage(
Configuration.GetConnectionString("AzureBlobConnection"), // connectionString
LogEventLevel.Information, // restrictedToMinimumLevel
Configuration["AssetStore:Container"], // storageContainerName
"logs/{yyyy}-{MM}-{dd}.log", // storageFileName
null, // outputTemplate
false, // writeInBatches
null, // period
null, // batchPostingLimit
false, // bypassBlobCreationValidation
null, // formatProvider
null, // cloudBlobProvider
null, // blobSizeLimitBytes
30 // retainedBlobCountLimit
))
.CreateLogger();
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
