]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stats: hide some columns in output
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Wed, 17 Apr 2024 09:12:27 +0000 (11:12 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 26 Apr 2024 08:20:57 +0000 (10:20 +0200)
Metric style stats can be automatically calculate since the introduction
of metric_generate() when using "struct stat_col" as input. This would
allow to centralize statistics generation. However, some stats are not
outputted under specific condition. For example, health check failures
on a server are only reported if checks are active.

To support this, define a new function metric_hide(). It is called by
metric_generate(). If true, it will skip metric calcuation and return an
empty field value instead. This allows to define "stat_col" metrics and
calculate them with metric_generate() but hiding them under certain
circumstances.

src/stats.c

index 7dd18371ec897bc5df1df57c62ed332db803b395..48efc934cbb7e6d7140dbc1107556ad4456c2ff0 100644 (file)
@@ -637,6 +637,38 @@ int stats_dump_one_line(const struct field *line, size_t stats_count,
        return ret;
 }
 
+/* Returns true if column at <idx> should be hidden.
+ * This may depends on various <objt> internal status.
+ */
+static int stcol_hide(enum stat_idx_px idx, enum obj_type *objt)
+{
+       struct proxy *px __maybe_unused;
+       struct server *srv = NULL;
+       struct listener *li = NULL;
+
+       switch (obj_type(objt)) {
+       case OBJ_TYPE_PROXY:
+               px = __objt_proxy(objt);
+               break;
+       case OBJ_TYPE_SERVER:
+               srv = __objt_server(objt);
+               px = srv->proxy;
+               break;
+       case OBJ_TYPE_LISTENER:
+               li = __objt_listener(objt);
+               px = li->bind_conf->frontend;
+               break;
+       default:
+               ABORT_NOW();
+               return 0;
+       }
+
+       switch (idx) {
+       default:
+               return 0;
+       }
+}
+
 /* Generate if possible a metric value from <col>. <cap> must be set to one of
  * STATS_PX_CAP_* values to check if the metric is available for this object
  * type. Metric value will be extracted from <counters>.
@@ -644,6 +676,7 @@ int stats_dump_one_line(const struct field *line, size_t stats_count,
  * Returns a field value or an empty one if cap not compatible.
  */
 static struct field me_generate_field(const struct stat_col *col,
+                                      enum stat_idx_px idx, enum obj_type *objt,
                                       const void *counters, uint8_t cap)
 {
        struct field value;
@@ -669,6 +702,10 @@ static struct field me_generate_field(const struct stat_col *col,
        if (!(col->cap & cap))
                return (struct field){ .type = FF_EMPTY };
 
+       /* Check if metric should be hidden in output. */
+       if (stcol_hide(idx, objt))
+               return (struct field){ .type = FF_EMPTY };
+
        switch (stcol_format(col)) {
        case FF_U64:
                value = mkf_u64(stcol_nature(col), *(uint64_t *)counter);
@@ -700,7 +737,8 @@ int stats_fill_fe_line(struct proxy *px, struct field *line, int len,
                struct field field = { 0 };
 
                if (stcol_is_generic(col)) {
-                       field = me_generate_field(col, &px->fe_counters, STATS_PX_CAP_FE);
+                       field = me_generate_field(col, i, &px->obj_type,
+                                                 &px->fe_counters, STATS_PX_CAP_FE);
                }
                else {
                        switch (i) {
@@ -976,7 +1014,8 @@ int stats_fill_li_line(struct proxy *px, struct listener *l, int flags,
                struct field field = { 0 };
 
                if (stcol_is_generic(col)) {
-                       field = me_generate_field(col, l->counters, STATS_PX_CAP_LI);
+                       field = me_generate_field(col, i, &l->obj_type,
+                                                 l->counters, STATS_PX_CAP_LI);
                }
                else {
                        switch (i) {
@@ -1257,7 +1296,8 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags,
                struct field field = { 0 };
 
                if (stcol_is_generic(col)) {
-                       field = me_generate_field(col, &sv->counters, STATS_PX_CAP_SRV);
+                       field = me_generate_field(col, i, &sv->obj_type,
+                                                 &sv->counters, STATS_PX_CAP_SRV);
                }
                else {
                        switch (i) {
@@ -1723,7 +1763,8 @@ int stats_fill_be_line(struct proxy *px, int flags, struct field *line, int len,
                struct field field = { 0 };
 
                if (stcol_is_generic(col)) {
-                       field = me_generate_field(col, &px->be_counters, STATS_PX_CAP_BE);
+                       field = me_generate_field(col, i, &px->obj_type,
+                                                 &px->be_counters, STATS_PX_CAP_BE);
                }
                else {
                        switch (i) {