]> git.kaiwu.me - haproxy.git/commitdiff
MINOR: ring/cli: improve the "show events" parser regarding options
authorWilly Tarreau <w@1wt.eu>
Mon, 7 Sep 2026 14:20:56 +0000 (16:20 +0200)
committerWilly Tarreau <w@1wt.eu>
Mon, 7 Sep 2026 14:29:16 +0000 (16:29 +0200)
The "show events" parser remains counter-intuitive in that the options
are historically placed after the ring name, making it behave differently
from commonly used tools and other CLI commands.

Let's relax the parser to take any -XXX as a set of option and the only
word not starting with - as the sink name. That way it becomes possible
to parse options before or after the sink name. The doc was updated to
reflect this and present available options as an enumeration rather than
an unreadable wall of text.

doc/management.txt
src/sink.c

index 7f41b3accf91653f9b17132f4c9c3a47ec66cafd..02f3aeef6ea7e022a85aa91b10108b6b947166ef 100644 (file)
@@ -3185,30 +3185,42 @@ show errors [<iid>|<proxy>] [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 [<sink>] [-w] [-n] [-0] [-r] [-s]
-  With no option, this lists all known event sinks and their types. With an
-  option, it will dump all available events in the designated sink if it is of
-  type buffer. If option "-w" is passed after the sink name, then once the end
-  of the buffer is reached, the command will wait for new events and display
-  them. It is possible to stop the operation by entering any input (which will
-  be discarded) or by closing the session. Finally, option "-n" is used to
-  directly seek to the end of the buffer, which is often convenient when
-  combined with "-w" to only report new events. By default, all events are
-  delimited by a line feed character ('\n' or 10 or 0x0A). It is possible to
-  change this to the NUL character ('\0' or 0) by passing the "-0" argument.
-  Option "-s" sanitizes the output, so that binary contents resulting from
-  captured or decoded data do not alter the terminal's rendering. Whitespace
-  characters (space and tab) are replaced with a space so that each record
-  stays on a single line, and the other control characters (0x00 to 0x1F and
-  0x7F) as well as non-ASCII chars (0x80 and above) are replaced with a '?'.
-  The output length is preserved. This way, dumping a ring cannot inject ANSI
-  escape sequences nor writing direction codes into the operator's terminal,
-  which is useful when dumping to a terminal, or to a program whose input must
-  not be interpreted as special (e.g. monitoring scripts whose output is copied
-  verbatim into reports). Finally, "-r" undoes "-s" and may be appended in
-  cases where "-s" was unconditionally appended, or as a future-proof way to
-  ensure long-term compatibility in case the default changes. All options
-  starting with "-" may conveniently be combined (e.g. "-nsw").
+show events  [-[wn0rs]*] [<sink>]
+  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
+  beginning with "-", and optionally grouped together behind the same "-":
+
+    -0  by default, all events are delimited on output by a line feed character
+        ('\n' or 10 or 0x0A). Option "-0" changes this delimiter to the NUL
+        character ('\0' or 0), which might be more convenient for external
+        tools.
+
+    -n  directly seeks to the end of the buffer, which is generally combined
+        with "-w" to only report new events (like "tail -f").
+
+    -r  undoes "-s", i.e. switches the output to raw mode in case it was
+        already in sanitized mode (via a previous option). This is recommended
+        for tools that want to be future-proof in case the default format
+        eventually changes.
+
+    -s  sanitizes the output, so that binary contents resulting from captured
+        or decoded data do not alter the terminal's rendering. Whitespace
+        characters (spaces and tabs) are replaced with a space so that each
+        record stays on a single line, and the other control characters (0x00
+        to 0x1F and 0x7F) as well as non-ASCII chars (0x80 and above) are
+        replaced with a '?'. The output length is preserved. This way, dumping
+        a ring cannot inject ANSI escape sequences nor writing direction codes
+        into the operator's terminal, which is useful when dumping to a
+        terminal, or to a program whose input must not be interpreted as
+        special (e.g. monitoring scripts whose output is copied verbatim into
+        reports).
+
+    -w  once the end of the buffer is reached, the command will wait for new
+        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.
 
 show fd [-!plcfbs]* [[<tgid>]/[<fd>] | <fd>]
   Dump the list of either all open file descriptors or just the one number <fd>
index 25f76ba3f56c2a218a4dbf5c2b308feb5c75b5b6..1b43343ca8945f6cc0c599986496fa81559e2d57 100644 (file)
@@ -356,12 +356,35 @@ leave:
 static int cli_parse_show_events(char **args, char *payload, struct appctx *appctx, void *private)
 {
        struct sink *sink;
+       const char *name = NULL;
        uint ring_flags;
        int arg;
 
-       args++; // make args[1] the 1st arg
+       ring_flags = 0;
+       for (arg = 2; *args[arg]; arg++) {
+               const char *p = args[arg];
+
+               if (*p != '-') {
+                       /* that's a sink name */
+                       if (name)
+                               return cli_err(appctx, "only one sink name may be specified.");
+                       name = p;
+                       continue;
+               }
+
+               while (*++p) {
+                       switch (*p) {
+                       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 's' : ring_flags |= RING_WF_SANITIZE;  break;
+                       case 'r' : ring_flags &= ~RING_WF_SANITIZE; break;
+                       default: return cli_err(appctx, "unknown option");
+                       }
+               }
+       }
 
-       if (!*args[1]) {
+       if (!name) {
                /* no arg => report the list of supported sink */
                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");
                list_for_each_entry(sink, &sink_list, sink_list) {
@@ -380,31 +403,13 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc
        if (!cli_has_level(appctx, ACCESS_LVL_OPER))
                return 1;
 
-       sink = sink_find(args[1]);
+       sink = sink_find(name);
        if (!sink)
                return cli_err(appctx, "No such event sink");
 
        if (sink->type != SINK_TYPE_BUFFER)
                return cli_msg(appctx, LOG_NOTICE, "Nothing to report for this sink");
 
-       ring_flags = 0;
-       for (arg = 2; *args[arg]; arg++) {
-               const char *p = args[arg];
-
-               if (*p != '-')
-                       continue;
-
-               while (*++p) {
-                       switch (*p) {
-                       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 's' : ring_flags |= RING_WF_SANITIZE;  break;
-                       case 'r' : ring_flags &= ~RING_WF_SANITIZE; break;
-                       default: return cli_err(appctx, "unknown option");
-                       }
-               }
-       }
        return ring_attach_cli(sink->ctx.ring, appctx, ring_flags);
 }
 
@@ -1498,7 +1503,7 @@ REGISTER_POST_CHECK(sink_postcheck);
 REGISTER_POST_DEINIT(sink_deinit);
 
 static struct cli_kw_list cli_kws = {{ },{
-       { { "show", "events", NULL }, "show events [<sink>] [-0nrsw]*          : show event sink state", cli_parse_show_events, NULL, NULL },
+       { { "show", "events", NULL }, "show events [-0nrsw]* [<sink>]          : show event sink state", cli_parse_show_events, NULL, NULL },
        {{},}
 }};