MINOR: cli/activity: add a thread number argument to "show activity"
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.
This commit is contained in:
parent
dadf00e226
commit
9a7fa90239
|
@ -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
|
||||
|
|
57
src/cli.c
57
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},
|
||||
|
|
Loading…
Reference in New Issue