From: Willy Tarreau Date: Tue, 27 Feb 2024 15:17:42 +0000 (+0100) Subject: MINOR: log/applet: add new function syslog_applet_append_event() X-Git-Tag: v3.0-dev6~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=201c706330c8fa248a052d5e22a1ba0259f8bf00;p=thirdparty%2Fhaproxy.git MINOR: log/applet: add new function syslog_applet_append_event() This function takes a buffer on input, and offset and a length, and consumes the block from that buffer to send it to the appctx's output buffer. Contrary to its sibling applet_append_line(), instead of just appending an LF at the end of the line, it prepends the message size in decimal and a space before the message, as expected by syslog TCP implementaions. This will be used to simplify the ring reader code. --- diff --git a/include/haproxy/log.h b/include/haproxy/log.h index 9204410aac..591be3b4b5 100644 --- a/include/haproxy/log.h +++ b/include/haproxy/log.h @@ -87,6 +87,8 @@ 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 list *list_format, char **err); +ssize_t syslog_applet_append_event(void *ctx, const struct buffer *buf, size_t ofs, size_t len); + /* * Parse the log_format string and fill a linked list. * Variable name are preceded by % and composed by characters [a-zA-Z0-9]* : %varname diff --git a/src/log.c b/src/log.c index cd8404b0fc..be44e3c2e0 100644 --- a/src/log.c +++ b/src/log.c @@ -4345,6 +4345,41 @@ static struct applet syslog_applet = { .release = NULL, }; +/* Atomically append an event to applet >ctx>'s output, prepending it with its + * size in decimal followed by a space. + * The line is read from at offset relative to the buffer's head, + * for bytes. It returns the number of bytes consumed from the input + * buffer on success, -1 if it temporarily cannot (buffer full), -2 if it will + * never be able to (too large msg). The input buffer is 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, const struct buffer *buf, size_t ofs, size_t len) +{ + struct appctx *appctx = ctx; + char *p; + + /* first, encode the message's size */ + chunk_reset(&trash); + p = ulltoa(len, trash.area, b_size(&trash)); + if (p) { + trash.data = p - trash.area; + trash.area[trash.data++] = ' '; + } + + /* check if the message has a chance to fit */ + if (unlikely(!p || trash.data + len > b_size(&trash))) + return -2; + + /* try to transfer it or report full */ + trash.data += b_getblk(buf, trash.area + trash.data, len, ofs); + if (applet_putchk(appctx, &trash) == -1) + return -1; + + /* OK done */ + return len; +} + /* * Parse "log-forward" section and create corresponding sink buffer. *