I would like to log using Serilog. I want logging that only logs error or higher such that when the error is logged it includes the last 10 logs along with it.
I have made a proof of concept that works with the console. Here is the code. Circular buffer is a nuget package.
using CircularBuffer;
using Serilog.Core;
using Serilog.Events;
namespace ProminentMediaserilog;
public class ErrorWithRecentLogsSink : ILogEventSink
{
private readonly CircularBuffer<LogEvent> _recentLogs;
public ErrorWithRecentLogsSink(int capacity)
{
_recentLogs = new CircularBuffer<LogEvent>(capacity);
}
public void Emit(LogEvent logEvent)
{
if (logEvent.Level < LogEventLevel.Error)
{
_recentLogs.PushBack(logEvent);
return;
}
var recentLogs = string.Join(",", GetRecentLogs().Select(rl => GetLogMessage(rl)));
var message = $"{GetLogMessage(logEvent)}{Environment.NewLine}Recent Logs: {recentLogs}";
Console.WriteLine(message);
}
private string GetLogMessage(LogEvent logEvent)
{
return $"{logEvent.Timestamp:HH:mm:ss} {logEvent.Level} {logEvent.RenderMessage()}{Environment.NewLine}";
}
public LogEvent[] GetRecentLogs()
{
return _recentLogs.ToArray();
}
}
As you can see from the code when the log level is lower than error the logEvent is added to a Circular buffer which keeps the last 10 logs. And when the log is error it logs the error and the last 10 logs from the buffer.
What I would like however is the same code to work but saving logs to a file not writing them to the console. I could do similar to above and add my own logic to save the log message to a file but ideally I would like to achieve this using a sink that already exists such as file so I can take advantage of all the file options it has such as creating a new file for each unit of time.
Is this possible to do and if so how do would you go about doing it?