]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cli/activity: add a thread number argument to "show activity"
authorWilly Tarreau <w@1wt.eu>
Fri, 15 Jul 2022 14:51:16 +0000 (16:51 +0200)
committerWilly Tarreau <w@1wt.eu>
Fri, 15 Jul 2022 17:41:26 +0000 (19:41 +0200)
The output of "show activity" can be so large that the output is visually
unreadable on a screen. Let's add an option to filter on the desired
column (actually the thread number), use "0" to report only the first
column (aggregated/sum/avg), and use "-1", the default, for the normal
detailed dump.

doc/management.txt
src/cli.c

index e65ac471ad6a9d2bd3c1dd8fd383abea3565923e..6aeb08d38b6fc6239acf0408b964284a65328c43 100644 (file)
@@ -2488,7 +2488,7 @@ user
   increased. It also drops expert and experimental mode. See also "show cli
   level".
 
-show activity
+show activity [-1 | 0 | thread_num]
   Reports some counters about internal events that will help developers and
   more generally people who know haproxy well enough to narrow down the causes
   of reports of abnormal behaviours. A typical example would be a properly
@@ -2498,7 +2498,14 @@ show activity
   is not a problem since calls to this command will typically be performed
   twice. The fields are purposely not documented so that their exact meaning is
   verified in the code where the counters are fed. These values are also reset
-  by the "clear counters" command.
+  by the "clear counters" command. On multi-threaded deployments, the first
+  column will indicate the total (or average depending on the nature of the
+  metric) for all threads, and the list of all threads' values will be
+  represented between square brackets in the thread order. Optionally the
+  thread number to be dumped may be specified in argument. The special value
+  "0" will report the aggregated value (first column), and "-1", which is the
+  default, will display all the columns. Note that just like in single-threaded
+  mode, there will be no brackets when a single column is requested.
 
 show cli sockets
   List CLI sockets. The output format is composed of 3 fields separated by
index bd77418fe596e9493cf0075b29e403302dde15fc..419466524b196d3e293b03a61eaa2e4368dea664 100644 (file)
--- a/src/cli.c
+++ b/src/cli.c
@@ -86,6 +86,11 @@ extern const char *stat_status_codes[];
 
 struct proxy *mworker_proxy; /* CLI proxy of the master */
 
+/* CLI context for the "show activity" command */
+struct show_activity_ctx {
+       int thr;         /* thread ID to show or -1 for all */
+};
+
 /* CLI context for the "show env" command */
 struct show_env_ctx {
        char **var;      /* first variable to show */
@@ -1463,6 +1468,8 @@ static int cli_io_handler_show_fd(struct appctx *appctx)
 static int cli_io_handler_show_activity(struct appctx *appctx)
 {
        struct stconn *sc = appctx_sc(appctx);
+       struct show_activity_ctx *actctx = appctx->svcctx;
+       int tgt = actctx->thr; // target thread, -1 for all, 0 for total only
        int thr;
 
        if (unlikely(sc_ic(sc)->flags & (CF_WRITE_ERROR|CF_SHUTW)))
@@ -1484,10 +1491,15 @@ static int cli_io_handler_show_activity(struct appctx *appctx)
                        chunk_appendf(&trash, " %u\n", _tot);           \
                        break;                                          \
                }                                                       \
-               chunk_appendf(&trash, " %u [", _tot);                   \
-               for (t = 0; t < _nbt; t++)                              \
-                       chunk_appendf(&trash, " %u", _v[t]);            \
-               chunk_appendf(&trash, " ]\n");                          \
+               if (tgt == -1) {                                        \
+                       chunk_appendf(&trash, " %u [", _tot);           \
+                       for (t = 0; t < _nbt; t++)                      \
+                               chunk_appendf(&trash, " %u", _v[t]);    \
+                       chunk_appendf(&trash, " ]\n");                  \
+               } else if (tgt == 0)                                    \
+                               chunk_appendf(&trash, " %u\n", _tot);   \
+                       else                                            \
+                               chunk_appendf(&trash, " %u\n", _v[tgt-1]);\
        } while (0)
 
 #undef SHOW_AVG
