mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-07 15:47:01 +02:00
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
|
the last one that was created before the command was entered; those which
|
||||||
die in the mean time will not appear.
|
die in the mean time will not appear.
|
||||||
|
|
||||||
show sess <id>
|
show sess <id> | older <age> | all
|
||||||
Display a lot of internal information about the specified session identifier.
|
Display a lot of internal information about the matching sessions. In the
|
||||||
This identifier is the first field at the beginning of the lines in the dumps
|
first form, only the session matching the specified session identifier will
|
||||||
of "show sess" (it corresponds to the session pointer). Those information are
|
be shown. This identifier is the first field at the beginning of the lines in
|
||||||
useless to most users but may be used by haproxy developers to troubleshoot a
|
the dumps of "show sess" (it corresponds to the session pointer). In the
|
||||||
complex bug. The output format is intentionally not documented so that it can
|
second form, only sessions older than <age> (in seconds by default) will be
|
||||||
freely evolve depending on demands. You may find a description of all fields
|
shown. If "all" is used instead, then all sessions will be dumped. Dumping
|
||||||
returned in src/dumpstats.c
|
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
|
||||||
The special id "all" dumps the states of all sessions, which must be avoided
|
information are useless to most users but may be used by haproxy developers
|
||||||
as much as possible as it is highly CPU intensive and can take a lot of time.
|
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] \
|
show stat [domain <dns|proxy>] [{<iid>|<proxy>} <type> <sid>] [typed|json] \
|
||||||
[desc] [up|no-maint]
|
[desc] [up|no-maint]
|
||||||
|
35
src/stream.c
35
src/stream.c
@ -3115,6 +3115,7 @@ struct show_sess_ctx {
|
|||||||
void *target; /* session we want to dump, or NULL for all */
|
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 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 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 section; /* section of the session being dumped */
|
||||||
int pos; /* last position of the current session's buffer */
|
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))
|
if (!cli_has_level(appctx, ACCESS_LVL_OPER))
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (*args[2] && strcmp(args[2], "all") == 0)
|
/* now all sessions by default */
|
||||||
ctx->target = (void *)-1;
|
|
||||||
else if (*args[2])
|
|
||||||
ctx->target = (void *)strtoul(args[2], NULL, 0);
|
|
||||||
else
|
|
||||||
ctx->target = NULL;
|
ctx->target = NULL;
|
||||||
|
ctx->min_age = 0;
|
||||||
ctx->section = 0; /* start with stream status */
|
ctx->section = 0; /* start with stream status */
|
||||||
ctx->pos = 0;
|
ctx->pos = 0;
|
||||||
ctx->thr = 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 back-ref must be reset, it will be detected and set by
|
||||||
* the dump code upon first invocation.
|
* the dump code upon first invocation.
|
||||||
*/
|
*/
|
||||||
@ -3596,6 +3613,12 @@ static int cli_io_handler_dump_sess(struct appctx *appctx)
|
|||||||
continue;
|
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) {
|
||||||
if (ctx->target != (void *)-1 && ctx->target != curr_strm)
|
if (ctx->target != (void *)-1 && ctx->target != curr_strm)
|
||||||
goto next_sess;
|
goto next_sess;
|
||||||
@ -3822,7 +3845,7 @@ static int cli_parse_shutdown_sessions_server(char **args, char *payload, struct
|
|||||||
|
|
||||||
/* register cli keywords */
|
/* register cli keywords */
|
||||||
static struct cli_kw_list cli_kws = {{ },{
|
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", "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 },
|
{ { "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
Block a user