From 117bc4bb38f0d7ba4b2dd6122445c402cd3ece25 Mon Sep 17 00:00:00 2001 From: Pedro Date: Mon, 29 Dec 2025 13:26:35 +0700 Subject: [PATCH 1/4] filter_log_to_metrics: add gzip compression option for prometheus exporter Signed-off-by: Pedro --- plugins/out_prometheus_exporter/prom_http.c | 94 ++++++++++++++++++++- 1 file changed, 93 insertions(+), 1 deletion(-) diff --git a/plugins/out_prometheus_exporter/prom_http.c b/plugins/out_prometheus_exporter/prom_http.c index 5f3307f9af0..c7bb4aece46 100644 --- a/plugins/out_prometheus_exporter/prom_http.c +++ b/plugins/out_prometheus_exporter/prom_http.c @@ -19,6 +19,9 @@ #include #include +#include +#include +#include #include "prom.h" #include "prom_http.h" @@ -157,10 +160,73 @@ static int http_server_mq_create(struct prom_http *ph) return 0; } +/* Check if client accepts gzip encoding */ +static int client_accepts_gzip(mk_request_t *request) +{ + struct mk_http_header *header; + const char *accept_encoding; + size_t len; + const char *p; + const char *end; + + /* Get Accept-Encoding header */ + header = mk_http_header_get(MK_HEADER_ACCEPT_ENCODING, request, NULL, 0); + if (!header || header->val.len == 0) { + return 0; + } + + accept_encoding = header->val.data; + len = header->val.len; + + /* Check if "gzip" is present in Accept-Encoding header (case-insensitive) */ + if (len < 4) { + return 0; + } + + p = accept_encoding; + end = accept_encoding + len; + + /* Search for "gzip" token */ + while (p < end - 3) { + /* Case-insensitive comparison for "gzip" */ + if ((p[0] == 'g' || p[0] == 'G') && + (p[1] == 'z' || p[1] == 'Z') && + (p[2] == 'i' || p[2] == 'I') && + (p[3] == 'p' || p[3] == 'P')) { + /* Check if it's a complete token (not part of another word) */ + /* Check character before "gzip" */ + if (p > accept_encoding) { + char prev = p[-1]; + if (prev != ',' && prev != ' ' && prev != '\t') { + p++; + continue; + } + } + /* Check character after "gzip" */ + if (p + 4 < end) { + char next = p[4]; + if (next != ',' && next != ' ' && next != '\t' && next != ';') { + p++; + continue; + } + } + /* Found valid "gzip" token */ + return 1; + } + p++; + } + + return 0; +} + /* HTTP endpoint: /metrics */ static void cb_metrics(mk_request_t *request, void *data) { struct prom_http_buf *buf; + void *compressed_data = NULL; + size_t compressed_size = 0; + int use_gzip = 0; + int ret; (void) data; buf = metrics_get_latest(); @@ -172,9 +238,35 @@ static void cb_metrics(mk_request_t *request, void *data) buf->users++; + /* Check if client accepts gzip encoding */ + use_gzip = client_accepts_gzip(request); + + /* Compress data if client supports gzip */ + if (use_gzip) { + ret = flb_gzip_compress(buf->buf_data, buf->buf_size, + &compressed_data, &compressed_size); + if (ret != 0 || !compressed_data) { + /* Compression failed, fall back to uncompressed */ + use_gzip = 0; + if (compressed_data) { + flb_free(compressed_data); + compressed_data = NULL; + } + } + } + mk_http_status(request, 200); flb_hs_add_content_type_to_req(request, FLB_HS_CONTENT_TYPE_PROMETHEUS); - mk_http_send(request, buf->buf_data, buf->buf_size, NULL); + + /* Add Content-Encoding header if compressed */ + if (use_gzip && compressed_data) { + mk_http_header(request, "Content-Encoding", 16, "gzip", 4); + mk_http_send(request, compressed_data, compressed_size, NULL); + flb_free(compressed_data); + } else { + mk_http_send(request, buf->buf_data, buf->buf_size, NULL); + } + mk_http_done(request); buf->users--; From 4eae4dc026796da62e1b4294b38748043664b41b Mon Sep 17 00:00:00 2001 From: Pedro Date: Mon, 29 Dec 2025 17:53:18 +0700 Subject: [PATCH 2/4] filter_log_to_metrics: remove superfluous string.h include Signed-off-by: Pedro --- plugins/out_prometheus_exporter/prom_http.c | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/out_prometheus_exporter/prom_http.c b/plugins/out_prometheus_exporter/prom_http.c index c7bb4aece46..bf8505537f5 100644 --- a/plugins/out_prometheus_exporter/prom_http.c +++ b/plugins/out_prometheus_exporter/prom_http.c @@ -21,7 +21,6 @@ #include #include #include -#include #include "prom.h" #include "prom_http.h" From 9c95cb43ca0e4d627b3fe854351ce7d1c0e9b392 Mon Sep 17 00:00:00 2001 From: Pedro Date: Wed, 14 Jan 2026 15:23:11 +0700 Subject: [PATCH 3/4] filter_log_to_metrics: use strncasecmp for string comparison Signed-off-by: Pedro --- plugins/out_prometheus_exporter/prom_http.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/out_prometheus_exporter/prom_http.c b/plugins/out_prometheus_exporter/prom_http.c index bf8505537f5..41dc8eae489 100644 --- a/plugins/out_prometheus_exporter/prom_http.c +++ b/plugins/out_prometheus_exporter/prom_http.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "prom.h" #include "prom_http.h" @@ -188,10 +189,7 @@ static int client_accepts_gzip(mk_request_t *request) /* Search for "gzip" token */ while (p < end - 3) { /* Case-insensitive comparison for "gzip" */ - if ((p[0] == 'g' || p[0] == 'G') && - (p[1] == 'z' || p[1] == 'Z') && - (p[2] == 'i' || p[2] == 'I') && - (p[3] == 'p' || p[3] == 'P')) { + if (strncasecmp(p, "gzip", 4) == 0) { /* Check if it's a complete token (not part of another word) */ /* Check character before "gzip" */ if (p > accept_encoding) { From 7006e1726a48431aac5575de557d5f3fb8cbda91 Mon Sep 17 00:00:00 2001 From: Pedro Date: Wed, 14 Jan 2026 16:08:20 +0700 Subject: [PATCH 4/4] filter_log_to_metrics: apply coding guideline Signed-off-by: Pedro --- plugins/out_prometheus_exporter/prom_http.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/plugins/out_prometheus_exporter/prom_http.c b/plugins/out_prometheus_exporter/prom_http.c index 41dc8eae489..206c20dd467 100644 --- a/plugins/out_prometheus_exporter/prom_http.c +++ b/plugins/out_prometheus_exporter/prom_http.c @@ -260,7 +260,8 @@ static void cb_metrics(mk_request_t *request, void *data) mk_http_header(request, "Content-Encoding", 16, "gzip", 4); mk_http_send(request, compressed_data, compressed_size, NULL); flb_free(compressed_data); - } else { + } + else { mk_http_send(request, buf->buf_data, buf->buf_size, NULL); }