From 5e558c172791978d41a2e3f07519bc49ee2337e3 Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Fri, 7 Mar 2025 10:34:19 +0100 Subject: [PATCH] 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. --- doc/management.txt | 3 ++ src/stream.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 77 insertions(+) diff --git a/doc/management.txt b/doc/management.txt index b4bfcf937..e02fd7664 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -3363,7 +3363,10 @@ show sess [ | all | help] [*] It is possible to set some options to customize the dump or apply some filters. Here are the supported options: + - backend only display streams attached to this backend + - frontend only display streams attached to this frontend - older only display streams older than seconds + - server 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 diff --git a/src/stream.c b/src/stream.c index c7ba90d94..2f3a381af 100644 --- a/src/stream.c +++ b/src/stream.c @@ -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 only display streams older than seconds\n" + " server only show streams attached to this backend+server\n" + " backend only show streams attached to this backend\n" + " frontend 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 (/).\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.