Serilog and seq when no server available

Viewed 1053

What is the expected behavior when an application that uses Serilog and Seq can't find a server to send the logs to? Will every attempt to log throw an exception?

I would like my app to use the Seq server if it's available, but still continue to run and log to file if it is not.

enter image description here

2 Answers

What is the expected behavior when an application that uses Serilog and Seq can't find a server to send the logs to?

It depends if your are using a regular sink (via .WriteTo) or an auditing sink (via .AuditTo).

Writing to a regular sink is meant to be a safe operation and never throw exceptions, and that's by design. Thus any exceptions that happen when sending those messages would only appear in the SelfLog if you enable it.

e.g.

// Write Serilog errors to the Console
Serilog.Debugging.SelfLog.Enable(msg => Console.WriteLine(msg));

The example above is, of course, just to illustrate the SelfLog feature... You'd choose if/where/how to display or store these error messages.

Writing to an auditing sink, you'd expect to see an error for each message that fails.

Will every attempt to log throw an exception?

It depends on the Sink. In the case of Serilog.Sinks.Seq, it's a periodic batching sink, so it will try to send messages in batches of X log events (X is configurable) so if the Seq server is not available, you'd expect to see an error per each batch that fails to send.

I would like my app to use the Seq server if it's available, but still continue to run and log to file if it is not.

The Seq sink has in-memory buffering and retry support to handle short periods of server or network unavailability, which is usually enough for most applications.

Alternatively, the Seq sink has durable log shipping baked-in, and you can specify a file on disk where it's going to store buffered messages on a file on disk, so it can try again even if your app is restarted.

Log.Logger = new LoggerConfiguration()
    .WriteTo.Seq("https://my-seq-server:5341",
        bufferBaseFilename: @"C:\MyApp\Logs\myapp") // <<<<<<
    .CreateLogger();

Finally, another alternative is to use Seq Forwarder that you can install side-by-side with your app (i.e. same server) and you write the logs directly to it and it takes care of persisting them to its own internal local storage and forwarding them to a remote Seq server when it becomes available.

diagram Seq Forwarder

Serilog has a strong guarantee of never throwing to the logging thread (exceptions from forwarding like you cite are emitted via SelfLog)

It's not common and/or there is no natural way to say "Seq but fall back to file" out of the box - a batching sink holds things and eventually drops things to avoid running out of memory.

The README of https://github.com/serilog/serilog-sinks-async is probably worth a read if you're considering what semantics you really want regarding File and/or Server. (Perhaps if you're in a hosted env with health checks, you might consider an inability to forward logs to be an indicator of ill-health - the obvious problem in that case is that any replacement instance likely would not fare any better). Also this Best practices Guide might help you think through what you really want.

Unfortunately you're better off splitting your questions into individual ones to aid actually answering here.

Related