|
internal static class LogHelper |
|
{ |
|
private static readonly AsyncLocal<Guid> TestCorrelationId = new AsyncLocal<Guid>(); |
|
private static readonly ConcurrentDictionary<Guid, XUnitBddfyTextReporter> BddfyTextReporterLookup = new ConcurrentDictionary<Guid, XUnitBddfyTextReporter>(); |
|
private static readonly ConcurrentDictionary<Guid, ITestOutputHelper> LoggerLookup = new ConcurrentDictionary<Guid, ITestOutputHelper>(); |
|
private static readonly ConcurrentDictionary<Guid, ILogger> SerilogLookup = new ConcurrentDictionary<Guid, ILogger>(); |
|
|
|
public static IDisposable Capture(ITestOutputHelper outputHelper) |
|
{ |
|
if (outputHelper == null) |
|
throw new ArgumentNullException(nameof(outputHelper)); |
|
|
|
var correlationId = Guid.NewGuid(); |
|
LoggerLookup.TryAdd(correlationId, outputHelper); |
|
BddfyTextReporterLookup.TryAdd(correlationId, new XUnitBddfyTextReporter()); |
|
SerilogLookup.TryAdd(correlationId, CreateLogger()); |
|
|
|
TestCorrelationId.Value = correlationId; |
|
|
|
return new DelegateDisposable(() => |
|
{ |
|
LoggerLookup.TryRemove(correlationId, out ITestOutputHelper removedHelper); |
|
BddfyTextReporterLookup.TryRemove(correlationId, out XUnitBddfyTextReporter removedBddfyTextReporter); |
|
SerilogLookup.TryRemove(correlationId, out ILogger removedLogger); |
|
}); |
|
} |
|
|
|
public static bool TryGetTestOutputHelper(out ITestOutputHelper testOutputHelper) |
|
{ |
|
return LoggerLookup.TryGetValue(TestCorrelationId.Value, out testOutputHelper); |
|
} |
|
|
|
public static bool TryBddfyReporter(out XUnitBddfyTextReporter reporter) |
|
{ |
|
return BddfyTextReporterLookup.TryGetValue(TestCorrelationId.Value, out reporter); |
|
} |
|
|
|
public static bool TryGetLogger(out ILogger logger) |
|
{ |
|
return SerilogLookup.TryGetValue(TestCorrelationId.Value, out logger); |
|
} |
|
|
|
static LogHelper() |
|
{ |
|
Configurator.Processors.Add(() => |
|
{ |
|
TryBddfyReporter(out XUnitBddfyTextReporter reporter); |
|
return reporter; |
|
}); |
|
} |
|
|
|
private static ILogger CreateLogger() |
|
{ |
|
return new LoggerConfiguration() |
|
.MinimumLevel.Debug() |
|
.MinimumLevel.Override("IdentityServer", LogEventLevel.Warning) |
|
.MinimumLevel.Override("Microsoft", LogEventLevel.Fatal) |
|
.MinimumLevel.Override("System", LogEventLevel.Warning) |
|
.Enrich.WithDemystifiedStackTraces() |
|
.WriteTo.Sink<XUnitLogContextSink>() |
|
.WriteTo.LiterateConsole() |
|
.CreateLogger(); |
|
} |
|
|
|
private class DelegateDisposable : IDisposable |
|
{ |
|
public DelegateDisposable(Action action) |
|
{ |
|
_action = action; |
|
} |
|
|
|
public void Dispose() |
|
{ |
|
_action(); |
|
} |
|
|
|
private readonly Action _action; |
|
} |
|
} |