public void Log <TState>(MSLogLevel logLevel, EventId eventId, TState state, Exception exception,
                                     Func <TState, Exception, string> formatter)
            {
                var lvl = logLevel switch
                {
                    MSLogLevel.Trace => LogLevel.Debug,
                    MSLogLevel.Debug => LogLevel.Debug,
                    // EFCore feels the need to log individual DB commands as "Information" so I'm slapping debug on it.
                    MSLogLevel.Information => LogLevel.Debug,
                    MSLogLevel.Warning => LogLevel.Warning,
                    MSLogLevel.Error => LogLevel.Error,
                    MSLogLevel.Critical => LogLevel.Fatal,
                    MSLogLevel.None => LogLevel.Debug,
                    _ => LogLevel.Debug
                };

                _sawmill.Log(lvl, formatter(state, exception));
            }
        private async Task ListenerThread(CancellationToken cancel)
        {
            try
            {
                while (!cancel.IsCancellationRequested)
                {
                    var getContextTask = _listener.GetContextAsync();
                    var ctx            = await getContextTask.WaitAsync(cancel);

                    // Task.Run this so it gets run on another thread pool thread.
                    _ = Task.Run(async() =>
                    {
                        var resp = ctx.Response;
                        var req  = ctx.Request;
                        try
                        {
                            var stream = resp.OutputStream;
                            // prometheus-net is a terrible library and have to do all this insanity,
                            // just to handle the ScrapeFailedException correctly.
                            // Ridiculous.
                            await _registry.CollectAndExportAsTextAsync(new WriteWrapStream(() =>
                            {
                                resp.ContentType = "text/plain; version=0.0.4; charset=utf-8";
                                resp.StatusCode  = 200;

                                var acceptEncoding = req.Headers["Accept-Encoding"];
                                var gzip           = acceptEncoding != null && acceptEncoding.Contains("gzip");

                                if (gzip)
                                {
                                    stream = new GZipStream(stream, CompressionLevel.Fastest);
                                    resp.Headers["Content-Encoding"] = "gzip";
                                }

                                return(stream);
                            }), cancel);

                            await stream.DisposeAsync();
                        }
                        catch (ScrapeFailedException e)
                        {
                            resp.StatusCode = 503;
                            if (!string.IsNullOrWhiteSpace(e.Message))
                            {
                                await using var sw = new StreamWriter(resp.OutputStream);
                                await sw.WriteAsync(e.Message);
                            }
                        }
                        catch (OperationCanceledException)
                        {
                            // Nada.
                        }
                        catch (Exception e)
                        {
                            _sawmill.Log(LogLevel.Error, e, "Exception in metrics listener");

                            resp.StatusCode = 500;
                        }
                        finally
                        {
                            resp.Close();
                        }
                    }, CancellationToken.None);
                }
            }
            finally
            {
                _listener.Stop();
                _listener.Close();
            }
        }