From 5c0d1c1a74d86b252b4cfd2fda672a1038711d5a Mon Sep 17 00:00:00 2001 From: Aurelien DARRAGON Date: Fri, 25 Aug 2023 09:50:27 +0200 Subject: [PATCH] MEDIUM: sink: inherit from caller fmt in ring_write() when rings didn't set one implicit rings were automatically forced to the parent logger format, but this was done upon ring creation. This is quite restrictive because we might want to choose the desired format right before generating the log header (ie: when producing the log message), depending on the logger (log directive) that is responsible for the log message, and with current logic this is not possible. (To this day, we still have dedicated implicit ring per log directive, but this might change) In ring_write(), we check if the sink->fmt is specified: - defined: we use it since it is the most precise format (ie: for named rings) - undefined: then we fallback to the format from the logger With this change, implicit rings' format is now set to UNSPEC upon creation. This is safe because the log header building function automatically enforces the "raw" format when UNSPEC is set. And since logger->format also defaults to "raw", no change of default behavior should be expected. --- include/haproxy/sink.h | 3 ++- src/sink.c | 24 ++++++++++++++++-------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/include/haproxy/sink.h b/include/haproxy/sink.h index bed687fe3..e88208de8 100644 --- a/include/haproxy/sink.h +++ b/include/haproxy/sink.h @@ -38,7 +38,8 @@ int sink_announce_dropped(struct sink *sink, struct log_header hdr); /* tries to send message parts from message array to sink . - * Formatting according to the sink's preferences is done here. + * Formatting according to the sink's preference is done here, unless sink->fmt + * is unspecified, in which case the caller formatting will be used instead. * * It will stop writing at instead of sink->maxlen if is * positive and inferior to sink->maxlen. diff --git a/src/sink.c b/src/sink.c index 569b4c8d2..ef9e3b158 100644 --- a/src/sink.c +++ b/src/sink.c @@ -165,9 +165,11 @@ struct sink *sink_new_buf(const char *name, const char *desc, enum log_fmt fmt, } /* tries to send message parts from message array to sink . - * Formatting according to the sink's preference is done here. Lost messages - * are NOT accounted for. It is preferable to call sink_write() instead which - * will also try to emit the number of dropped messages when there are any. + * Formatting according to the sink's preference is done here, unless sink->fmt + * is unspecified, in which case the caller formatting will be used instead. + * Lost messages are NOT accounted for. It is preferable to call sink_write() + * instead which will also try to emit the number of dropped messages when there + * are any. * * It will stop writing at instead of sink->maxlen if is * positive and inferior to sink->maxlen. @@ -183,7 +185,8 @@ struct sink *sink_new_buf(const char *name, const char *desc, enum log_fmt fmt, if (sink->fmt == LOG_FORMAT_RAW) goto send; - hdr.format = sink->fmt; /* sink format prevails over log one */ + if (sink->fmt != LOG_FORMAT_UNSPEC) + hdr.format = sink->fmt; /* sink format prevails over log one */ pfx = build_log_header(hdr, &npfx); send: @@ -1191,11 +1194,16 @@ struct sink *sink_new_from_logger(struct logger *logger) goto error; } - /* disable sink->maxlen, we already have logger->maxlen */ - sink->maxlen = 0; + /* ring format normally defaults to RAW, but here we set ring format + * to UNSPEC to inherit from caller format in sink_write() since we + * cannot customize implicit ring settings + */ + sink->fmt = LOG_FORMAT_UNSPEC; - /* set ring format from logger format */ - sink->fmt = logger->format; + /* for the same reason, we disable sink->maxlen to inherit from caller + * maxlen in sink_write() + */ + sink->maxlen = 0; /* Set default connect and server timeout for sink forward proxy */ sink->forward_px->timeout.connect = MS_TO_TICKS(1000);