A few questions before you begin:

Does this issue relate to a new feature or an existing bug?

  • Bug
  • [x ] New Feature

What version of Serilog is affected? Please list the related NuGet package. v2.6.0

What is the target framework and operating system? See target frameworks & net standard matrix.

  • [x ] netCore 2.0
  • netCore 1.0
  • 4.7
  • 4.6.x
  • 4.5.x

Please describe the current behavior? Any pending writes can only be flushed by effectively disposing the entire log pipeline (usually at the end of the app).

Please describe the expected behavior? The ability to Flush pending writes in the sink pipeline and receive a notification (preferable using an Async pattern) once all pending writes have been written.

There are points in a program logic where it is desirable to know that log events prior to that point have been committed before proceeding. This would involve doing a Flush of some sort and waiting for the Flush to complete. Currently CloseAndFlush() or Dispose can only really be called at the end of the application because both effectively tear down the existing logging pipeline. It would be great if there was a way to Flush at an intermediary point.

Two suggestions on how one might think about this:

  1. Add a Flush method to ILogger. This would flush the pipeline and resolve when all pending writes are written. Since of course new writes may be introduced concurrently, the Flush represents a partial order for concurrent events, but should obey temporal causality for events written before the flush.
  2. Make ILogger IDisposable (instead of just Logger). Then sub-loggers could be created which when disposed would imply that all events written from that ILogger instances have been flushed. This provides a weaker order guarantee since it doesn’t say anything about log events that were written by other ILogger instances before the dispose event, but lends itself to hierarchical structuring better. (Of course this could still be achieved with try {...} finally { logger.Flush()} for case (1).

Since Flush necessitates blocking for I/O (either disk or network or both) it seems reasonable that this should implement some kind of async pattern (while individual log calls are expected to be buffered and likely return immediately). Ideally this would use Task (or ValueTask now that it is available generally), but since Serilog doesn’t currently incorporate any use of Task there might be better choices.

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:10
  • Comments:22 (11 by maintainers)

github_iconTop GitHub Comments

4reactions
MaxShoshincommented, Mar 1, 2018

Nicholas,

I can share our use case where Flush method will be very usefull:

void RestartApp()
{
    // Flush method instead Dispose will be very usefull here:
    _logger.Dispose(); 

    try
    {
        // During this method our process can be killed without any chance to dispose logger.
        // In our scenario in most cases our application killed here, so we need to dispose
        // logger in code above to be sure that all events are flushed
        ExitImmediatleyOrThrowException(); 
    }
    catch(Exception ex)
    {
        // But in some cases we got exception instead process kill:
        // we lost information about error as _logger already disposed
        _logger.Error(ex, "Error"); 
    }
}

In our case we it will be ok if some sinks drop events during flush in case of some kind failures.

Thank you!

2reactions
tippmarcommented, Sep 25, 2018

CloseAndFlush() works just fine for the ASP.NET Core app I’m working on. I’ve found, however, that I have to Sleep(2000) or so before the app terminates so that all the sinks can do their business.

    public static int Main(string[] args)
    {
        ConfigureLogging(); // set up Serilog

        try
        {
            Log.Logger.Information("Custom.API Server is starting.");
            var webHost = BuildWebHost(args);
            webHost.Run();

            Log.Logger.Information("Custom.API Server is starting.");
            return 0;
        }
        catch (Exception ex)
        {
            Log.Fatal(ex, "Host terminated unexpectedly.");
            return 1;
        }
        finally
        {
            Log.CloseAndFlush();
            Thread.Sleep(2000); // give serilog / seq time to flush the messages
        }
    }

`

Read more comments on GitHub >

github_iconTop Results From Across the Web

How to Flush Application Insights in a ILogger
Please try use the method InMemoryChannel.Flush , code sample as blow: using Microsoft.ApplicationInsights.Channel; using Microsoft.
Read more >
C# (CSharp) ILogger.Flush Examples
C# (CSharp) ILogger.Flush - 34 examples found. These are the top rated real world C# (CSharp) examples of ILogger.Flush extracted from open source...
Read more >
IConsole.Flush Method (Microsoft.Extensions.Logging. ...
This API supports the .NET infrastructure and is not intended to be used directly from your code. public: void Flush();. C# Copy. public...
Read more >
Something like flush function for logger?
I'm building escript and using logger but i have noticed that if my script finishes too fast not all log information is printed...
Read more >
Does LogManager.Flush() synchronously write all the logs ...
Flush (), we expect all pending logs to be written to the log file immediately. While actually the logs seems to be asynchronously...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found