From: Willy Tarreau Date: Mon, 31 Mar 2025 16:17:35 +0000 (+0200) Subject: MINOR: ring: support arbitrary delimiters through ring_dispatch_messages() X-Git-Tag: v3.2-dev10~12 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0be6d73e889c4952aac7652638afa79ba2f6c752;p=thirdparty%2Fhaproxy.git MINOR: ring: support arbitrary delimiters through ring_dispatch_messages() 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. --- diff --git a/include/haproxy/applet.h b/include/haproxy/applet.h index 17e1c77da..700a66795 100644 --- a/include/haproxy/applet.h +++ b/include/haproxy/applet.h @@ -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); diff --git a/include/haproxy/log.h b/include/haproxy/log.h index 99340a67c..ff69f7b0e 100644 --- a/include/haproxy/log.h +++ b/include/haproxy/log.h @@ -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. diff --git a/include/haproxy/ring.h b/include/haproxy/ring.h index 3eb965a28..f1e28da77 100644 --- a/include/haproxy/ring.h +++ b/include/haproxy/ring.h @@ -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 */ diff --git a/src/applet.c b/src/applet.c index fafd7a6d1..1cd10e038 100644 --- a/src/applet.c +++ b/src/applet.c @@ -737,7 +737,7 @@ end: return ret; } -/* Atomically append a line to applet 's output, appending a trailing LF. +/* Atomically append a line to applet 's output, appending a delimiter. * The line is read from vectors and at offset relative to the * area's origin, for 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; diff --git a/src/log.c b/src/log.c index ca8716d20..3fae7e60b 100644 --- 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; diff --git a/src/ring.c b/src/ring.c index 5b5833365..672258b30 100644 --- a/src/ring.c +++ b/src/ring.c @@ -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 diff --git a/src/sink.c b/src/sink.c index 5186a4237..e10307053 100644 --- a/src/sink.c +++ b/src/sink.c @@ -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