mirror of
http://git.haproxy.org/git/haproxy.git/
synced 2025-02-23 14:16:53 +00:00
BUG/MEDIUM: log: improper use of logsrv->maxlen for buffer targets
Ine709e1e
("MEDIUM: logs: buffer targets now rely on new sink_write") we started using the sink API instead of using the ring_write function directly. But as indicated in the commit message, the maxlen parameter of the log directive now only applies to the message part and not the complete payload. I don't know what the original intent was (maybe minimizing code changes) but it seems wrong, because the doc doesn't mention this special case, and the result is that the ring->buffer output can differ from all other log output types, making it very confusing. One last issue with this is that log messages can end up being dropped at runtime, only for the buffer target, and even if logsrv->maxlen is correctly set (including default: 1024) because depending on the generated header size the payload can grow bigger than the accepted sink size (sink maxlen is not mandatory) and we have no simple way to detect this at configuration time. First, we partially reverte709e1e
: TARGET_BUFFER still leverages the proper sink API, but thanks to "MINOR: sink: pass explicit maxlen parameter to sink_write()" we now explicitly pass the logsrv->maxlen to the sink_write function in order to stop writing as soon as either sink->maxlen or logsrv->maxlen is reached. This restores pre-e709e1e behavior with the added benefit from using the high-level API, which includes automatically announcing dropped message events. Then, we also need to take the ending '\n' into account: it is not explicitly set when generating the logline for TARGET_BUFFER, but it will be forcefully added by the sink_forward_io_handler function from the tcp handler applet when log messages from the buffer are forwarded to tcp endpoints. In current form, because the '\n' is added later in the chain, maxlen is not being considered anymore, so the final log message could exceed maxlen by 1 byte, which could make receiving servers unhappy in logging context. To prevent this, we sacrifice 1 byte from the logsrv->maxlen to ensure that the final message will never exceed log->maxlen, even if the '\n' char is automatically appended later by the forwarding applet. Thanks to this change TCP (over RING/BUFFER) target now behaves like FD and UDP targets. This commit depends on: - "MINOR: sink: pass explicit maxlen parameter to sink_write()" It may be backported as far as 2.2 [For 2.2 and 2.4 the patch does not apply automatically, the sink_write() call must be updated by hand]
This commit is contained in:
parent
b6e2d62fb3
commit
47ee036e5f
@ -1685,11 +1685,17 @@ static inline void __do_send_log(struct logsrv *logsrv, int nblogger, int level,
|
||||
send:
|
||||
if (logsrv->type == LOG_TARGET_BUFFER) {
|
||||
struct ist msg;
|
||||
size_t maxlen = logsrv->maxlen;
|
||||
|
||||
msg = ist2(message, size);
|
||||
msg = isttrim(msg, logsrv->maxlen);
|
||||
|
||||
sent = sink_write(logsrv->sink, 0, &msg, 1, level, facility, metadata);
|
||||
/* make room for the final '\n' which may be forcefully inserted
|
||||
* by tcp forwarder applet (sink_forward_io_handler)
|
||||
*/
|
||||
maxlen -= 1;
|
||||
|
||||
sent = sink_write(logsrv->sink, maxlen, &msg, 1, level, facility, metadata);
|
||||
}
|
||||
else if (logsrv->addr.ss_family == AF_CUST_EXISTING_FD) {
|
||||
struct ist msg;
|
||||
|
Loading…
Reference in New Issue
Block a user