ASP .NET Core Logging with Serilog

The de facto loggers in the .NET space have historically been log4net and NLog. Along comes Serilog and it has a more metadata"y" approach that they describe as structured events. Serilog fits in extremely well with modern aggregated logging services like Elastisearch, Loggly, etc...

Logging Goals:

  • Upon application start, log an Informational started message before doing any other work
  • Any process exceptions should be logged as Fatal
  • Log to a file and keep the last 30 days of logs
  • Production logging should be set to Informational
// Install-Package Serilog.AspNetCore
// Install-Package Serilog.Sinks.Console
// Install-Package Serilog.Sinks.RollingFile
// Install-Package Serilog.Sinks.Async
// This code is slightly modified from https://nblumhardt.com/2017/08/use-serilog/

public class Program
{
    public static int Main(string[] args)
    {
        Log.Logger = new LoggerConfiguration()
            .MinimumLevel.Information()
            .MinimumLevel.Override("Microsoft", LogEventLevel.Warning) // Warning level will exclude individual requests
            .Enrich.FromLogContext()
            .WriteTo.Console()
            // RollingFile defaults to 31 days and a max file size of 1GB
            .WriteTo.Async(a => a.RollingFile("logs/myapp-{Date}.log", LogEventLevel.Information)) // Good idea to wrap any file sinks in an Async sink
            .CreateLogger();

        try
        {
            Log.Information("Starting web host");

            var host = new WebHostBuilder()
                .UseKestrel()
                .UseIISIntegration()
                .UseContentRoot(Directory.GetCurrentDirectory())
                .UseStartup<Startup>()
                .UseSerilog()  // Sets Serilog as the logging provider
                .Build();

            host.Run();

            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
        }
    }
}