Skip to content

Instantly share code, notes, and snippets.

@bronumski
Created November 3, 2021 20:06
Show Gist options
  • Save bronumski/6289750d2c0ca20e0f1a315f0f4dc7b0 to your computer and use it in GitHub Desktop.
Save bronumski/6289750d2c0ca20e0f1a315f0f4dc7b0 to your computer and use it in GitHub Desktop.
BufferedTextWriterSink
class BufferedTextWriterSink : ILogEventSink, IDisposable
{
private readonly LogEventLevel? standardErrorFromLevel;
private readonly ITextFormatter formatter;
private readonly object _syncRoot = new();
private readonly TextWriter standardWriter;
private readonly TextWriter errorWriter;
private readonly ConcurrentBag<LogEvent> logEvents = new();
public BufferedTextWriterSink(
ITextFormatter formatter = null,
LogEventLevel? standardErrorFromLevel = LogEventLevel.Debug,
TextWriter standardWriter = null,
TextWriter errorWriter = null)
{
this.standardErrorFromLevel = standardErrorFromLevel;
this.formatter = formatter ?? new Serilog.Formatting.Display.MessageTemplateTextFormatter(
"[{Level:u3}] <{SourceContext}> - {Message:lj}{NewLine}{Exception}", CultureInfo.InvariantCulture );
this.standardWriter = standardWriter ?? Console.Out;
this.errorWriter = errorWriter ?? this.standardWriter ?? Console.Error;
}
public void Emit( LogEvent logEvent )
{
logEvents.Add(logEvent);
}
public void FlushToConsole() =>
logEvents
.OrderBy( l => l.Timestamp )
.ToList()
.ForEach(RenderEvent);
private void RenderEvent( LogEvent logEvent )
{
TextWriter output = SelectOutputStream(logEvent.Level);
object syncRoot = this._syncRoot;
bool lockTaken = false;
try
{
Monitor.Enter( syncRoot, ref lockTaken );
formatter.Format( logEvent, output );
output.Flush();
}
finally
{
if( lockTaken )
Monitor.Exit( syncRoot );
}
}
public void Dispose() => FlushToConsole();
private TextWriter SelectOutputStream(LogEventLevel logEventLevel) =>
( logEventLevel, standardErrorFromLevel.GetValueOrDefault() ) switch
{
_ when standardErrorFromLevel.HasValue is false => standardWriter,
var (eventLevel, @default) when eventLevel >= @default => errorWriter,
_ => standardWriter
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment