]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MEDIUM: contrib/prometheus-exporter: Properly set flags to dump metrics
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 5 Jun 2020 06:18:56 +0000 (08:18 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 5 Jun 2020 07:41:46 +0000 (09:41 +0200)
When the metrics are dumped, in the main function promex_dump_metrics(), the
appctx flags are set before entering in a new scope, among others things to know
which metrics names and descriptions to use. But, those flags are not restored
when the dump is interrupted because of a full output buffer. If this happens
after the dump of global metrics, it may only lead to extra #TYPE and #HELP
lines. But if this happens during the dump of global metrics, the following
dumps of frontends, backends and servers metrics use names and descriptions of
global ones with the unmatching indexes. This first leads to unexisting metrics
names. For instance, "haproxy_frontend_nbproc". But also to out-of-bound
accesses to name and description arrays because there are more stats fields than
info fields.

It is easy to reproduce the bug using small buffers, setting tune.bufsize to
8192 for instance.

This patch should fix the issue #666. It must be backported as far as 2.0.

contrib/prometheus-exporter/service-prometheus.c

index f7542d26bc4d3dc61d23f697911ad60152a79bbc..dfd5e1a43c3e34593f4ae5c45e595fb797850ce5 100644 (file)
@@ -2149,13 +2149,12 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
 static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *si, struct htx *htx)
 {
        int ret;
-       int flags = appctx->ctx.stats.flags;
 
        switch (appctx->st1) {
                case PROMEX_DUMPER_INIT:
                        appctx->ctx.stats.px = NULL;
                        appctx->ctx.stats.sv = NULL;
-                       appctx->ctx.stats.flags = (flags|PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
+                       appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC);
                        appctx->st2 = promex_global_metrics[INF_NAME];
                        appctx->st1 = PROMEX_DUMPER_GLOBAL;
                        /* fall through */
@@ -2172,7 +2171,8 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
 
                        appctx->ctx.stats.px = proxies_list;
                        appctx->ctx.stats.sv = NULL;
-                       appctx->ctx.stats.flags = (flags|PROMEX_FL_METRIC_HDR|PROMEX_FL_STATS_METRIC);
+                       appctx->ctx.stats.flags &= ~PROMEX_FL_INFO_METRIC;
+                       appctx->ctx.stats.flags |= (PROMEX_FL_METRIC_HDR|PROMEX_FL_STATS_METRIC);
                        appctx->st2 = promex_front_metrics[ST_F_PXNAME];
                        appctx->st1 = PROMEX_DUMPER_FRONT;
                        /* fall through */
@@ -2189,7 +2189,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
 
                        appctx->ctx.stats.px = proxies_list;
                        appctx->ctx.stats.sv = NULL;
-                       appctx->ctx.stats.flags = (flags|PROMEX_FL_METRIC_HDR|PROMEX_FL_STATS_METRIC);
+                       appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
                        appctx->st2 = promex_back_metrics[ST_F_PXNAME];
                        appctx->st1 = PROMEX_DUMPER_BACK;
                        /* fall through */
@@ -2206,7 +2206,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
 
                        appctx->ctx.stats.px = proxies_list;
                        appctx->ctx.stats.sv = (appctx->ctx.stats.px ? appctx->ctx.stats.px->srv : NULL);
-                       appctx->ctx.stats.flags = (flags|PROMEX_FL_METRIC_HDR|PROMEX_FL_STATS_METRIC);
+                       appctx->ctx.stats.flags |= PROMEX_FL_METRIC_HDR;
                        appctx->st2 = promex_srv_metrics[ST_F_PXNAME];
                        appctx->st1 = PROMEX_DUMPER_SRV;
                        /* fall through */
@@ -2223,7 +2223,7 @@ static int promex_dump_metrics(struct appctx *appctx, struct stream_interface *s
 
                        appctx->ctx.stats.px = NULL;
                        appctx->ctx.stats.sv = NULL;
-                       appctx->ctx.stats.flags = flags;
+                       appctx->ctx.stats.flags &= ~(PROMEX_FL_METRIC_HDR|PROMEX_FL_INFO_METRIC|PROMEX_FL_STATS_METRIC);
                        appctx->st2 = 0;
                        appctx->st1 = PROMEX_DUMPER_DONE;
                        /* fall through */