MINOR: stream/cli: make "show sess" support filtering on front/back/server

With "show sess", particularly "show sess all", we're often missing the
ability to inspect only streams attached to a frontend, backend or server.
Let's just add these filters to the command. Only one at a time may be set.

One typical use case could be to dump streams attached to a server after
issuing "shutdown sessions server XXX" to figure why any wouldn't stop
for example.
This commit is contained in:
Willy Tarreau 2025-03-07 10:34:19 +01:00
parent 2bd7cf53cb
commit 5e558c1727
2 changed files with 77 additions and 0 deletions

View File

@ -3363,7 +3363,10 @@ show sess [<id> | all | help] [<options>*]
It is possible to set some options to customize the dump or apply some
filters. Here are the supported options:
- backend <b> only display streams attached to this backend
- frontend <f> only display streams attached to this frontend
- older <age> only display streams older than <age> seconds
- server <b/s> only show streams attached to this backend+server
- show-uri dump the transaction URI, as captured during the request
analysis. It is only displayed if it was captured.
- susp only show streams considered as suspicious by the developers

View File

@ -3269,10 +3269,14 @@ void list_services(FILE *out)
/* flags used for show_sess_ctx.flags */
#define CLI_SHOWSESS_F_SUSP 0x00000001 /* show only suspicious streams */
#define CLI_SHOWSESS_F_DUMP_URI 0x00000002 /* Dump TXN's uri if available in dump */
#define CLI_SHOWSESS_F_SERVER 0x00000004 /* show only streams attached to this server */
#define CLI_SHOWSESS_F_BACKEND 0x00000008 /* show only streams attached to this backend */
#define CLI_SHOWSESS_F_FRONTEND 0x00000010 /* show only streams attached to this frontend */
struct show_sess_ctx {
struct bref bref; /* back-reference from the session being dumped */
void *target; /* session we want to dump, or NULL for all */
void *filter; /* element to filter on (e.g. server if CLI_SHOWSESS_F_SERVER) */
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 */
@ -3779,6 +3783,9 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx
"Available options: \n"
" show-uri also display the transaction URI, if available\n"
" older <age> only display streams older than <age> seconds\n"
" server <b/s> only show streams attached to this backend+server\n"
" backend <b> only show streams attached to this backend\n"
" frontend <f> only show streams attached to this frontend\n"
"Without any argument, all streams are dumped in a shorter format.");
return cli_err(appctx, trash.area);
}
@ -3796,6 +3803,63 @@ static int cli_parse_show_sess(char **args, char *payload, struct appctx *appctx
else if (*args[cur_arg] && strcmp(args[cur_arg], "susp") == 0) {
ctx->flags |= CLI_SHOWSESS_F_SUSP;
}
else if (*args[cur_arg] && strcmp(args[cur_arg], "server") == 0) {
struct ist be_name, sv_name;
struct proxy *be;
struct server *sv;
if (ctx->flags & (CLI_SHOWSESS_F_FRONTEND|CLI_SHOWSESS_F_BACKEND|CLI_SHOWSESS_F_SERVER))
return cli_err(appctx, "Only one of backend, frontend or server may be set.\n");
if (!*args[cur_arg + 1])
return cli_err(appctx, "Missing server name (<backend>/<server>).\n");
sv_name = ist(args[cur_arg + 1]);
be_name = istsplit(&sv_name, '/');
if (!istlen(sv_name))
return cli_err(appctx, "Require 'backend/server'.\n");
if (!(be = proxy_be_by_name(ist0(be_name))))
return cli_err(appctx, "No such backend.\n");
if (!(sv = server_find_by_name(be, ist0(sv_name))))
return cli_err(appctx, "No such server.\n");
ctx->flags |= CLI_SHOWSESS_F_SERVER;
ctx->filter = sv;
cur_arg++;
}
else if (*args[cur_arg] && strcmp(args[cur_arg], "backend") == 0) {
struct proxy *be;
if (ctx->flags & (CLI_SHOWSESS_F_FRONTEND|CLI_SHOWSESS_F_BACKEND|CLI_SHOWSESS_F_SERVER))
return cli_err(appctx, "Only one of backend, frontend or server may be set.\n");
if (!*args[cur_arg + 1])
return cli_err(appctx, "Missing backend name.\n");
if (!(be = proxy_be_by_name(args[cur_arg + 1])))
return cli_err(appctx, "No such backend.\n");
ctx->flags |= CLI_SHOWSESS_F_BACKEND;
ctx->filter = be;
cur_arg++;
}
else if (*args[cur_arg] && strcmp(args[cur_arg], "frontend") == 0) {
struct proxy *fe;
if (ctx->flags & (CLI_SHOWSESS_F_FRONTEND|CLI_SHOWSESS_F_BACKEND|CLI_SHOWSESS_F_SERVER))
return cli_err(appctx, "Only one of backend, frontend or server may be set.\n");
if (!*args[cur_arg + 1])
return cli_err(appctx, "Missing frontend name.\n");
if (!(fe = proxy_fe_by_name(args[cur_arg + 1])))
return cli_err(appctx, "No such frontend.\n");
ctx->flags |= CLI_SHOWSESS_F_FRONTEND;
ctx->filter = fe;
cur_arg++;
}
else {
chunk_printf(&trash, "Unsupported option '%s', try 'help' for more info.\n", args[cur_arg]);
return cli_err(appctx, trash.area);
@ -3873,6 +3937,16 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
goto next_sess;
}
if ((ctx->flags & CLI_SHOWSESS_F_SERVER) &&
(!(curr_strm->be->cap & PR_CAP_BE) || curr_strm->target != ctx->filter))
goto next_sess;
if ((ctx->flags & CLI_SHOWSESS_F_BACKEND) && (curr_strm->be != ctx->filter))
goto next_sess;
if ((ctx->flags & CLI_SHOWSESS_F_FRONTEND) && (curr_strm->sess->fe != ctx->filter))
goto next_sess;
if (ctx->flags & CLI_SHOWSESS_F_SUSP) {
/* only show suspicious streams. Non-suspicious ones have a valid
* expiration date in the future and a valid front endpoint.