From 9141d87830700085ca2e8ea3fdc340350a9a870d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 20 Apr 2026 17:40:25 +0200 Subject: [PATCH] BUG/MINOR: sample: adjust dependencies for channel output bytes counters The bytes_in, bytes_out, {req,res}.bytes_{in,out} sample fetch functions are marked as internal dependencies only. But that's not exact, they are statistics. Request traffic (bytes_in, req.bytes*) is usable starting from the request, while response traffic (bytes_out, res.bytes*) is usable as soon as a response begins to be received, and all are valid till the end of the transaction. The impact is that the log-format below: log-format "req.bytes_in=%[req.bytes_in] req.bytes_out=%[req.bytes_out] res.bytes_in=%[res.bytes_in] res.bytes_out=%[res.bytes_out]" is emitted too early and only logs zeroes when uploading 1MB and downloading 1MB: req.bytes_in=0 req.bytes_out=0 res.bytes_in=15288 res.bytes_out=0 This patch marks the request stats RQFIN and the response stats RSFIN, so that they're valid at any moment and the logs backend knows it must wait for the latest moment to emit such a line. With this change, the line above now correctly produces: req.bytes_in=1000157 req.bytes_out=1000157 res.bytes_in=1048629 res.bytes_out=1048629 This should be backported as far as the latest LTS probably, along with these 2 previous patches: BUG/MINOR: log: consider format expression dependencies to decide when to log MINOR: sample: make RQ/RS stats available everywhere --- src/sample.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/sample.c b/src/sample.c index bc9dadff4..b9a1f0782 100644 --- a/src/sample.c +++ b/src/sample.c @@ -5659,8 +5659,8 @@ static int sample_conv_bytes_check(struct arg *args, struct sample_conv *conv, } static struct sample_fetch_kw_list smp_logs_kws = {ILH, { - { "bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, - { "bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, + { "bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RQFIN }, + { "bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RSFIN }, { "txn.timer.total", smp_fetch_txn_timers, 0, NULL, SMP_T_SINT, SMP_USE_TXFIN }, /* "Ta" */ { "txn.timer.user", smp_fetch_txn_timers, 0, NULL, SMP_T_SINT, SMP_USE_TXFIN }, /* "Tu" */ @@ -5672,14 +5672,14 @@ static struct sample_fetch_kw_list smp_logs_kws = {ILH, { { "fc.timer.handshake", smp_fetch_conn_timers, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, /* "Th" */ { "fc.timer.total", smp_fetch_conn_timers, 0, NULL, SMP_T_SINT, SMP_USE_SSFIN }, /* "Tt" */ - { "req.bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, - { "req.bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, + { "req.bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RQFIN }, + { "req.bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RQFIN }, { "req.timer.idle", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV }, /* "Ti" */ { "req.timer.tq", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV }, /* "Tq" */ { "req.timer.hdr", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_HRQHV }, /* "TR" */ { "req.timer.queue", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV }, /* "Tw" */ - { "res.bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, - { "res.bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_INTRN }, + { "res.bytes_in", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RSFIN }, + { "res.bytes_out", smp_fetch_bytes, 0, NULL, SMP_T_SINT, SMP_USE_RSFIN }, { "res.timer.data", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_RSFIN }, /* "Td" */ { "res.timer.hdr", smp_fetch_reX_timers, 0, NULL, SMP_T_SINT, SMP_USE_HRSHV }, /* "Tr" */ { /* END */ }, -- 2.47.3