]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: promex: Add global and proxies description as labels to all metrics
authorChristopher Faulet <cfaulet@haproxy.com>
Fri, 15 Nov 2024 13:15:43 +0000 (14:15 +0100)
committerChristopher Faulet <cfaulet@haproxy.com>
Fri, 15 Nov 2024 13:25:13 +0000 (14:25 +0100)
While the global description is exposed, when defined, in a dedicated
metric, it is not possible to dump the description defined in a
frontend/listen/backend sections. So, thanks to this patch, it is now
possible to dump it as a label of all metrics of the corresponding
section. To do so, "desc-labels" parameter must be provided on the URL:

    /metrics?desc-labels

When this parameter is set, if a description is provided in a section,
including the global one, the "desc" label will be added to all metrics of
this section. For instance:

  haproxy_frontend_current_sessions{proxy="front-http",desc="..."} 1

Note that servers metrics inherit the description of their backend/listen
section.

This patch should solve the issue #1531.

addons/promex/README
addons/promex/include/promex/promex.h
addons/promex/service-prometheus.c

index 6eb2698d8b13ff43958d37fa9291b5b3d451e58b..6226e62afaee63c95bfa4c40af6b48f9199cf26b 100644 (file)
@@ -91,6 +91,18 @@ name must be preceded by a minus character ('-'). Here are examples:
   # Only dump frontends, backends and servers status
   /metrics?metrics=haproxy_frontend_status,haproxy_backend_status,haproxy_server_status
 
+* Add section description as label for all metrics
+
+It is possible to set a description in global and proxy sections, via the
+"description" directive. The global descrption is exposed if it is define via
+the "haproxy_process_description" metric. But the descriptions provided in proxy
+sections are not dumped. However, it is possible to add it as a label for all
+metrics of the corresponding section, including the global one. To do so,
+"desc-labels" parameter must be set:
+
+  /metrics?desc-labels
+
+  / metrics?scope=frontend&desc-labels
 
 * Dump extra counters
 
index 74ea2f120d5e5dcb423e659d943d29a87db5d441..517c472bbab3e9d21bde9b2fed8c367f04d875dd 100644 (file)
@@ -47,6 +47,7 @@
 #define PROMEX_FL_NO_MAINT_SRV      0x00002000
 #define PROMEX_FL_EXTRA_COUNTERS    0x00004000
 #define PROMEX_FL_INC_METRIC_BY_DEFAULT 0x00008000
+#define PROMEX_FL_DESC_LABELS       0x00010000
 
 #define PROMEX_FL_SCOPE_ALL (PROMEX_FL_SCOPE_GLOBAL | PROMEX_FL_SCOPE_FRONT | \
                             PROMEX_FL_SCOPE_LI | PROMEX_FL_SCOPE_BACK | \
