structured-logging.jpg

ASP.NET Core Structured Logging

Introduction to ASP.NET Core Structured Logging

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. I always add logging to my projects early in the development cycle. 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. 

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(); 
  } 
} 

Handy References 

Matthew ChestnutASP.NET Core Structured Logging

Join the conversation

This site uses Akismet to reduce spam. Learn how your comment data is processed.