Cleanly resolving Serilog Pump ThreadAbortException on xunit.console.exe exit

341 Views Asked by At

I'm getting the following exception from xunit.console.exe when I shut down my app, which uses Serilog:

System.AggregateException: One or more errors occurred. ---> System.Threading.ThreadAbortException: Thread was being aborted.
   at Serilog.Sinks.Async.BackgroundWorkerSink.Pump()
   at System.Threading.Tasks.Task.Execute()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions)
   at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
   at Serilog.Sinks.Async.BackgroundWorkerSink.Dispose()
   at Serilog.LoggerConfiguration.<CreateLogger>b__28_0()
---> (Inner Exception #0) System.Threading.ThreadAbortException: Thread was being aborted.
   at Serilog.Sinks.Async.BackgroundWorkerSink.Pump()
   at System.Threading.Tasks.Task.Execute()<---

Yes, I've done some bold things (creating a Serilog WriteTo.Async-wrapped set of loggers), but I need to figure out the cleanest way to not provoke the exception and get back to clean test runs. (If there was a hook for Assembly Uninitialization, I'd call Log.CloseAndFlush() in it)

(Yes, I appreciate that a Unit Test should not be wiring up heavyweight logging, but I will still need to resolve the issue for integration tests)

(Will be self-answering when I suss it out; I just couldnt google up an answer and believe one should be able to)

1

There are 1 best solutions below

0
Ruben Bartelink On

There's no point not just fixing your code - the whole point of having tests is to listen to them ;)

In this specific instance, some code was statically building loggers/auditors that are pretty central to the apps behavior, which should have been surfaced as constructor dependencies, not hidden in static variables deep within in the first instance.

The reason I arrived at this point was that my app has cross-cutting logging requirements, sufficiently central to the throughput to result in my switching logging approaches - being forced into this pushes the management of the logs to a better place, which is a win (and hiding it would have been another step down the slippery slope of paying perf costs for incidental things in the context of a test).