index 78115aa5ce9b2d5d77a67a8af47b97e09f00f191..e0a20be499898e8031f3158b627f551c0c6a0a72 100644 (file)
@@ -569,6 +569,7 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
 
        for (; ctx->field_num < ST_I_INF_MAX; ctx->field_num++) {
                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
+               int lb_idx = 0;
 
                if (!(promex_global_metrics[ctx->field_num].flags & ctx->flags))
                        continue;
@@ -581,22 +582,22 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
 
                switch (ctx->field_num) {
                        case ST_I_INF_NODE:
-                               labels[0].name  = ist("node");
-                               labels[0].value = ist(global.node);
+                               labels[lb_idx].name  = ist("node");
+                               labels[lb_idx].value = ist(global.node);
+                               lb_idx++;
                                val = mkf_u32(FN_GAUGE, 1);
                                break;
 
                        case ST_I_INF_DESCRIPTION:
                                if (!global.desc)
                                        continue;
-                               labels[0].name  = ist("desc");
-                               labels[0].value = ist(global.desc);
                                val = mkf_u32(FN_GAUGE, 1);
                                break;
 
                        case ST_I_INF_BUILD_INFO:
-                               labels[0].name  = ist("version");
-                               labels[0].value = ist(HAPROXY_VERSION);
+                               labels[lb_idx].name  = ist("version");
+                               labels[lb_idx].value = ist(HAPROXY_VERSION);
+                               lb_idx++;
                                val = mkf_u32(FN_GAUGE, 1);
                                break;
 
@@ -604,6 +605,12 @@ static int promex_dump_global_metrics(struct appctx *appctx, struct htx *htx)
                                val = stat_line_info[ctx->field_num];
                }
 
+               if (global.desc && ((ctx->field_num == ST_I_INF_DESCRIPTION) || (ctx->flags & PROMEX_FL_DESC_LABELS))) {
+                       labels[lb_idx].name  = ist("desc");
+                       labels[lb_idx].value = ist(global.desc);
+                       lb_idx++;
+               }
+
                if (!promex_dump_ts(appctx, prefix, name, desc,
                                    promex_global_metrics[ctx->field_num].type,
                                    &val, labels, &out, max))
@@ -660,9 +667,17 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
 
                while (px) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
+                       int lb_idx = 0;
+
+                       labels[lb_idx].name  = ist("proxy");
+                       labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                       lb_idx++;
 
-                       labels[0].name  = ist("proxy");
-                       labels[0].value = ist2(px->id, strlen(px->id));
+                       if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                               labels[lb_idx].name  = ist("desc");
+                               labels[lb_idx].value = ist(px->desc);
+                               lb_idx++;
+                       }
 
                        /* skip the disabled proxies, global frontend and non-networked ones */
                        if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
@@ -675,8 +690,8 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                                case ST_I_PX_STATUS:
                                        state = !(px->flags & PR_FL_STOPPED);
                                        for (; ctx->obj_state < PROMEX_FRONT_STATE_COUNT; ctx->obj_state++) {
-                                               labels[1].name = ist("state");
-                                               labels[1].value = promex_front_st[ctx->obj_state];
+                                               labels[lb_idx].name = ist("state");
+                                               labels[lb_idx].value = promex_front_st[ctx->obj_state];
                                                val = mkf_u32(FO_STATUS, state == ctx->obj_state);
 
                                                if (!promex_dump_ts(appctx, prefix, name, desc,
@@ -709,8 +724,8 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                                                goto next_px;
                                        if (ctx->field_num != ST_I_PX_HRSP_1XX)
                                                ctx->flags &= ~PROMEX_FL_METRIC_HDR;
-                                       labels[1].name = ist("code");
-                                       labels[1].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
+                                       labels[lb_idx].name = ist("code");
+                                       labels[lb_idx].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
                                        val = stats[ctx->field_num];
                                        break;
 
@@ -756,12 +771,21 @@ static int promex_dump_front_metrics(struct appctx *appctx, struct htx *htx)
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
+                               int lb_idx = 0;
+
+                               labels[lb_idx].name  = ist("proxy");
+                               labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                               lb_idx++;
 
-                               labels[0].name  = ist("proxy");
-                               labels[0].value = ist2(px->id, strlen(px->id));
+                               labels[lb_idx].name  = ist("mod");
+                               labels[lb_idx].value = ist2(mod->name, strlen(mod->name));
+                               lb_idx++;
 
-                               labels[1].name  = ist("mod");
-                               labels[1].value = ist2(mod->name, strlen(mod->name));
+                               if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                                       labels[lb_idx].name  = ist("desc");
+                                       labels[lb_idx].value = ist(px->desc);
+                                       lb_idx++;
+                               }
 
                                /* skip the disabled proxies, global frontend and non-networked ones */
                                if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
@@ -844,9 +868,18 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
 
                while (px) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
+                       int lb_idx = 0;
 
-                       labels[0].name  = ist("proxy");
-                       labels[0].value = ist2(px->id, strlen(px->id));
+                       labels[lb_idx].name  = ist("proxy");
+                       labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                       lb_idx++;
+
+
+                       if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                               labels[lb_idx].name  = ist("desc");
+                               labels[lb_idx].value = ist(px->desc);
+                               lb_idx++;
+                       }
 
                        /* skip the disabled proxies, global frontend and non-networked ones */
                        if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
@@ -859,8 +892,8 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                                if (!li->counters)
                                        continue;
 
-                               labels[1].name  = ist("listener");
-                               labels[1].value = ist2(li->name, strlen(li->name));
+                               labels[lb_idx].name  = ist("listener");
+                               labels[lb_idx].value = ist2(li->name, strlen(li->name));
 
                                if (!stats_fill_li_line(px, li, 0, stats,
                                                        ST_I_PX_MAX, &(ctx->field_num)))
@@ -871,8 +904,8 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                                                status = get_li_status(li);
                                                for (; ctx->obj_state < LI_STATE_COUNT; ctx->obj_state++) {
                                                        val = mkf_u32(FO_STATUS, status == ctx->obj_state);
-                                                       labels[2].name = ist("state");
-                                                       labels[2].value = ist(li_status_st[ctx->obj_state]);
+                                                       labels[lb_idx+1].name = ist("state");
+                                                       labels[lb_idx+1].value = ist(li_status_st[ctx->obj_state]);
                                                        if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                            promex_st_metrics[ctx->field_num].type,
                                                                            &val, labels, &out, max))
