Here's another example, I'm hoping this provides a complete example for anyone in need:
- .NET 7 Console App
- Microsoft Generic Host with top-level statements
- Uses a Bootstrap Logger for capturing startup exceptions
- Loads the Logger from IConfiguration
Program.cs
using ConsoleUI;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using Serilog;
using Serilog.Core;
using Serilog.Events;
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Override("Default", LogEventLevel.Debug)
.Enrich.FromLogContext()
.WriteTo.Console()
.CreateBootstrapLogger();
try
{
HostApplicationBuilder builder = Host.CreateApplicationBuilder();
builder.Services.AddLogging(config =>
{
config.ClearProviders();
Logger logger = new LoggerConfiguration()
.ReadFrom.Configuration(builder.Configuration)
.CreateLogger();
config.AddSerilog(logger);
});
builder.Services.AddHostedService<App>();
IHost app = builder.Build();
app.Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Host terminated unexpectedly");
}
finally
{
Log.CloseAndFlush();
}
appsettings.json
{
"Serilog": {
"Using": [ "Serilog.Sinks.Console", "Serilog.Sinks.File" ],
"MinimumLevel": {
"Default": "Information",
"Override": {
"System": "Information",
"Microsoft": "Information",
"Microsoft.AspNetCore": "Information",
"Microsoft.EntityFrameworkCore": "Information",
"Azure": "Information"
}
},
"WriteTo": [
{
"Name": "Console",
"Args": {
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}|{Level:u3}|{SourceContext}|{Message:lj}{NewLine}{Exception}"
}
},
{
"Name": "File",
"Args": {
"path": "logs/ConsoleUI-.log",
"rollingInterval": "Day",
"retainedFileCountLimit": 15,
"outputTemplate": "{Timestamp:yyyy-MM-dd HH:mm:ss.fff zzz}|{Level:u3}|{SourceContext}|{Message:lj}{NewLine}{Exception}"
}
}
],
"Enrich": [ "FromLogContext", "WithMachineName" ],
"Properties": {
"Application": "ConsoleUI"
}
}
}
App.cs
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
namespace ConsoleUI;
public class App : IHostedService
{
private readonly IHostApplicationLifetime _hostApplicationLifetime;
private readonly IConfiguration _config;
private readonly ILogger<App> _logger;
public App(IHostApplicationLifetime hostApplicationLifetime,
IConfiguration configuration,
ILogger<App> logger)
{
_hostApplicationLifetime = hostApplicationLifetime;
_config = configuration;
_logger = logger;
}
public Task StartAsync(CancellationToken cancellationToken)
{
_hostApplicationLifetime.ApplicationStarted.Register(async () =>
{
try
{
await Task.Yield(); // https://github.com/dotnet/runtime/issues/36063
await Task.Delay(1000); // Additional delay for Microsoft.Hosting.Lifetime messages
await ExecuteAsync();
}
catch (Exception ex)
{
_logger.LogError(ex, "Unhandled exception!");
}
finally
{
_hostApplicationLifetime.StopApplication();
}
});
return Task.CompletedTask;
}
public Task StopAsync(CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
public async Task ExecuteAsync()
{
_logger.LogTrace("Hello, Trace!");
_logger.LogDebug("Hello, Debug!");
_logger.LogInformation("Hello, World!");
_logger.LogWarning("Hello, Warning!");
_logger.LogError("Hello, Error!");
_logger.LogCritical("Hello, Critical!");
await Task.Delay(1);
}
}
Nuget Packages

Output
