private void StartLoop(IScheduler scheduler) { //delegate allocations below - but that's fine as it's not really on the "critical path" (polled relatively infrequently) - and it's much more readable this way scheduler.Schedule(repeatAction => _httpListener.BeginGetContext(ar => { try { var httpListenerContext = _httpListener.EndGetContext(ar); var request = httpListenerContext.Request; var response = httpListenerContext.Response; response.StatusCode = 200; var acceptHeader = request.Headers.Get("Accept"); var acceptHeaders = acceptHeader == null ? null : acceptHeader.Split(','); var contentType = ScrapeHandler.GetContentType(acceptHeaders); response.ContentType = contentType; using (var outputStream = response.OutputStream) { var collected = _registry.CollectAll(); ScrapeHandler.ProcessScrapeRequest(collected, contentType, outputStream); } response.Close(); } catch (Exception e) { Trace.WriteLine(string.Format("Error in MetricsServer: {0}", e)); } repeatAction.Invoke(); }, null)); }
public void Configure(IApplicationBuilder app) { app.Run(context => { var response = context.Response; var request = context.Request; response.StatusCode = 200; var acceptHeader = request.Headers["Accept"]; var contentType = ScrapeHandler.GetContentType(acceptHeader); response.ContentType = contentType; using (var outputStream = response.Body) { var collected = _registry.CollectAll(); ScrapeHandler.ProcessScrapeRequest(collected, contentType, outputStream); }; return(Task.FromResult(true)); }); }
public async Task Invoke(HttpContext context) { // We just handle the root URL (/metrics or whatnot). if (!string.IsNullOrWhiteSpace(context.Request.Path.Value)) { await _next(context); return; } var request = context.Request; var response = context.Response; var acceptHeaders = request.Headers["Accept"]; var contentType = ScrapeHandler.GetContentType(acceptHeaders); response.ContentType = contentType; IEnumerable <MetricFamily> metrics; try { metrics = _registry.CollectAll(); } catch (ScrapeFailedException ex) { response.StatusCode = 503; if (!string.IsNullOrWhiteSpace(ex.Message)) { using (var writer = new StreamWriter(response.Body)) await writer.WriteAsync(ex.Message); } return; } response.StatusCode = 200; using (var outputStream = response.Body) ScrapeHandler.ProcessScrapeRequest(metrics, contentType, outputStream); }
protected override Task StartServer(CancellationToken cancel) { // This will ensure that any failures to start are nicely thrown from StartServerAsync. _httpListener.Start(); // Kick off the actual processing to a new thread and return a Task for the processing thread. return(Task.Factory.StartNew(delegate { try { while (!cancel.IsCancellationRequested) { // There is no way to give a CancellationToken to GCA() so, we need to hack around it a bit. var getContext = _httpListener.GetContextAsync(); getContext.Wait(cancel); var context = getContext.Result; var request = context.Request; var response = context.Response; try { IEnumerable <MetricFamily> metrics; try { metrics = _registry.CollectAll(); } catch (ScrapeFailedException ex) { response.StatusCode = 503; if (!string.IsNullOrWhiteSpace(ex.Message)) { using (var writer = new StreamWriter(response.OutputStream)) writer.Write(ex.Message); } continue; } var acceptHeader = request.Headers.Get("Accept"); var acceptHeaders = acceptHeader?.Split(','); var contentType = ScrapeHandler.GetContentType(acceptHeaders); response.ContentType = contentType; response.StatusCode = 200; using (var outputStream = response.OutputStream) ScrapeHandler.ProcessScrapeRequest(metrics, contentType, outputStream); } catch (Exception ex) when(!(ex is OperationCanceledException)) { Trace.WriteLine(string.Format("Error in MetricsServer: {0}", ex)); try { response.StatusCode = 500; } catch { // Might be too late in request processing to set response code, so just ignore. } } finally { response.Close(); } } } finally { _httpListener.Stop(); _httpListener.Close(); } }, TaskCreationOptions.LongRunning)); }