]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: stats: introduce stats field ctx
authorAurelien DARRAGON <adarragon@haproxy.com>
Thu, 15 Dec 2022 13:01:04 +0000 (14:01 +0100)
committerWilly Tarreau <w@1wt.eu>
Thu, 15 Dec 2022 15:53:49 +0000 (16:53 +0100)
Add a new value in stats ctx: field.
Implement field support in line dumping parent functions
stats_print_proxy_field_json() and stats_dump_proxy_to_buffer().

This will allow child dumping functions to support partial line dumping
when needed. ie: when dumping buffer is exhausted: do a partial send and
wait for a new buffer to finish the dump. Thanks to field ctx, the function
can start dumping where it left off on previous (unterminated) invokation.

include/haproxy/stats-t.h
src/stats.c

index 4dd65f4d74b8a2eb981201117aac3216c25ea045..9cc1d33a9f20f5b355f35bf2d84d8d7464fe348e 100644 (file)
@@ -540,6 +540,7 @@ struct show_stat_ctx {
        uint32_t domain;        /* set the stats to used, for now only proxy stats are supported */
        int scope_str;          /* limit scope to a frontend/backend substring */
        int scope_len;          /* length of the string above in the buffer */
+       int field;              /* current field iterator when stat line is dumped through returning function */
        int px_st;              /* STAT_PX_ST* */
        unsigned int flags;     /* STAT_* from stats-t.h */
        int iid, type, sid;     /* proxy id, type and service id if bounding of stats is enabled */
index 0d9e4d79a1878145260141b042ebe612526a82fd..1a9f263252203aacf62692d52beb4053175f8e7a 100644 (file)
@@ -3045,8 +3045,11 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
        struct channel *rep = sc_ic(sc);
        struct server *sv, *svs;        /* server and server-state, server-state=server or server->track */
        struct listener *l;
+       int current_field;
 
        chunk_reset(&trash);
+more:
+       current_field = ctx->field;
 
        switch (ctx->px_st) {
        case STAT_PX_ST_INIT:
@@ -3108,8 +3111,11 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
                if (stats_dump_fe_stats(sc, px)) {
                        if (!stats_putchk(rep, htx, &trash))
                                goto full;
+                       if (ctx->field)
+                               goto more;
                }
 
+               current_field = 0;
                ctx->obj2 = px->conf.listeners.n;
                ctx->px_st = STAT_PX_ST_LI;
                __fallthrough;
@@ -3142,9 +3148,12 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
                        if (stats_dump_li_stats(sc, px, l)) {
                                if (!stats_putchk(rep, htx, &trash))
                                        goto full;
+                               if (ctx->field)
+                                       goto more;
                        }
                }
 
+               current_field = 0;
                ctx->obj2 = px->srv; /* may be NULL */
                ctx->px_st = STAT_PX_ST_SV;
                __fallthrough;
@@ -3215,8 +3224,11 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
                if (stats_dump_be_stats(sc, px)) {
                        if (!stats_putchk(rep, htx, &trash))
                                goto full;
+                       if (ctx->field)
+                               goto more;
                }
 
+               current_field = 0;
                ctx->px_st = STAT_PX_ST_END;
                __fallthrough;
 
@@ -3240,6 +3252,8 @@ int stats_dump_proxy_to_buffer(struct stconn *sc, struct htx *htx,
 
   full:
        sc_need_room(sc);
+       /* restore previous field */
+       ctx->field = current_field;
        return 0;
 }
 
@@ -3729,6 +3743,7 @@ static int stats_dump_proxies(struct stconn *sc,
 
                ctx->obj1 = px->next;
                ctx->px_st = STAT_PX_ST_INIT;
+               ctx->field = 0;
        }
 
        return 1;
@@ -3791,6 +3806,7 @@ static int stats_dump_stat_to_buffer(struct stconn *sc, struct htx *htx,
                        ctx->obj1 = proxies_list;
 
                ctx->px_st = STAT_PX_ST_INIT;
+               ctx->field = 0;
                ctx->state = STAT_STATE_LIST;
                __fallthrough;
 
@@ -4579,22 +4595,33 @@ static int stats_dump_info_to_buffer(struct stconn *sc)
 {
        struct appctx *appctx = __sc_appctx(sc);
        struct show_stat_ctx *ctx = appctx->svcctx;
+       int ret;
+       int current_field;
 
        if (!stats_fill_info(info, INF_TOTAL_FIELDS, ctx->flags))
                return 0;
 
        chunk_reset(&trash);
+more:
+       current_field = ctx->field;
 
        if (ctx->flags & STAT_FMT_TYPED)
-               stats_dump_typed_info_fields(&trash, info, ctx);
+               ret = stats_dump_typed_info_fields(&trash, info, ctx);
        else if (ctx->flags & STAT_FMT_JSON)
-               stats_dump_json_info_fields(&trash, info, ctx);
+               ret = stats_dump_json_info_fields(&trash, info, ctx);
        else
-               stats_dump_info_fields(&trash, info, ctx);
+               ret = stats_dump_info_fields(&trash, info, ctx);
 
-       if (applet_putchk(appctx, &trash) == -1)
+       if (applet_putchk(appctx, &trash) == -1) {
+               /* restore previous field */
+               ctx->field = current_field;
                return 0;
-
+       }
+       if (ret && ctx->field) {
+               /* partial dump */
+               goto more;
+       }
+       ctx->field = 0;
        return 1;
 }
 
@@ -4947,6 +4974,7 @@ static int cli_parse_show_info(char **args, char *payload, struct appctx *appctx
        ctx->scope_str = 0;
        ctx->scope_len = 0;
        ctx->flags = 0;
+       ctx->field = 0; /* explicit default value */
 
        while (*args[arg]) {
                if (strcmp(args[arg], "typed") == 0)