MINOR: promex: introduce haproxy_backend_agg_check_status

This patch introduces haproxy_backend_agg_check_status metric
as we wanted in 42d7c402d but with the right data source.

This patch could be backported as far as 2.4.

(cherry picked from commit e06e31ea3b62ef8ccb911ac3969ae70f7bbb7574)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit f0319e0f56581873f906f79dc218bf6f10b8f6c2)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit d8567a9fea61ae0ab0019a7cc563961e7afc34ad)
[cf: Adapted because the appctx was refactored in 2.6]
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
(cherry picked from commit 67cd53b415f2f411dfebe2024d0b480e740be258)
Signed-off-by: Christopher Faulet <cfaulet@haproxy.com>
diff --git a/addons/promex/service-prometheus.c b/addons/promex/service-prometheus.c
index 5bd5cc7..7bbfc46 100644
--- a/addons/promex/service-prometheus.c
+++ b/addons/promex/service-prometheus.c
@@ -290,6 +290,7 @@
 	[ST_F_UWEIGHT]              = { .n = IST("uweight"),                          .type = PROMEX_MT_GAUGE,    .flags = (                                               PROMEX_FL_BACK_METRIC | PROMEX_FL_SRV_METRIC) },
 	[ST_F_AGG_SRV_CHECK_STATUS] = { .n = IST("agg_server_check_status"),	      .type = PROMEX_MT_GAUGE,    .flags = (                                               PROMEX_FL_BACK_METRIC                       ) },
 	[ST_F_AGG_SRV_STATUS ]      = { .n = IST("agg_server_status"),	              .type = PROMEX_MT_GAUGE,    .flags = (                                               PROMEX_FL_BACK_METRIC                       ) },
+	[ST_F_AGG_CHECK_STATUS]     = { .n = IST("agg_check_status"),	              .type = PROMEX_MT_GAUGE,    .flags = (                                               PROMEX_FL_BACK_METRIC                       ) },
 };
 
 /* Description of overridden stats fields */
@@ -793,6 +794,7 @@
 	double secs;
 	enum promex_back_state bkd_state;
 	enum promex_srv_state srv_state;
+	enum healthcheck_status srv_check_status;
 
 	for (;appctx->st2 < ST_F_TOTAL_FIELDS; appctx->st2++) {
 		if (!(promex_st_metrics[appctx->st2].flags & appctx->ctx.stats.flags))
@@ -801,6 +803,8 @@
 		while (appctx->ctx.stats.obj1) {
 			struct promex_label labels[PROMEX_MAX_LABELS-1] = {};
 			unsigned int srv_state_count[PROMEX_SRV_STATE_COUNT] = { 0 };
+			unsigned int srv_check_count[HCHK_STATUS_SIZE] = { 0 };
+			const char *check_state;
 
 			px = appctx->ctx.stats.obj1;
 
@@ -835,6 +839,28 @@
 					}
 					appctx->ctx.stats.st_code = 0;
 					goto next_px;
+				case ST_F_AGG_CHECK_STATUS:
+					if (!px->srv)
+						goto next_px;
+					sv = px->srv;
+					while (sv) {
+						srv_check_status = sv->check.status;
+						srv_check_count[srv_check_status] += 1;
+						sv = sv->next;
+					}
+					for (; appctx->ctx.stats.st_code < HCHK_STATUS_SIZE; appctx->ctx.stats.st_code++) {
+						if (get_check_status_result(appctx->ctx.stats.st_code) < CHK_RES_FAILED)
+								continue;
+						val = mkf_u32(FO_STATUS, srv_check_count[appctx->ctx.stats.st_code]);
+						check_state = get_check_status_info(appctx->ctx.stats.st_code);
+						labels[1].name = ist("state");
+						labels[1].value = ist(check_state);
+						if (!promex_dump_metric(appctx, htx, prefix, &promex_st_metrics[appctx->st2],
+									&val, labels, &out, max))
+							goto full;
+					}
+					appctx->ctx.stats.st_code = 0;
+					goto next_px;
 				case ST_F_STATUS:
 					bkd_state = ((px->lbprm.tot_weight > 0 || !px->srv) ? 1 : 0);
 					for (; appctx->ctx.stats.st_code < PROMEX_BACK_STATE_COUNT; appctx->ctx.stats.st_code++) {
diff --git a/include/haproxy/stats-t.h b/include/haproxy/stats-t.h
index 6cdf0a0..920a311 100644
--- a/include/haproxy/stats-t.h
+++ b/include/haproxy/stats-t.h
@@ -445,6 +445,7 @@
 	ST_F_UWEIGHT,
 	ST_F_AGG_SRV_STATUS,
 	ST_F_AGG_SRV_CHECK_STATUS,
+	ST_F_AGG_CHECK_STATUS,
 
 	/* must always be the last one */
 	ST_F_TOTAL_FIELDS
diff --git a/src/stats.c b/src/stats.c
index 8fcc42c..f46ce2f 100644
--- a/src/stats.c
+++ b/src/stats.c
@@ -259,6 +259,7 @@
 	[ST_F_UWEIGHT]                       = { .name = "uweight",                     .desc = "Server's user weight, or sum of active servers' user weights for a backend" },
 	[ST_F_AGG_SRV_CHECK_STATUS]          = { .name = "agg_server_check_status",     .desc = "Backend's aggregated gauge of servers' state check status" },
 	[ST_F_AGG_SRV_STATUS ]               = { .name = "agg_server_status",           .desc = "Backend's aggregated gauge of servers' status" },
+	[ST_F_AGG_CHECK_STATUS]              = { .name = "agg_check_status",            .desc = "Backend's aggregated gauge of servers' state check status" },
 };
 
 /* one line of info */
@@ -2671,6 +2672,9 @@
 			case ST_F_AGG_SRV_STATUS:
 				metric = mkf_u32(FN_GAUGE, 0);
 				break;
+			case ST_F_AGG_CHECK_STATUS:
+				metric = mkf_u32(FN_GAUGE, 0);
+				break;
 			case ST_F_WEIGHT:
 				metric = mkf_u32(FN_AVG, (px->lbprm.tot_weight * px->lbprm.wmult + px->lbprm.wdiv - 1) / px->lbprm.wdiv);
 				break;