1

I'm using Prometheus (Prometheus.KestrelMetricServer) to export our services metrics.

Everything is working but although the Accept-Encoding header is set to gzip, the response of GET localhost:port/metrics is still not compressed.

Does Prometheus support compression for export metrics?

And if so, how can I tell Prometheus to send metrics compressed? (either as gzip, defalte or ...)

UPDATE: It's a Console app (not a WebApi). So the Prometheus.KestrelMetricServer itself serves the /metrics (instead of IIS or Kestrel or ...). I am looking for a way to compress the response by Prometheus.KestrelMetricServer itself

ABS
  • 2,626
  • 3
  • 28
  • 44
  • Yes it does. [Documentation](https://prometheus.io/docs/instrumenting/exposition_formats/#text-based-format). Since request came with header `Accept-Encoding:gzip` it would be strange if it didn't. – markalex Mar 16 '23 at 08:48
  • @markalex Yes, documentation says that. But neither ``Accept-Encoding`` nor ``Content-Encoding`` causes the response to be compressed(as I checked the transferred size) – ABS Mar 16 '23 at 09:33
  • `Content-Encoding` have to be set by the server (as well as compression). You need to look into your lib's documentation to activate compression (if standalone mode used) or configure own web-server to return compressed response (if middleware mode). – markalex Mar 16 '23 at 10:23

1 Answers1

1

After digging more into this, looks like the Prometheus.KestrelMetricServer doesnt support Gzip compression and thats as per the design. Here is the ISSUE from their github repo from 2019:

After considering this feature request, I have decided to reject it from the backlog.

The reason is that there is already available the ASP.NET Core metric server, which is significantly more flexible in what it supports, allowing you to incorporate custom middleware (such as gzip) into the pipeline. Please use the ASP.NET Core server for such scenarios.

The Kestrel server is kept at a minimal feature set in maintenance mode and is unlikely to receive significant updates in future versions.

As I see it, you have some work arounds:

WEB applications:

One possible workaround could be to use a reverse proxy, such as Nginx, to sit in front of your Kestrel server and handle the compression.

Use a different Prometheus exporter such as the Prometheus.AspNetCore package. It supports Gzip compression out of the box, so you would not need to make any additional configuration changes.

Console Applications

Manually handle the HTTP requests and responses by using the HTTPListener

Something like this:

var httpListener = new HttpListener();
httpListener.Prefixes.Add("http://localhost:9199/");
httpListener.Start();

while (httpListener.IsListening)
{
    var myContext = httpListener.GetContext();
    var myRequest = context.Request;
    var myResponse = context.Response;

    if (myRequest.Url.LocalPath == "/metrics")
    {
        var acceptEncoding = myRequest.Headers["Accept-Encoding"];
        if (acceptEncoding != null && acceptEncoding.Contains("gzip"))
        {
            myResponse.Headers.Add("Content-Encoding", "gzip");
            myResponse.OutputStream = new System.IO.Compression.GZipStream(response.OutputStream, System.IO.Compression.CompressionMode.Compress);
                }
Isaiah4110
  • 9,855
  • 1
  • 40
  • 56