]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ring: support arbitrary delimiters through ring_dispatch_messages()
authorWilly Tarreau <w@1wt.eu>
Mon, 31 Mar 2025 16:17:35 +0000 (18:17 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 Apr 2025 12:36:35 +0000 (14:36 +0200)
In order to support delimiting output events with other characters than
just the LF, let's pass the delimiter through the API. The default remains
the LF, used by applet_append_line(), and ignored by the log forwarder.

include/haproxy/applet.h
include/haproxy/log.h
include/haproxy/ring.h
src/applet.c
src/log.c
src/ring.c
src/sink.c

index 17e1c77daa7fe7c3cea0ec6d8e52bebf6380ed21..700a66795f8ce972a69e8f6d9046df7efc337daa 100644 (file)
@@ -58,7 +58,7 @@ size_t appctx_raw_snd_buf(struct appctx *appctx, struct buffer *buf, size_t coun
 size_t appctx_snd_buf(struct stconn *sc, struct buffer *buf, size_t count, unsigned int flags);
 
 int appctx_fastfwd(struct stconn *sc, unsigned int count, unsigned int flags);
-ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len);
+ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim);
 static forceinline void applet_fl_set(struct appctx *appctx, uint on);
 static forceinline void applet_fl_clr(struct appctx *appctx, uint off);
 
index 99340a67c8ebfd0ff8e53f5097a39b2e3b833c2d..ff69f7b0ef25549922ebf7f8caa59bf4faabe217 100644 (file)
@@ -144,7 +144,7 @@ void app_log(struct list *loggers, struct buffer *tag, int level, const char *fo
  */
 int add_to_logformat_list(char *start, char *end, int type, struct lf_expr *lf_expr, char **err);
 
-ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len);
+ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim);
 
 /*
  * Parse the log_format string and fill a linked list.
index 3eb965a283ed9cb7956b4b7fc3f78c4758dab8cd..f1e28da77e6f3d4fe1b1ef4f60eaf73584d032e3 100644 (file)
@@ -43,7 +43,8 @@ void cli_io_release_show_ring(struct appctx *appctx);
 
 size_t ring_max_payload(const struct ring *ring);
 int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t *last_ofs_ptr, uint flags,
-                           ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len),
+                           ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim),
+                           char delim,
                            size_t *processed);
 
 /* returns the ring storage's usable area */
index fafd7a6d19c34e16a830606b59bf94f8e5eb53a3..1cd10e0382b099b46378ee1591b760345b2221d0 100644 (file)
@@ -737,7 +737,7 @@ end:
        return ret;
 }
 
-/* Atomically append a line to applet <ctx>'s output, appending a trailing LF.
+/* Atomically append a line to applet <ctx>'s output, appending a delimiter.
  * The line is read from vectors <v1> and <v2> at offset <ofs> relative to the
  * area's origin, for <len> bytes. It returns the number of bytes consumed from
  * the input vectors on success, -1 if it temporarily cannot (buffer full), -2
@@ -745,7 +745,7 @@ end:
  * The caller is responsible for making sure that there are at least ofs+len
  * bytes in the input vectors.
  */
-ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len)
+ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim)
 {
        struct appctx *appctx = ctx;
 
@@ -757,7 +757,7 @@ ssize_t applet_append_line(void *ctx, struct ist v1, struct ist v2, size_t ofs,
        chunk_reset(&trash);
        vp_peek_ofs(v1, v2, ofs, trash.area, len);
        trash.data += len;
-       trash.area[trash.data++] = '\n';
+       trash.area[trash.data++] = delim;
        if (applet_putchk(appctx, &trash) == -1)
                return -1;
        return len;
index ca8716d2072636af6d2848f162b17b5602bcb80c..3fae7e60ba96cf885e081da485eff639310332bd 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -5976,7 +5976,7 @@ static struct applet syslog_applet = {
  * large msg). The input vectors are not modified. The caller is responsible for
  * making sure that there are at least ofs+len bytes in the input buffer.
  */
-ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len)
+ssize_t syslog_applet_append_event(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim)
 {
        struct appctx *appctx = ctx;
        char *p;
index 5b5833365b3e4e6d1a6e72f09f1d5a3e807ba7bd..672258b30ea485b4775ae8cac9fbf859825264f5 100644 (file)
@@ -550,7 +550,8 @@ int ring_attach_cli(struct ring *ring, struct appctx *appctx, uint flags)
  * processed by the function (even when the function returns 0)
  */
 int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t *last_ofs_ptr, uint flags,
-                           ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len),
+                           ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim),
+                           char delim,
                            size_t *processed)
 {
        size_t head_ofs, tail_ofs, prev_ofs;
@@ -644,7 +645,7 @@ int ring_dispatch_messages(struct ring *ring, void *ctx, size_t *ofs_ptr, size_t
 
                BUG_ON(msg_len + cnt + 1 > vp_size(v1, v2));
 
-               copied = msg_handler(ctx, v1, v2, cnt, msg_len);
+               copied = msg_handler(ctx, v1, v2, cnt, msg_len, delim);
                if (copied == -2) {
                        /* too large a message to ever fit, let's skip it */
                        goto skip;
@@ -703,7 +704,7 @@ 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, NULL);
+       ret = ring_dispatch_messages(ring, appctx, &ctx->ofs, &last_ofs, ctx->flags, applet_append_line, '\n', NULL);
 
        if (ret && (ctx->flags & RING_WF_WAIT_MODE)) {
                /* we've drained everything and are configured to wait for more
index 5186a423793ed834903841a20619113a68caae48..e10307053f5451b87b85766de0e0d13c4ac093ad 100644 (file)
@@ -412,7 +412,7 @@ void sink_setup_proxy(struct proxy *px)
 }
 
 static void _sink_forward_io_handler(struct appctx *appctx,
-                                     ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len))
+                                     ssize_t (*msg_handler)(void *ctx, struct ist v1, struct ist v2, size_t ofs, size_t len, char delim))
 {
        struct stconn *sc = appctx_sc(appctx);
        struct sink_forward_target *sft = appctx->svcctx;
@@ -446,7 +446,7 @@ static void _sink_forward_io_handler(struct appctx *appctx,
        MT_LIST_DELETE(&appctx->wait_entry);
 
        ret = ring_dispatch_messages(ring, appctx, &sft->ofs, &last_ofs, 0,
-                                    msg_handler, &processed);
+                                    msg_handler, '\n', &processed);
        sft->e_processed += processed;
 
        /* if server's max-reuse is set (>= 0), destroy the applet once the