From: Christopher Faulet Date: Fri, 15 Nov 2024 13:15:43 +0000 (+0100) Subject: MINOR: promex: Add global and proxies description as labels to all metrics X-Git-Tag: v3.1-dev13~11 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=25b05927456780aaca2d61f6b05b9a4ad4302eb3;p=thirdparty%2Fhaproxy.git MINOR: promex: Add global and proxies description as labels to all metrics 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. --- diff --git a/addons/promex/README b/addons/promex/README index 6eb2698d8b..6226e62afa 100644 --- a/addons/promex/README +++ b/addons/promex/README @@ -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 diff --git a/addons/promex/include/promex/promex.h b/addons/promex/include/promex/promex.h index 74ea2f120d..517c472bba 100644 --- a/addons/promex/include/promex/promex.h +++ b/addons/promex/include/promex/promex.h @@ -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 | \ diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c index 78115aa5ce..e0a20be499 100644 --- a/addons/promex/service-prometheus.c +++ b/addons/promex/service-prometheus.c @@ -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: