]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
BUG/MINOR: log: consider format expression dependencies to decide when to log
authorWilly Tarreau <w@1wt.eu>
Mon, 20 Apr 2026 15:59:53 +0000 (17:59 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 21 Apr 2026 06:01:07 +0000 (08:01 +0200)
Log-format properly takes into account the LW_* flags set by the log
aliases, however its consideration for the sample fetch expressions is
very minimalistic (HTTP y/n). It poses a problem because logging some
statistics doesn't work unless some log aliases are involved to force
the log to wait till the end.

Before this change, the following log-format:

    log-format "res.timer.data=%[res.timer.data]"

would log "res.timer.data=0" regardless of the time taken to transfer
data, and the log would be emitted instantly. However, this line:

    log-format "res.timer.data=%[res.timer.data] %B"

would properly log the time taken to transfer the data because %B which
carries the log flag LW_BYTES forces the log to wait till the end.

This patch makes sure that anything requiring response (headers or body)
waits for at least the response, and that anything requiring response body
or end of transfer (req/res) waits till the end (LW_BYTES). Thanks to
this, the log above is now correct even without the "%B" hack.

This should be backported at least till the latest LTS.

src/log.c

index ba3399ad33a27b5d7346ffbecf89c9abd16fe486..97f06f9ce43ecc91ff0bc62eac394903bcf71710 100644 (file)
--- a/src/log.c
+++ b/src/log.c
@@ -1112,6 +1112,14 @@ int lf_expr_postcheck(struct lf_expr *lf_expr, struct proxy *px, char **err)
                        px->to_log |= LW_XPRT;
                        if (px->http_needed)
                                px->to_log |= LW_REQ;
+
+                       /* anything involving the response needs to happen at response time */
+                       if (expr->fetch->use & (SMP_USE_HRSHP|SMP_USE_HRSHP|SMP_USE_HRSBO))
+                               px->to_log |= LW_RESP;
+
+                       /* anything involving the end of the response needs to happen after final bytes */
+                       if (expr->fetch->use & (SMP_USE_HRSBO|SMP_USE_RQFIN|SMP_USE_RSFIN|SMP_USE_TXFIN|SMP_USE_SSFIN))
+                               px->to_log |= LW_BYTES;
                }
                else if (lf->type == LOG_FMT_ALIAS) {
                        if (!default_px && !http_mode &&