MINOR: http_fetch: Add support for checks to unique-id fetch
Some checks are pending
Contrib / build (push) Waiting to run
alpine/musl / gcc (push) Waiting to run
VTest / Generate Build Matrix (push) Waiting to run
VTest / (push) Blocked by required conditions
Windows / Windows, gcc, all features (push) Waiting to run

This allows to use the `unique-id` fetch within `tcp-check` or `http-check`
ruleset. The format is taken from the checked server's backend (which is
naturally inherited from the corresponding `defaults` section).

This is particularly useful with

    http-check send ... hdr request-id %[unique-id]

to ensure all requests sent by HAProxy have a unique ID header attached.

This resolves GitHub Issue #3307.

Reviewed-by: Volker Dusch <github@wallbash.com>
This commit is contained in:
Tim Duesterhus 2026-04-13 19:37:31 +02:00 committed by Willy Tarreau
parent 2c748125f5
commit ed0c51d2c0
3 changed files with 70 additions and 7 deletions

View file

@ -6186,7 +6186,7 @@ timeout server-fin X - X X
timeout tarpit X X X X
timeout tunnel X - X X
transparent (deprecated) X - X X
unique-id-format X X X -
unique-id-format X X X X
unique-id-header X X X -
use_backend - X X -
use-fcgi-app - - X X
@ -15020,7 +15020,7 @@ unique-id-format <fmt>
May be used in the following contexts: tcp, http
May be used in sections : defaults | frontend | listen | backend
yes | yes | yes | no
yes | yes | yes | yes
Arguments :
<fmt> is a Custom log format string (see section 8.2.6).
@ -15042,6 +15042,11 @@ unique-id-format <fmt>
It is recommended to use hexadecimal notation for many fields since it
makes them more compact and saves space in logs.
For regular connections the format configured in the frontend is used to
generate the unique ID. For health checks the format of the backend is
used when using the "unique-id" fetch within a tcp-check or an http-check
ruleset.
Example:
unique-id-format %{+X}o\ %ci:%cp_%fi:%fp_%Ts_%rt:%pid

View file

@ -0,0 +1,49 @@
varnishtest "Health-checks: unique_id fetch"
feature ignore_unknown_macro
#REGTEST_TYPE=slow
server s1 {
rxreq
expect req.method == GET
expect req.url == /
expect req.proto == HTTP/1.1
expect req.http.host == "localhost"
expect req.http.request-id == "TEST-be=up"
txresp
} -start
syslog S1 -level notice {
recv
expect ~ "[^:\\[ ]\\[${h1_pid}\\]: Health check for server be/srv succeeded.*code: 200"
} -start
haproxy h1 -conf {
global
.if feature(THREAD)
thread-groups 1
.endif
defaults
mode http
timeout client "${HAPROXY_TEST_TIMEOUT-5s}"
timeout server "${HAPROXY_TEST_TIMEOUT-5s}"
timeout connect "${HAPROXY_TEST_TIMEOUT-5s}"
option httpchk
option log-health-checks
backend be
log ${S1_addr}:${S1_port} len 2048 local0
unique-id-format TEST-%[be_name]=%[srv_is_up(srv),iif(up,down)]
http-check connect
http-check send meth GET uri / ver HTTP/1.1 hdr host localhost hdr request-id %[unique-id]
http-check expect status 200
## implicit expect rule
server srv ${s1_addr}:${s1_port} check inter 100ms rise 1 fall 1
} -start
syslog S1 -wait

View file

@ -22,6 +22,7 @@
#include <haproxy/base64.h>
#include <haproxy/channel.h>
#include <haproxy/chunk.h>
#include <haproxy/check.h>
#include <haproxy/connection.h>
#include <haproxy/global.h>
#include <haproxy/h1.h>
@ -504,14 +505,22 @@ static int smp_fetch_srv_status(const struct arg *args, struct sample *smp, cons
static int smp_fetch_uniqueid(const struct arg *args, struct sample *smp, const char *kw, void *private)
{
struct ist unique_id;
struct check *check;
if (lf_expr_isempty(&smp->sess->fe->format_unique_id))
if (smp->strm) {
if (lf_expr_isempty(&smp->sess->fe->format_unique_id))
return 0;
unique_id = stream_generate_unique_id(smp->strm, &smp->sess->fe->format_unique_id);
} else if ((check = objt_check(smp->sess->origin)) != NULL) {
if (lf_expr_isempty(&check->proxy->format_unique_id))
return 0;
unique_id = check_generate_unique_id(check, &check->proxy->format_unique_id);
} else {
return 0;
}
if (!smp->strm)
return 0;
unique_id = stream_generate_unique_id(smp->strm, &smp->sess->fe->format_unique_id);
if (!isttest(unique_id))
return 0;