From: Amaury Denoyelle Date: Mon, 29 Apr 2024 13:35:17 +0000 (+0200) Subject: MINOR: stats: convert req_tot as generic column X-Git-Tag: v3.0-dev10~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=933b4ae27d447cf7e450da03512299a94964cef8;p=thirdparty%2Fhaproxy.git MINOR: stats: convert req_tot as generic column req_tot counter is a special case as it is not managed identically between frontend and backend side. For the backend side, this metric is available directly into be_counters, which allows to use a generic stat column definition. On the frontend side however, the metric value is an aggredate of multiple fe_counters value. This is the case since the splitting between HTTP version introduced in the following patch : 9969adbcdc1a79a6e8bb0a6283191d8d330a04f1 MINOR: stats: add by HTTP version cumulated number of sessions and requests This difference cannot be handled automatically by me_generate_field(). Add a special case in the function to produce it on frontend side reusing the aggregated value. This not done however for stats-file as there is no counter to preload. --- diff --git a/src/stats.c b/src/stats.c index 0073e8309a..3f3ee0fe3c 100644 --- a/src/stats.c +++ b/src/stats.c @@ -253,7 +253,8 @@ const struct stat_col stat_cols_px[ST_I_PX_MAX] = { [ST_I_PX_HANAFAIL] = ME_NEW_BE("hanafail", FN_COUNTER, FF_U64, failed_hana, STATS_PX_CAP____S, "Total number of failed checks caused by an 'on-error' directive after an 'observe' condition matched"), [ST_I_PX_REQ_RATE] = { .name = "req_rate", .desc = "Number of HTTP requests processed over the last second on this object" }, [ST_I_PX_REQ_RATE_MAX] = { .name = "req_rate_max", .desc = "Highest value of http requests observed since the worker process started" }, - [ST_I_PX_REQ_TOT] = { .name = "req_tot", .desc = "Total number of HTTP requests processed by this object since the worker process started" }, + /* Note: ST_I_PX_REQ_TOT is also diplayed on frontend but does not uses a raw counter value, see me_generate_field() for details. */ + [ST_I_PX_REQ_TOT] = ME_NEW_BE("req_tot", FN_COUNTER, FF_U64, p.http.cum_req, STATS_PX_CAP___BS, "Total number of HTTP requests processed by this object since the worker process started"), [ST_I_PX_CLI_ABRT] = ME_NEW_BE("cli_abrt", FN_COUNTER, FF_U64, cli_aborts, STATS_PX_CAP_LFBS, "Total number of requests or connections aborted by the client since the worker process started"), [ST_I_PX_SRV_ABRT] = ME_NEW_BE("srv_abrt", FN_COUNTER, FF_U64, srv_aborts, STATS_PX_CAP_LFBS, "Total number of requests or connections aborted by the server since the worker process started"), [ST_I_PX_COMP_IN] = ME_NEW_PX("comp_in", FN_COUNTER, FF_U64, comp_in[COMP_DIR_RES], STATS_PX_CAP__FB_, "Total number of bytes submitted to the HTTP compressor for this object since the worker process started"), @@ -703,6 +704,7 @@ static int stcol_hide(enum stat_idx_px idx, enum obj_type *objt) case ST_I_PX_HRSP_3XX: case ST_I_PX_HRSP_4XX: case ST_I_PX_HRSP_5XX: + case ST_I_PX_REQ_TOT: case ST_I_PX_INTERCEPTED: case ST_I_PX_CACHE_LOOKUPS: case ST_I_PX_CACHE_HITS: @@ -762,6 +764,23 @@ static struct field me_generate_field(const struct stat_col *col, ABORT_NOW(); } + /* TODO Special case needed for ST_I_PX_REQ_TOT. It is defined as a + * generic column for backend side. Extra code required to diplay it on + * frontend side as an aggregate of values splitted by HTTP version. + */ + if (idx == ST_I_PX_REQ_TOT && cap == STATS_PX_CAP_FE && !stat_file) { + struct proxy *px = __objt_proxy(objt); + const size_t nb_reqs = + sizeof(px->fe_counters.p.http.cum_req) / + sizeof(*px->fe_counters.p.http.cum_req); + uint64_t total_req = 0; + int i; + + for (i = 0; i < nb_reqs; i++) + total_req += px->fe_counters.p.http.cum_req[i]; + return mkf_u64(FN_COUNTER, total_req); + } + if (stat_file) { /* stats-file emits separately frontend and backend stats. * Skip metric if not defined for any object on the cap side. @@ -869,18 +888,6 @@ int stats_fill_fe_line(struct proxy *px, int flags, struct field *line, int len, case ST_I_PX_REQ_RATE_MAX: field = mkf_u32(FN_MAX, px->fe_counters.p.http.rps_max); break; - case ST_I_PX_REQ_TOT: { - int i; - uint64_t total_req; - size_t nb_reqs = - sizeof(px->fe_counters.p.http.cum_req) / sizeof(*px->fe_counters.p.http.cum_req); - - total_req = 0; - for (i = 0; i < nb_reqs; i++) - total_req += px->fe_counters.p.http.cum_req[i]; - field = mkf_u64(FN_COUNTER, total_req); - break; - } case ST_I_PX_CONN_RATE: field = mkf_u32(FN_RATE, read_freq_ctr(&px->fe_conn_per_sec)); break; @@ -1442,10 +1449,6 @@ int stats_fill_sv_line(struct proxy *px, struct server *sv, int flags, if ((sv->agent.state & (CHK_ST_ENABLED|CHK_ST_PAUSED)) == CHK_ST_ENABLED) field = mkf_u32(FO_CONFIG|FS_SERVICE, sv->agent.health); break; - case ST_I_PX_REQ_TOT: - if (px->mode == PR_MODE_HTTP) - field = mkf_u64(FN_COUNTER, sv->counters.p.http.cum_req); - break; case ST_I_PX_LASTSESS: field = mkf_s32(FN_AGE, srv_lastsession(sv)); break; @@ -1717,10 +1720,6 @@ int stats_fill_be_line(struct proxy *px, int flags, struct field *line, int len, if (flags & STAT_F_SHLGNDS) field = mkf_str(FO_CONFIG|FS_SERVICE, backend_lb_algo_str(px->lbprm.algo & BE_LB_ALGO)); break; - case ST_I_PX_REQ_TOT: - if (px->mode == PR_MODE_HTTP) - field = mkf_u64(FN_COUNTER, px->be_counters.p.http.cum_req); - break; case ST_I_PX_LASTSESS: field = mkf_s32(FN_AGE, be_lastsession(px)); break;