]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: Add samples to retrieve info on streams for a connection
authorChristopher Faulet <cfaulet@haproxy.com>
Tue, 30 Apr 2024 15:52:04 +0000 (17:52 +0200)
committerChristopher Faulet <cfaulet@haproxy.com>
Mon, 6 May 2024 20:00:01 +0000 (22:00 +0200)
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.

doc/configuration.txt
src/connection.c

index ed9b67f347d2bd5f681c18bf29975543e6aab54e..bb3515bbc3a18c6c0e2de9eb3b42ce22af48d921 100644 (file)
@@ -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(<unit>)                                     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(<id>)                                    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.
index f9e05c37379ad7598a7f827533235eabfab26690..46526b141f0fdf6bc56e3797acf50caaf8b3f861 100644 (file)
@@ -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 <const> 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 */ },
 }};