using System; using System.Threading.Tasks; using System.Threading.Tasks.Dataflow; namespace Sony.Filtr.Tasks.Helpers { public class AsyncLogger { private readonly LoggerAdapter Logger; private ActionBlock, Action>>> LogProcessor; private ActionBlock, Action>>> LogProcessorErrorWithException; public static AsyncLogger GetLogger(string name) { return new AsyncLogger(LoggerAdapter.GetLogger(name)); } public AsyncLogger(LoggerAdapter logger, int maxDegreeOfParallelism = 1) { this.Logger = logger; this.LogProcessor = new ActionBlock<(Func, Action>)>( tuple => tuple.Item2(tuple.Item1), new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism, EnsureOrdered = true }); this.LogProcessorErrorWithException = new ActionBlock<(Exception, Func, Action>)>( tuple => tuple.Item3(tuple.Item1, tuple.Item2), new ExecutionDataflowBlockOptions() { MaxDegreeOfParallelism = maxDegreeOfParallelism, EnsureOrdered = true } ); } public Task TraceAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Trace)); } public Task DebugAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Debug)); } public Task WarnAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Warn)); } public Task InfoAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Information)); } public Task ErrorAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Error)); } public Task ErrorAsync(Exception ex, Func getMessage) { return this.LogProcessorErrorWithException.SendAsync((ex, getMessage, this.Logger.Error)); } public Task FatalAsync(Func getMessage) { return this.LogProcessor.SendAsync((getMessage, this.Logger.Fatal)); } public Task Complete() { this.LogProcessor.Complete(); this.LogProcessorErrorWithException.Complete(); return Task.WhenAll(this.LogProcessor.Completion, this.LogProcessorErrorWithException.Completion); } } }