Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

serilog async sink not flushing buffer to disk on shutdown

When using the serilog async sink with the file sink (and buffered = true), log entries are being lost on shutdown. I'm guessing it's the buffer not flushing to disk, even though it is being called. I'm not sure why this is happening, but I'm pretty certain it's the async sink. If I remove it from the config and just use the file sink on its own, the log gets flushed to disk as expected.

I've got a fairly simple setup.

program.cs:

 public class Program
{
    public static IConfiguration Configuration { get; } = new ConfigurationBuilder()
        .SetBasePath(Directory.GetCurrentDirectory())
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT") ?? "Production"}.json", optional: true)
        .AddEnvironmentVariables()
        .Build();

    public static void Main(string[] args)
    {

        Log.Logger = new LoggerConfiguration()
            .ReadFrom.Configuration(Configuration)
            .CreateLogger();

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

            CreateWebHostBuilder(args).Build().Run();

            Log.Information("Shutting down the web host");

        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly");

        }
        finally
        {
            Log.Information("Closing Log");

            Log.CloseAndFlush();
        }



    }

    public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
        WebHost.CreateDefaultBuilder(args)
            .UseStartup<Startup>()            
            .UseSerilog();

}

appsettings.json

    {
  "Serilog": {
    "MinimumLevel": {
      "Default": "Debug",
      "Override": {
        "Microsoft": "Information",
        "System": "Warning"
      }
    }
  },
  ...

appsettings.Development.json

{
  "Serilog": {
    "WriteTo": [
      {
        "Name": "Async",
        "Args": {
          "configure": [
            {
              "Name": "Console",
              "Args": {
                "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
                "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}"
              }
            },
            {
              "Name": "File",
              "Args": {
                "path": "logs/log.txt",
                "formatter": "Serilog.Formatting.Json.JsonFormatter",
                "rollingInterval": "Day",
                "retainedFileCountLimit": 7,
                "buffered": true
              }
            }
          ]
        }
      }
    ]
  }
}

If I put a breakpoint on the Log.CloseAndFlush() line it'll hit it when shutting down, but it doesn't actually flush the buffer to disk.

Any ideas?

like image 871
Bill Avatar asked Sep 19 '19 15:09

Bill


1 Answers

You will have to organize your config in below format.

"WriteTo": [
  {
    "Name": "Async",
    "Args": {
      "configure": [
        {
          "Name": "Console",
          "Args": {
            "theme": "Serilog.Sinks.SystemConsole.Themes.AnsiConsoleTheme::Code, Serilog.Sinks.Console",
            "outputTemplate": "[{Timestamp:HH:mm:ss} {Level:u3}] {Message:lj} <s:{SourceContext}>{NewLine}{Exception}"
          }
        }
      ]
    }
  },
  {
    "Name": "Async",
    "Args": {
      "configure": [
        {
          "Name": "File",
          "Args": {
            "path": "logs/log.txt",
            "formatter": "Serilog.Formatting.Json.JsonFormatter",
            "rollingInterval": "Day",
            "retainedFileCountLimit": 7,
            "buffered": true
          }
        }
      ]
    }
  }
]
like image 193
Prateek Avatar answered Oct 17 '22 16:10

Prateek