@@ -1504,10 +1516,15 @@ static int cli_io_handler_show_activity(struct appctx *appctx)
                        chunk_appendf(&trash, " %u\n", _tot);           \
                        break;                                          \
                }                                                       \
-               chunk_appendf(&trash, " %u [", (_tot + _nbt/2) / _nbt); \
-               for (t = 0; t < _nbt; t++)                              \
-                       chunk_appendf(&trash, " %u", _v[t]);            \
-               chunk_appendf(&trash, " ]\n");                          \
+               if (tgt == -1) {                                        \
+                       chunk_appendf(&trash, " %u [", (_tot + _nbt/2) / _nbt); \
+                       for (t = 0; t < _nbt; t++)                      \
+                               chunk_appendf(&trash, " %u", _v[t]);    \
+                       chunk_appendf(&trash, " ]\n");                  \
+               } else if (tgt == 0)                                    \
+                               chunk_appendf(&trash, " %u\n", (_tot + _nbt/2) / _nbt); \
+                       else                                            \
+                               chunk_appendf(&trash, " %u\n", _v[tgt-1]);\
        } while (0)
 
        chunk_appendf(&trash, "thread_id: %u (%u..%u)\n", tid + 1, 1, global.nbthread);
@@ -1636,6 +1653,28 @@ static int cli_io_handler_show_cli_sock(struct appctx *appctx)
 }
 
 
+/* parse a "show activity" CLI request. Returns 0 if it needs to continue, 1 if it
+ * wants to stop here. It sets a show_activity_ctx context where, if a specific
+ * thread is requested, it puts the thread number into ->thr otherwise sets it to
+ * -1.
+ */
+static int cli_parse_show_activity(char **args, char *payload, struct appctx *appctx, void *private)
+{
+       struct show_activity_ctx *ctx = applet_reserve_svcctx(appctx, sizeof(*ctx));
+
+       if (!cli_has_level(appctx, ACCESS_LVL_OPER))
+               return 1;
+
+       ctx->thr = -1; // show all by default
+       if (*args[2])
+               ctx->thr = atoi(args[2]);
+
+       if (ctx->thr < -1 || ctx->thr > global.nbthread)
+               return cli_err(appctx, "Thread ID number must be between -1 and nbthread\n");
+
+       return 0;
+}
+
 /* parse a "show env" CLI request. Returns 0 if it needs to continue, 1 if it
  * wants to stop here. It reserves a sohw_env_ctx where it puts the variable to
  * be dumped as well as a flag if a single variable is requested, otherwise puts
@@ -3164,7 +3203,7 @@ static struct cli_kw_list cli_kws = {{ },{
        { { "show", "cli", "sockets",  NULL },   "show cli sockets                        : dump list of cli sockets",                                cli_parse_default, cli_io_handler_show_cli_sock, NULL, NULL, ACCESS_MASTER },
        { { "show", "cli", "level", NULL },      "show cli level                          : display the level of the current CLI session",            cli_parse_show_lvl, NULL, NULL, NULL, ACCESS_MASTER},
        { { "show", "fd", NULL },                "show fd [num]                           : dump list of file descriptors in use or a specific one",  cli_parse_show_fd, cli_io_handler_show_fd, NULL },
-       { { "show", "activity", NULL },          "show activity                           : show per-thread activity stats (for support/developers)", cli_parse_default, cli_io_handler_show_activity, NULL },
+       { { "show", "activity", NULL },          "show activity [-1|0|thread_num]         : show per-thread activity stats (for support/developers)", cli_parse_show_activity, cli_io_handler_show_activity, NULL },
        { { "show", "version", NULL },           "show version                            : show version of the current process",                     cli_parse_show_version, NULL, NULL, NULL, ACCESS_MASTER },
        { { "operator", NULL },                  "operator                                : lower the level of the current CLI session to operator",  cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER},
        { { "user", NULL },                      "user                                    : lower the level of the current CLI session to user",      cli_parse_set_lvl, NULL, NULL, NULL, ACCESS_MASTER},