Matthew Chestnut is a Senior Consultant at ThreeWill. He has over 25 years of software development experience around enterprise and departmental business productivity applications. He has a proven track record of quality software development, on-budget project management and management of successful software development teams.
Introduction to Logging During Development Projects
I have been working on several applications lately using Angular and Vue.js frameworks on the front-end and .NET Core or .NET Standard in the middle-tier for SQL Server and MongoDB access. I am a huge fan of application logging, and I always add logging during development projects. I like structured logging even more! I tend to use Serilog (https://serilog.net/) along with Seq (https://datalust.co/seq) whenever possible.
Use Case
In this example, I want the ability to write structured logging information in Program.cs. This was not so much a business requirement, more of a desire to start the logging as soon as possible.
The standard dependency injection and appSettings.json configuration is available only after CreateHostBuilder starts executing, so there are some manual steps required to initialize logging before CreateHostBuilder gets started.
Implementation
Here is my version of Program.cs that implements the early initialization of logging so I can log application startup information, especially if errors occur at startup.
[ps]using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Serilog;
using System;
namespace ThreeWillTestApi
{
public class Program
{
public static void Main(string[] args)
{
var configuration = new ConfigurationBuilder()
.AddJsonFile("appsettings.json", optional: false, reloadOnChange: false)
.AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT")
?? "production"}.json", optional: true, reloadOnChange: false)
.AddEnvironmentVariables()
.Build();
Log.Logger = new LoggerConfiguration()
.ReadFrom.Configuration(configuration)
.CreateLogger();
try
{
// not using ILogger right now, using the static method
// just showing it’s possible to log
Log.Information("Starting web host in {SourceContext}", "MegatronApi.Program");
CreateHostBuilder(args).Build().Run();
}
catch (Exception ex)
{
Log.Fatal(ex, "Web host terminated unexpectedly");
}
finally
{
// log the stop, if normally closed, e.g. via Ctrl-C in Kestrel console window
Log.Information("Stopping web host in {SourceContext}", "MegatronApi.Program");
// push any pending log messages
Log.CloseAndFlush();
}
}
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>()
.UseUrls("http://localhost:5000");
})
.UseSerilog();
}
} [/ps]
Handy References
Logging during development projects takes a lot of background information, here you can see some of the references I love to use.
- Setting up Serilog in ASP.NET Core 3
- Serilog configuration settings