From: Christopher Faulet Date: Tue, 30 Apr 2024 15:52:04 +0000 (+0200) Subject: MINOR: connection: Add samples to retrieve info on streams for a connection X-Git-Tag: v3.0-dev11~28 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=bd47e344b86f35e828f18ace14027e37ee68e88b;p=thirdparty%2Fhaproxy.git MINOR: connection: Add samples to retrieve info on streams for a connection Thanks to the previous fix, it is now possible to get the number of opened streams for a connection and the negociated limit. Here, corresponding sample feches are added, in fc_ and bc_ scopes. On frontend side, the limit of streams is imposed by HAProxy. But on the backend side, the limit is defined by the server. it may be useful for debugging purpose because it may explain slow-downs on some processing. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index ed9b67f347..bb3515bbc3 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -21366,9 +21366,11 @@ bc_err integer bc_err_str string bc_glitches integer bc_http_major integer +bc_nb_streams integer bc_src ip bc_src_port integer bc_srv_queue integer +bc_settings_streams_limit integer be_id integer be_name string bc_rtt() integer @@ -21395,6 +21397,7 @@ fc_fackets integer fc_glitches integer fc_http_major integer fc_lost integer +fc_nb_streams integer fc_pp_authority string fc_pp_unique_id string fc_pp_tlv() string @@ -21407,6 +21410,7 @@ fc_sacked integer fc_src ip fc_src_is_local boolean fc_src_port integer +fc_settings_streams_limit integer fc_unacked integer fe_defbe string fe_id integer @@ -21639,6 +21643,9 @@ bc_http_major : integer for HTTP/0.9 to HTTP/1.1 or 2 for HTTP/2. Note, this is based on the on-wire encoding and not the version present in the request header. +bc_nb_streams : integer + Returns the number of streams opened on the backend connection. + bc_src : ip This is the source ip address of the connection on the server side, which is the server address HAProxy connected from. It is of type IP and works on both @@ -21653,6 +21660,11 @@ bc_srv_queue : integer Number of streams de-queued while waiting for a connection slot on the target server. This is the equivalent of %sq in the log-format. +bc_settings_streams_limit : integer + Returns the maximum number of streams allowed on the backend connection. For + TCP and HTTP/1.1 connections, it is always 1. For other protocols, it depends + on the settings negociated with the server. + be_id : integer Returns an integer containing the current backend's id. It can be used in frontends with responses to check which backend processed the request. If @@ -21877,6 +21889,9 @@ fc_lost : integer not TCP or if the operating system does not support TCP_INFO, for example Linux kernels before 2.4, the sample fetch fails. +fc_nb_streams : integer + Returns the number of streams opened on the frontend connection. + fc_pp_authority : string Returns the first authority TLV sent by the client in the PROXY protocol header, if any. @@ -21962,6 +21977,10 @@ fc_src_port : integer connection on the client side. Only "tcp-request connection" rules may alter this address. See "src-port" for details. +fc_settings_streams_limit : integer + Returns the maximum number of streams allowed on the frontend connection. For + TCP and HTTP/1.1 connections, it is always 1. For other protocols, it depends + on the settings negociated with the client. fc_unacked : integer Returns the unacked counter measured by the kernel for the client connection. diff --git a/src/connection.c b/src/connection.c index f9e05c3737..46526b141f 100644 --- a/src/connection.c +++ b/src/connection.c @@ -2529,6 +2529,59 @@ int smp_fetch_fc_err_str(const struct arg *args, struct sample *smp, const char return 1; } + +/* fetch the current number of streams opened for a connection */ +int smp_fetch_fc_nb_streams(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct connection *conn; + unsigned int nb_strm; + + conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) : smp->strm ? sc_conn(smp->strm->scb) : NULL; + + if (!conn) + return 0; + + if (!conn->mux || !conn->mux->ctl) { + if (!conn->mux) + smp->flags |= SMP_F_MAY_CHANGE; + return 0; + } + + nb_strm = conn->mux->ctl(conn, MUX_CTL_GET_NBSTRM, NULL); + + smp->flags = SMP_F_VOL_TEST; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = nb_strm; + + return 1; +} + +/* fetch the maximum number of streams supported by a connection */ +int smp_fetch_fc_streams_limit(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + struct connection *conn; + unsigned int strm_limit; + + conn = (kw[0] != 'b') ? objt_conn(smp->sess->origin) : smp->strm ? sc_conn(smp->strm->scb) : NULL; + + if (!conn) + return 0; + + if (!conn->mux || !conn->mux->ctl) { + if (!conn->mux) + smp->flags |= SMP_F_MAY_CHANGE; + return 0; + } + + strm_limit = conn->mux->ctl(conn, MUX_CTL_GET_MAXSTRM, NULL); + + smp->flags = 0; + smp->data.type = SMP_T_SINT; + smp->data.u.sint = strm_limit; + + return 1; +} + /* Note: must not be declared as its list will be overwritten. * Note: fetches that may return multiple types should be declared using the * appropriate pseudo-type. If not available it must be declared as the lowest @@ -2539,14 +2592,18 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { { "bc_err_str", smp_fetch_fc_err_str, 0, NULL, SMP_T_STR, SMP_USE_L4SRV }, { "bc_glitches", smp_fetch_fc_glitches, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV }, { "bc_http_major", smp_fetch_fc_http_major, 0, NULL, SMP_T_SINT, SMP_USE_L4SRV }, + { "bc_nb_streams", smp_fetch_fc_nb_streams, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV }, + { "bc_setting_streams_limit", smp_fetch_fc_streams_limit, 0, NULL, SMP_T_SINT, SMP_USE_L5SRV }, { "fc_err", smp_fetch_fc_err, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, { "fc_err_str", smp_fetch_fc_err_str, 0, NULL, SMP_T_STR, SMP_USE_L4CLI }, { "fc_glitches", smp_fetch_fc_glitches, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, { "fc_http_major", smp_fetch_fc_http_major, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, { "fc_rcvd_proxy", smp_fetch_fc_rcvd_proxy, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, + { "fc_nb_streams", smp_fetch_fc_nb_streams, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, { "fc_pp_authority", smp_fetch_fc_pp_authority, 0, NULL, SMP_T_STR, SMP_USE_L4CLI }, { "fc_pp_unique_id", smp_fetch_fc_pp_unique_id, 0, NULL, SMP_T_STR, SMP_USE_L4CLI }, - { "fc_pp_tlv", smp_fetch_fc_pp_tlv, ARG1(1, STR), smp_check_tlv_type, SMP_T_STR, SMP_USE_L4CLI }, + { "fc_pp_tlv", smp_fetch_fc_pp_tlv, ARG1(1, STR), smp_check_tlv_type, SMP_T_STR, SMP_USE_L5CLI }, + { "fc_settings_streams_limit", smp_fetch_fc_streams_limit, 0, NULL, SMP_T_SINT, SMP_USE_L5CLI }, { /* END */ }, }};