@@ -925,9 +958,17 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
+                               int lb_idx = 0;
 
-                               labels[0].name  = ist("proxy");
-                               labels[0].value = ist2(px->id, strlen(px->id));
+                               labels[lb_idx].name  = ist("proxy");
+                               labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                               lb_idx++;
+
+                               if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                                       labels[lb_idx].name  = ist("desc");
+                                       labels[lb_idx].value = ist(px->desc);
+                                       lb_idx++;
+                               }
 
                                /* skip the disabled proxies, global frontend and non-networked ones */
                                if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_FE))
@@ -940,11 +981,11 @@ static int promex_dump_listener_metrics(struct appctx *appctx, struct htx *htx)
                                        if (!li->counters)
                                                continue;
 
-                                       labels[1].name  = ist("listener");
-                                       labels[1].value = ist2(li->name, strlen(li->name));
+                                       labels[lb_idx].name  = ist("listener");
+                                       labels[lb_idx].value = ist2(li->name, strlen(li->name));
 
-                                       labels[2].name  = ist("mod");
-                                       labels[2].value = ist2(mod->name, strlen(mod->name));
+                                       labels[lb_idx+1].name  = ist("mod");
+                                       labels[lb_idx+1].value = ist2(mod->name, strlen(mod->name));
 
                                        counters = EXTRA_COUNTERS_GET(li->extra_counters, mod);
                                        if (!mod->fill_stats(counters, stats + ctx->field_num, &ctx->mod_field_num))
@@ -1032,9 +1073,18 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                        unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 };
                        unsigned int srv_check_count[HCHK_STATUS_SIZE] = { 0 };
                        const char *check_state;
+                       int lb_idx = 0;
+
+                       labels[lb_idx].name  = ist("proxy");
+                       labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                       lb_idx++;
+
+                       if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                               labels[lb_idx].name  = ist("desc");
+                               labels[lb_idx].value = ist(px->desc);
+                               lb_idx++;
+                       }
 
-                       labels[0].name  = ist("proxy");
-                       labels[0].value = ist2(px->id, strlen(px->id));
 
                        /* skip the disabled proxies, global frontend and non-networked ones */
                        if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
@@ -1056,8 +1106,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                        }
                                        for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) {
                                                val = mkf_u32(FN_GAUGE, srv_state_count[ctx->obj_state]);
-                                               labels[1].name = ist("state");
-                                               labels[1].value = promex_srv_st[ctx->obj_state];
+                                               labels[lb_idx].name = ist("state");
+                                               labels[lb_idx].value = promex_srv_st[ctx->obj_state];
                                                if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                    promex_st_metrics[ctx->field_num].type,
                                                                    &val, labels, &out, max))
