From: Amaury Denoyelle Date: Tue, 30 Apr 2024 12:09:36 +0000 (+0200) Subject: MINOR: stats: support age in stats-file X-Git-Tag: v3.0-dev10~16 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e92ae8f0bab0801b8b72889255bec9e34ad02067;p=thirdparty%2Fhaproxy.git MINOR: stats: support age in stats-file Extend generic stat column support to be able to fully support age stats type. Several changes were required. On output, me_generate_field() has been updated to report the difference between the current tick with the stored value for FN_AGE type. Also, if an age stats is hidden in show stats, -1 is returned instead of an empty metric, which is the value to mark an age as unset. On counters preload, load_ctr() was updated to handled FN_AGE. A similar substraction is performed to the current tick value. --- diff --git a/src/stats-file.c b/src/stats-file.c index 4f07ddc903..c63916ea01 100644 --- a/src/stats-file.c +++ b/src/stats-file.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include /* Dump all fields from into for stats-file. */ int stats_dump_fields_file(struct buffer *out, @@ -211,6 +213,7 @@ static int load_ctr(const struct stat_col *col, const struct ist token, value.u.u64 = read_uint64(&ptr, istend(token)); break; + case FF_S32: case FF_U32: value.u.u32 = read_uint(&ptr, istend(token)); break; @@ -230,6 +233,9 @@ static int load_ctr(const struct stat_col *col, const struct ist token, else if (fn == FN_RATE && ff == FF_U32) { preload_freq_ctr(counter, value.u.u32); } + else if (fn == FN_AGE && (ff == FF_U32 || ff == FF_S32)) { + *(uint32_t *)counter = ns_to_sec(now_ns) - value.u.u32; + } else { /* Unsupported field format/nature combination. */ return 1; diff --git a/src/stats.c b/src/stats.c index e792f86526..57b386b662 100644 --- a/src/stats.c +++ b/src/stats.c @@ -742,6 +742,8 @@ static struct field me_generate_field(const struct stat_col *col, /* Only generic stat column must be used as input. */ BUG_ON(!stcol_is_generic(col)); + fn = stcol_nature(col); + switch (cap) { case STATS_PX_CAP_FE: case STATS_PX_CAP_LI: @@ -786,11 +788,17 @@ static struct field me_generate_field(const struct stat_col *col, } else { /* Ensure metric is defined for the current cap. */ - if (!(col->cap & cap) || stcol_hide(idx, objt)) + if (!(col->cap & cap)) return (struct field){ .type = FF_EMPTY }; + + if (stcol_hide(idx, objt)) { + if (fn == FN_AGE) + return mkf_s32(FN_AGE, -1); + else + return (struct field){ .type = FF_EMPTY }; + } } - fn = stcol_nature(col); if (fn == FN_COUNTER) { switch (stcol_format(col)) { case FF_U64: @@ -806,6 +814,23 @@ static struct field me_generate_field(const struct stat_col *col, BUG_ON(stcol_format(col) != FF_U32); value = mkf_u32(FN_RATE, read_freq_ctr(counter)); } + else if (fn == FN_AGE) { + unsigned long age = *(unsigned long *)counter; + if (age) + age = ns_to_sec(now_ns) - age; + + switch (stcol_format(col)) { + case FF_U32: + value = mkf_u32(FN_AGE, age); + break; + case FF_S32: + value = mkf_s32(FN_AGE, age); + break; + default: + /* only FF_U32/FF+S32 for age as generic stat column */ + ABORT_NOW(); + } + } else { /* No generic column available for other field nature. */ ABORT_NOW();