From: Amaury Denoyelle Date: Mon, 2 Nov 2026 16:03:36 +0000 (+0100) Subject: MINOR: sink: add timeout argument for "show events" X-Git-Url: https://git.kaiwu.me/?a=commitdiff_plain;h=16e86dae4bfa3731200bd9d8b998ba0d93617b29;p=haproxy.git MINOR: sink: add timeout argument for "show events" Define a new "-u" argument for the CLI show events command. This allows activating the uninterruptible execution mode for cli_io_handler_show_ring(). The inactivity delay is directly derived from the configured stats timeout. --- diff --git a/doc/management.txt b/doc/management.txt index 7632544d0..45d94176c 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -3247,7 +3247,7 @@ show errors [|] [request|response] error was at byte 23. This is the slash ('/') in header name "header/bizarre", which is not a valid HTTP character for a header name. -show events [-[wn0rs]*] [] +show events [-[wun0rs]*] [] With no option, this lists all known event sinks and their types. Arguments not starting with "-" are taken for a sink name, whose events will be dumped if it is of type buffer. The command also supports a variety of options @@ -3284,7 +3284,16 @@ show events [-[wn0rs]*] [] events and display them. It is possible to stop the operation by entering any input (which will be discarded) or by closing the session. Note that using "echo show events -w | socat ..." does close the input - and interrupt the dump. + and interrupt the dump; see '-u' option instead in this case. + + -u executes the command as an uninterruptible job. This is useful when + using utilities such as 'socat' to continue running after a half-close + of the CLI input. The command will still be stopped in this case if a + send error occurs while dumping new events or if no events are detected + after a delay based on the configured stats timeout. + + Example : + $ echo "show events -u buf0" | socat -t10 - /var/run/haproxy.sock show fd [-!plcfbs]* [[]/[] | ] Dump the list of either all open file descriptors or just the one number diff --git a/src/ring.c b/src/ring.c index e15dbb85b..a7aba4494 100644 --- a/src/ring.c +++ b/src/ring.c @@ -838,6 +838,7 @@ void cli_io_release_show_ring(struct appctx *appctx) size_t ofs = ctx->ofs; ring_detach_appctx(ring, appctx, ofs); + cli_dec_unintr(appctx); } /* Returns the MAXIMUM payload len that could theoretically fit into the ring diff --git a/src/sink.c b/src/sink.c index 7b1cfa1e8..46c5f810d 100644 --- a/src/sink.c +++ b/src/sink.c @@ -358,7 +358,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc struct sink *sink; const char *name = NULL; uint ring_flags; - int arg; + int arg, ret, unintr = 0; ring_flags = 0; for (arg = 2; *args[arg]; arg++) { @@ -377,6 +377,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc case '0' : ring_flags |= RING_WF_END_ZERO; break; case 'n' : ring_flags |= RING_WF_SEEK_NEW; break; case 'w' : ring_flags |= RING_WF_WAIT_MODE; break; + case 'u' : ring_flags |= RING_WF_WAIT_MODE; unintr = 1; break; case 's' : ring_flags |= RING_WF_SANITIZE; break; case 'r' : ring_flags &= ~RING_WF_SANITIZE; break; case 'h' : goto show_help; @@ -388,7 +389,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc if (!name) { /* no arg => report the list of supported sink */ show_help: - chunk_printf(&trash, "Supported events sinks are listed below. Add combinations of -0(zero), -w(wait), -n(new), -r(raw), -s(anitize). Any key to stop.\n"); + chunk_printf(&trash, "Supported events sinks are listed below. Add combinations of -0(zero), -w(wait), -u(ninterruptible), -n(new), -r(raw), -s(anitize). Any key to stop.\n"); list_for_each_entry(sink, &sink_list, sink_list) { chunk_appendf(&trash, " %-10s : type=%s, %u dropped, %s\n", sink->name, @@ -412,7 +413,15 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc if (sink->type != SINK_TYPE_BUFFER) return cli_msg(appctx, LOG_NOTICE, "Nothing to report for this sink"); - return ring_attach_cli(sink->ctx.ring, appctx, ring_flags); + if (unintr && cli_inc_unintr(appctx)) + return cli_err(appctx, "Cannot start a new uninterruptible job"); + + ret = ring_attach_cli(sink->ctx.ring, appctx, ring_flags); + if (ret && unintr) { + /* attach failure, decrement uninterruptible job counter */ + cli_dec_unintr(appctx); + } + return ret; } /* Pre-configures a ring proxy to emit connections */ @@ -1512,7 +1521,7 @@ REGISTER_POST_CHECK(sink_postcheck); REGISTER_POST_DEINIT(sink_deinit); static struct cli_kw_list cli_kws = {{ },{ - { { "show", "events", NULL }, "show events [-0hnrsw]* [] : show event sink state", cli_parse_show_events, NULL, NULL }, + { { "show", "events", NULL }, "show events [-0hnrswu]* [] : show event sink state", cli_parse_show_events, NULL, NULL }, {{},} }};