Skip to content

A bootstrap logger #28

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Oct 8, 2020
Merged

A bootstrap logger #28

merged 4 commits into from
Oct 8, 2020

Conversation

nblumhardt
Copy link
Member

We want to configure Serilog as soon as possible during program start-up, so that errors during start-up are logged. But, many logging-relevant services are not available until part-way through host bootstrapping. Instead of being stuck with an either/or choice, this PR attempts to address both requirements:

  1. During start-up, a special "bootstrap logger" is assigned to the static Log.Logger
  2. Later, once host services are available, the bootstrap logger is reconfigured and then frozen

Overall, there should be no regressions for existing code, since this mechanism is opt-in using the new bootstrap logger type (though I've taken the liberty of updating minimum framework/dependency versions, which is a breaking change).

Code using this path should suffer little to no performance penalty, since the Logger that ends up registered with the host is the underlying frozen/final logger.

Example

There's a web application example included in the changeset. Its Program.cs looks like this:

public static class Program
{
    public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .WriteTo.Console()
            .CreateBootstrapLogger();
        
        Log.Information("Starting up!");

        try
        {
            CreateHostBuilder(args).Build().Run();

            Log.Information("Stopped cleanly");
            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "An unhandled exception occured during bootstrapping");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseSerilog((context, services, configuration) => configuration
                .WriteTo.Console()
                .ReadFrom.Configuration(context.Configuration)
                .ReadFrom.Services(services))
            .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); });
}

Initially, a console logger is configured. Note the use of CreateBootstrapLogger(), a new method in this PR.

We write an event through it, and if bootstrapping fails, we'll also write the exception to it. The initial logger could be configured using any combination of sinks, etc.

Then, in CreateHostBuilder(), the logger is reconfigured: we again add Console, but also read from appSettings.json to add a file logger, and inject sinks etc. from the IServiceProvider (also a new method, here).

The output to the console is:

[17:04:19 INF] Starting up!
[17:04:19 INF] Now listening on: https://localhost:5001
[17:04:19 INF] Now listening on: http://localhost:5000
[17:04:19 INF] Application started. Press Ctrl+C to shut down.
[17:04:19 INF] Hosting environment: Development
[17:04:19 INF] Content root path: C:\Development\nblumhardt\serilog-extensions-hosting\samples\WebApplicationSample
[17:04:19 INF] Saying hello
[17:04:52 INF] Application is shutting down...
[17:04:52 INF] Stopped cleanly

Note the initial "Starting up!".

The output to the log file is:

2020-10-07 17:04:19.669 +10:00 [INF] Now listening on: https://localhost:5001
2020-10-07 17:04:19.699 +10:00 [INF] Now listening on: http://localhost:5000
2020-10-07 17:04:19.700 +10:00 [INF] Application started. Press Ctrl+C to shut down.
2020-10-07 17:04:19.701 +10:00 [INF] Hosting environment: Development
2020-10-07 17:04:19.702 +10:00 [INF] Content root path: C:\Development\nblumhardt\serilog-extensions-hosting\samples\WebApplicationSample
2020-10-07 17:04:19.979 +10:00 [INF] Saying hello
2020-10-07 17:04:52.511 +10:00 [INF] Application is shutting down...
2020-10-07 17:04:52.532 +10:00 [INF] Stopped cleanly

Note the final "Stopped cleanly" - the reconfigured logger outlives the host.

@nblumhardt
Copy link
Member Author

@serilog/reviewers-core I think this is ready to go :-)

Copy link
Member

@adamchester adamchester left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@nblumhardt
Copy link
Member Author

Thanks @adamchester

@nblumhardt nblumhardt merged commit ffb726b into serilog:dev Oct 8, 2020
@adamchester
Copy link
Member

Thanks @adamchester

Thank you for the awesome new feature 🥇

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants