]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stats: convert req_tot as generic column
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Mon, 29 Apr 2024 13:35:17 +0000 (15:35 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 2 May 2024 08:55:25 +0000 (10:55 +0200)
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.

src/stats.c

index 0073e8309a7a5a2fafe2001cf535aca8b14ad9e7..3f3ee0fe3c5b557064e6fb2bd83d5df77ffec8a2 100644 (file)
@@ -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;