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(); } }