@@ -1081,8 +1131,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                                                continue;
                                                val = mkf_u32(FO_STATUS, srv_check_count[ctx->obj_state]);
                                                check_state = get_check_status_info(ctx->obj_state);
-                                               labels[1].name = ist("state");
-                                               labels[1].value = ist(check_state);
+                                               labels[lb_idx].name = ist("state");
+                                               labels[lb_idx].value = ist(check_state);
                                                if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                    promex_st_metrics[ctx->field_num].type,
                                                                    &val, labels, &out, max))
@@ -1093,8 +1143,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                case ST_I_PX_STATUS:
                                        bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
                                        for (; ctx->obj_state < PROMEX_BACK_STATE_COUNT; ctx->obj_state++) {
-                                               labels[1].name = ist("state");
-                                               labels[1].value = promex_back_st[ctx->obj_state];
+                                               labels[lb_idx].name = ist("state");
+                                               labels[lb_idx].value = promex_back_st[ctx->obj_state];
                                                val = mkf_u32(FO_STATUS, bkd_state == ctx->obj_state);
                                                if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                    promex_st_metrics[ctx->field_num].type,
@@ -1156,8 +1206,8 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                                                goto next_px;
                                        if (ctx->field_num != ST_I_PX_HRSP_1XX)
                                                ctx->flags &= ~PROMEX_FL_METRIC_HDR;
-                                       labels[1].name = ist("code");
-                                       labels[1].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
+                                       labels[lb_idx].name = ist("code");
+                                       labels[lb_idx].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
                                        val = stats[ctx->field_num];
                                        break;
 
@@ -1203,12 +1253,21 @@ static int promex_dump_back_metrics(struct appctx *appctx, struct htx *htx)
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
+                               int lb_idx = 0;
 
-                               labels[0].name  = ist("proxy");
-                               labels[0].value = ist2(px->id, strlen(px->id));
+                               labels[lb_idx].name  = ist("proxy");
+                               labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                               lb_idx++;
 
-                               labels[1].name  = ist("mod");
-                               labels[1].value = ist2(mod->name, strlen(mod->name));
+                               labels[lb_idx].name  = ist("mod");
+                               labels[lb_idx].value = ist2(mod->name, strlen(mod->name));
+                               lb_idx++;
+
+                               if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                                       labels[lb_idx].name  = ist("desc");
+                                       labels[lb_idx].value = ist(px->desc);
+                                       lb_idx++;
+                               }
 
                                /* skip the disabled proxies, global frontend and non-networked ones */
                                if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
@@ -1292,9 +1351,17 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
 
                while (px) {
                        struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
+                       int lb_idx = 0;
 
-                       labels[0].name  = ist("proxy");
-                       labels[0].value = ist2(px->id, strlen(px->id));
+                       labels[lb_idx].name  = ist("proxy");
+                       labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                       lb_idx++;
+
+                       if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                               labels[lb_idx].name  = ist("desc");
+                               labels[lb_idx].value = ist(px->desc);
+                               lb_idx++;
+                       }
 
                        /* skip the disabled proxies, global frontend and non-networked ones */
                        if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
@@ -1304,8 +1371,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                sv = px->srv;
 
                        while (sv) {
-                               labels[1].name  = ist("server");
-                               labels[1].value = ist2(sv->id, strlen(sv->id));
+                               labels[lb_idx].name  = ist("server");
+                               labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
 
                                if (!stats_fill_sv_line(px, sv, 0, stats, ST_I_PX_MAX, &(ctx->field_num)))
                                        return -1;
@@ -1318,8 +1385,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                                state = promex_srv_status(sv);
                                                for (; ctx->obj_state < PROMEX_SRV_STATE_COUNT; ctx->obj_state++) {
                                                        val = mkf_u32(FO_STATUS, state == ctx->obj_state);
-                                                       labels[2].name = ist("state");
-                                                       labels[2].value = promex_srv_st[ctx->obj_state];
+                                                       labels[lb_idx+1].name = ist("state");
+                                                       labels[lb_idx+1].value = promex_srv_st[ctx->obj_state];
                                                        if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                            promex_st_metrics[ctx->field_num].type,
                                                                            &val, labels, &out, max))
