]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ring/cli: support delimiting events with a trailing \0 on "show events"
authorWilly Tarreau <w@1wt.eu>
Mon, 31 Mar 2025 16:26:26 +0000 (18:26 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 Apr 2025 12:36:35 +0000 (14:36 +0200)
At the moment it is not supported to produce multi-line events on the
"show events" output, simply because the LF character is used as the
default end-of-event mark. However it could be convenient to produce
well-formatted multi-line events, e.g. in JSON or other formats. UNIX
utilities have already faced similar needs in the past and added
"-print0" to "find" and "-0" to "xargs" to mention that the delimiter
is the NUL character. This makes perfect sense since it's never present
in contents, so let's do exactly the same here.

Thus from now on, "show events <ring> -0" will delimit messages using
a \0 instead of a \n, permitting a better and safer encapsulation.

doc/management.txt
include/haproxy/ring-t.h
src/ring.c
src/sink.c

index face1c89c918f4c195e0cb411a4c1075c2aca831..5ede6d1aae55870687ba32a007a7afbfc252fa06 100644 (file)
@@ -2884,7 +2884,7 @@ 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]
+show events [<sink>] [-w] [-n] [-0]
   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
@@ -2893,7 +2893,9 @@ show events [<sink>] [-w] [-n]
   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. For convenience, "-wn" or "-nw"
-  may be used to enable both options at once.
+  may be used to enable both options at once. 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.
 
 show fd [-!plcfbsd]* [<fd>]
   Dump the list of either all open file descriptors or just the one number <fd>
index 4e091ee0a5b3a63847600b46b2fdf0ed66f9076e..f1fd477271bc26085be364b4f1c053905bbf86c5 100644 (file)
@@ -95,6 +95,7 @@
 /* ring watch flags to be used when watching the ring */
 #define RING_WF_WAIT_MODE  0x00000001   /* wait for new contents */
 #define RING_WF_SEEK_NEW   0x00000002   /* seek to new contents  */
+#define RING_WF_END_ZERO   0x00000004   /* mark end of events with \0 instead of \n */
 
 /* ring flags */
 #define RING_FL_MAPPED     0x00000001 /* mmapped area, must not free() */
index 672258b30ea485b4775ae8cac9fbf859825264f5..fe03f3e369ed17bf0a3d5102ff2ba20e911c1255 100644 (file)
@@ -704,7 +704,8 @@ int cli_io_handler_show_ring(struct appctx *appctx)
 
        MT_LIST_DELETE(&appctx->wait_entry);
 
-       ret = ring_dispatch_messages(ring, appctx, &ctx->ofs, &last_ofs, ctx->flags, applet_append_line, '\n', NULL);
+       ret = ring_dispatch_messages(ring, appctx, &ctx->ofs, &last_ofs, ctx->flags, applet_append_line,
+                                    (ctx->flags & RING_WF_END_ZERO) ? 0 : '\n', NULL);
 
        if (ret && (ctx->flags & RING_WF_WAIT_MODE)) {
                /* we've drained everything and are configured to wait for more
index e10307053f5451b87b85766de0e0d13c4ac093ad..fa1dadc3c56acd5af3e79656c8e0ce28f2e635ee 100644 (file)
@@ -357,7 +357,7 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc
 
        if (!*args[1]) {
                /* no arg => report the list of supported sink */
-               chunk_printf(&trash, "Supported events sinks are listed below. Add -w(wait), -n(new). Any key to stop\n");
+               chunk_printf(&trash, "Supported events sinks are listed below. Add -0(zero), -w(wait), -n(new). 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,
@@ -387,6 +387,8 @@ static int cli_parse_show_events(char **args, char *payload, struct appctx *appc
                        ring_flags |= RING_WF_WAIT_MODE;
                else if (strcmp(args[arg], "-n") == 0)
                        ring_flags |= RING_WF_SEEK_NEW;
+               else if (strcmp(args[arg], "-0") == 0)
+                       ring_flags |= RING_WF_END_ZERO;
                else if (strcmp(args[arg], "-nw") == 0 || strcmp(args[arg], "-wn") == 0)
                        ring_flags |= RING_WF_WAIT_MODE | RING_WF_SEEK_NEW;
                else
@@ -1447,7 +1449,7 @@ REGISTER_POST_CHECK(sink_postcheck);
 REGISTER_POST_DEINIT(sink_deinit);
 
 static struct cli_kw_list cli_kws = {{ },{
-       { { "show", "events", NULL }, "show events [<sink>] [-w] [-n]          : show event sink state", cli_parse_show_events, NULL, NULL },
+       { { "show", "events", NULL }, "show events [<sink>] [-w] [-n] [-0]     : show event sink state", cli_parse_show_events, NULL, NULL },
        {{},}
 }};