serilog-extensions-hosting icon indicating copy to clipboard operation
serilog-extensions-hosting copied to clipboard

BootstrapLogger and reading config from appsettings (using Serilog.Settings.Configuration) not playing well together

Open gthvidsten opened this issue 10 months ago • 3 comments

I'm following the example and have the following code:

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .CreateBootstrapLogger();

try
{
    Log.Information("Starting");

    HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
    builder.Services.AddSerilog((services, loggerConfiguration) =>
    {
        loggerConfiguration
            .ReadFrom.Configuration(builder.Configuration)
            .ReadFrom.Services(services);
    });

    IHost host = builder.Build();
    await host.RunAsync();

    Log.Information("Stopping");
}
catch (Exception ex)
{
    Log.Fatal(ex, "Failing");
}
finally
{
    await Log.CloseAndFlushAsync();
}

And this appsettings.json:

{
  "Serilog": {
    "Using": [ "Serilog.Sinks.File" ],
    "WriteTo": [
      {
        "Name": "File",
        "Args": {
          "path": "Filename.log",
          "fileSizeLimitBytes": "10485760",
          "rollingInterval": "Day",
          "rollOnFileSizeLimit": true,
          "retainedFileCountLimit": 30
        }
      }
    ],
    "Enrich": [ "FromLogContext" ]
  }
}

Using the following packages:

<PackageReference Include="Serilog.Extensions.Hosting" Version="8.0.0" />
<PackageReference Include="Serilog.Settings.Configuration" Version="8.0.0" />
<PackageReference Include="Serilog.Sinks.Console" Version="5.0.1" />
<PackageReference Include="Serilog.Sinks.File" Version="5.0.0" />

When starting this I would expect all the messages appearing in Filename.log, but the "Starting" message appears in the Console. Everything else appears in the file as expected. Why doesn't the "Starting" message appear in the log file, and what can I do to have everything appear in the file? (and everything logged to console if something fails)

gthvidsten avatar Apr 10 '24 13:04 gthvidsten

Hi @gthvidsten; at the point Log.Information("Starting") is called, the bootstrap logger hasn't been reconfigured to write to the file, yet.

If you can move everything to the initial LoggerConfiguration (and customize the file path using environment variables, perhaps?) you can get around this:

Log.Logger = new LoggerConfiguration()
    .Enrich.FromLogContext()
    .WriteTo.Console()
    .WriteTo.File(...)
    .CreateLogger();

try
{
    Log.Information("Starting");

    HostApplicationBuilder builder = Host.CreateApplicationBuilder(args);
    builder.Services.AddSerilog();

    IHost host = builder.Build();
    await host.RunAsync();

    Log.Information("Stopping");
}
catch (Exception ex)
{
    Log.Fatal(ex, "Failing");
}
finally
{
    await Log.CloseAndFlushAsync();
}

nblumhardt avatar Apr 15 '24 00:04 nblumhardt

Thanks for the reply. I really don't want to have to read configurations this soon in the startup, but I see I might have been mistaken about how the BootstrapLogger is working:

I thought that it would create a logger, but not log anything to it until .AddSerilog() had been properly called, so that any messages logged before this would be cached and written to the correct place when it was available, and writing to the defaults only happens if something went wrong.

For now I may just remove the "Starting" message alltogether, though I'm open to other suggestions, of course :)

gthvidsten avatar Apr 15 '24 08:04 gthvidsten

The buffering style of design would be very interesting to explore, but you're correct - that's not how CreateBootstrapLogger() works today.

nblumhardt avatar Apr 15 '24 22:04 nblumhardt