@@ -1368,8 +1435,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                                                continue;
                                                        val = mkf_u32(FO_STATUS, sv->check.status == ctx->obj_state);
                                                        check_state = get_check_status_info(ctx->obj_state);
-                                                       labels[2].name = ist("state");
-                                                       labels[2].value = ist(check_state);
+                                                       labels[lb_idx+1].name = ist("state");
+                                                       labels[lb_idx+1].value = ist(check_state);
                                                        if (!promex_dump_ts(appctx, prefix, name, desc,
                                                                            promex_st_metrics[ctx->field_num].type,
                                                                            &val, labels, &out, max))
@@ -1407,8 +1474,8 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                                }
                                                if (ctx->field_num != ST_I_PX_HRSP_1XX)
                                                        ctx->flags &= ~PROMEX_FL_METRIC_HDR;
-                                               labels[2].name = ist("code");
-                                               labels[2].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
+                                               labels[lb_idx+1].name = ist("code");
+                                               labels[lb_idx+1].value = promex_hrsp_code[ctx->field_num - ST_I_PX_HRSP_1XX];
                                                val = stats[ctx->field_num];
                                                break;
 
@@ -1458,9 +1525,18 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                        while (px) {
                                struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
                                struct promex_metric metric;
+                               int lb_idx = 0;
+
+                               labels[lb_idx].name  = ist("proxy");
+                               labels[lb_idx].value = ist2(px->id, strlen(px->id));
+                               lb_idx++;
+
+                               if ((ctx->flags & PROMEX_FL_DESC_LABELS) && px->desc) {
+                                       labels[lb_idx].name  = ist("desc");
+                                       labels[lb_idx].value = ist(px->desc);
+                                       lb_idx++;
+                               }
 
-                               labels[0].name  = ist("proxy");
-                               labels[0].value = ist2(px->id, strlen(px->id));
 
                                /* skip the disabled proxies, global frontend and non-networked ones */
                                if ((px->flags & PR_FL_DISABLED) || px->uuid <= 0 || !(px->cap & PR_CAP_BE))
@@ -1470,11 +1546,11 @@ static int promex_dump_srv_metrics(struct appctx *appctx, struct htx *htx)
                                        sv = px->srv;
 
                                while (sv) {
-                                       labels[1].name  = ist("server");
-                                       labels[1].value = ist2(sv->id, strlen(sv->id));
+                                       labels[lb_idx].name  = ist("server");
+                                       labels[lb_idx].value = ist2(sv->id, strlen(sv->id));
 
-                                       labels[2].name  = ist("mod");
-                                       labels[2].value = ist2(mod->name, strlen(mod->name));
+                                       labels[lb_idx+1].name  = ist("mod");
+                                       labels[lb_idx+1].value = ist2(mod->name, strlen(mod->name));
 
                                        if ((ctx->flags & PROMEX_FL_NO_MAINT_SRV) && (sv->cur_admin & SRV_ADMF_MAINT))
                                                goto next_sv2;
@@ -1985,6 +2061,8 @@ static int promex_parse_uri(struct appctx *appctx, struct stconn *sc)
                }
                else if (strcmp(key, "no-maint") == 0)
                        ctx->flags |= PROMEX_FL_NO_MAINT_SRV;
+               else if (strcmp(key, "desc-labels") == 0)
+                       ctx->flags |= PROMEX_FL_DESC_LABELS;
        }
 
   end: