MINOR: stream/cli: add an optional "older" filter for "show sess"
It's often needed to be able to refine "show sess" when debugging, and very often a first glance at old streams is performed, but that's a difficult task in large dumps, and it takes lots of resources to dump everything. This commit adds "older <age>" to "show sess" in order to specify the minimum age of streams that will be dumped. This should simplify the identification of blocked ones.
This commit is contained in:
parent
ec76e0138b
commit
3ffcf7beb1
|
@ -3144,17 +3144,20 @@ show sess
|
|||
the last one that was created before the command was entered; those which
|
||||
die in the mean time will not appear.
|
||||
|
||||
show sess <id>
|
||||
Display a lot of internal information about the specified session identifier.
|
||||
This identifier is the first field at the beginning of the lines in the dumps
|
||||
of "show sess" (it corresponds to the session pointer). Those information are
|
||||
useless to most users but may be used by haproxy developers to troubleshoot a
|
||||
complex bug. The output format is intentionally not documented so that it can
|
||||
freely evolve depending on demands. You may find a description of all fields
|
||||
returned in src/dumpstats.c
|
||||
|
||||
The special id "all" dumps the states of all sessions, which must be avoided
|
||||
as much as possible as it is highly CPU intensive and can take a lot of time.
|
||||
show sess <id> | older <age> | all
|
||||
Display a lot of internal information about the matching sessions. In the
|
||||
first form, only the session matching the specified session identifier will
|
||||
be shown. This identifier is the first field at the beginning of the lines in
|
||||
the dumps of "show sess" (it corresponds to the session pointer). In the
|
||||
second form, only sessions older than <age> (in seconds by default) will be
|
||||
shown. If "all" is used instead, then all sessions will be dumped. Dumping
|
||||
many sessions can produce a huge output, take a lot of time and be CPU
|
||||
intensive, so it's always better to only dump the minimum needed. Those
|
||||
information are useless to most users but may be used by haproxy developers
|
||||
to troubleshoot a complex bug. The output format is intentionally not
|
||||
documented so that it can freely evolve depending on demands. This output
|
||||
is meant to be interpreted while checking function strm_dump_to_buffer() in
|
||||
src/stream.c to figure the exact meaning of certain fields.
|
||||
|
||||
show stat [domain <dns|proxy>] [{<iid>|<proxy>} <type> <sid>] [typed|json] \
|
||||
[desc] [up|no-maint]
|
||||
|
|
37
src/stream.c
37
src/stream.c
|
@ -3115,6 +3115,7 @@ struct show_sess_ctx {
|
|||
void *target; /* session we want to dump, or NULL for all */
|
||||
unsigned int thr; /* the thread number being explored (0..MAX_THREADS-1) */
|
||||
unsigned int uid; /* if non-null, the uniq_id of the session being dumped */
|
||||
unsigned int min_age; /* minimum age of streams to dump */
|
||||
int section; /* section of the session being dumped */
|
||||
int pos; /* last position of the current session's buffer */
|
||||
};
|
||||
|
@ -3510,16 +3511,32 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx
|
|||
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
||||
return 1;
|
||||
|
||||
if (*args[2] && strcmp(args[2], "all") == 0)
|
||||
ctx->target = (void *)-1;
|
||||
else if (*args[2])
|
||||
ctx->target = (void *)strtoul(args[2], NULL, 0);
|
||||
else
|
||||
ctx->target = NULL;
|
||||
/* now all sessions by default */
|
||||
ctx->target = NULL;
|
||||
ctx->min_age = 0;
|
||||
ctx->section = 0; /* start with stream status */
|
||||
ctx->pos = 0;
|
||||
ctx->thr = 0;
|
||||
|
||||
if (*args[2] && strcmp(args[2], "older") == 0) {
|
||||
unsigned timeout;
|
||||
const char *res;
|
||||
|
||||
if (!*args[3])
|
||||
return cli_err(appctx, "Expects a minimum age (in seconds by default).\n");
|
||||
|
||||
res = parse_time_err(args[3], &timeout, TIME_UNIT_S);
|
||||
if (res != 0)
|
||||
return cli_err(appctx, "Invalid age.\n");
|
||||
|
||||
ctx->min_age = timeout;
|
||||
ctx->target = (void *)-1; /* show all matching entries */
|
||||
}
|
||||
else if (*args[2] && strcmp(args[2], "all") == 0)
|
||||
ctx->target = (void *)-1;
|
||||
else if (*args[2])
|
||||
ctx->target = (void *)strtoul(args[2], NULL, 0);
|
||||
|
||||
/* The back-ref must be reset, it will be detected and set by
|
||||
* the dump code upon first invocation.
|
||||
*/
|
||||
|
@ -3596,6 +3613,12 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (ctx->min_age) {
|
||||
uint age = ns_to_sec(now_ns) - ns_to_sec(curr_strm->logs.request_ts);
|
||||
if (age < ctx->min_age)
|
||||
goto next_sess;
|
||||
}
|
||||
|
||||
if (ctx->target) {
|
||||
if (ctx->target != (void *)-1 && ctx->target != curr_strm)
|
||||
goto next_sess;
|
||||
|
@ -3822,7 +3845,7 @@ static int cli_parse_shutdown_sessions_server(char **args, char *payload, struct
|
|||
|
||||
/* register cli keywords */
|
||||
static struct cli_kw_list cli_kws = {{ },{
|
||||
{ { "show", "sess", NULL }, "show sess [id] : report the list of current sessions or dump this exact session", cli_parse_show_sess, cli_io_handler_dump_sess, cli_release_show_sess },
|
||||
{ { "show", "sess", NULL }, "show sess [<id>|all|older <age>] : report the list of current sessions or dump this exact session", cli_parse_show_sess, cli_io_handler_dump_sess, cli_release_show_sess },
|
||||
{ { "shutdown", "session", NULL }, "shutdown session [id] : kill a specific session", cli_parse_shutdown_session, NULL, NULL },
|
||||
{ { "shutdown", "sessions", "server" }, "shutdown sessions server <bk>/<srv> : kill sessions on a server", cli_parse_shutdown_sessions_server, NULL, NULL },
|
||||
{{},}
|
||||
|
|
Loading…
Reference in New Issue