Created
November 3, 2021 20:06
-
-
Save bronumski/6289750d2c0ca20e0f1a315f0f4dc7b0 to your computer and use it in GitHub Desktop.
BufferedTextWriterSink
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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