]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: cli/proxy: add a new "show servers conn" command
authorWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 05:00:59 +0000 (07:00 +0200)
committerWilly Tarreau <w@1wt.eu>
Wed, 1 Jul 2020 08:32:54 +0000 (10:32 +0200)
This command reuses the existing "show servers state" to also dump the
state of active and idle connections. The main use is to serve as a
debugging tool to troubleshot connection reuse issues.

doc/management.txt
src/proxy.c

index 0877992b6f4809e017520d3305568395cdf1e675..0585d38d8d31b85c1ce261d006d159921f24325f 100644 (file)
@@ -2290,6 +2290,21 @@ show profiling
   Dumps the current profiling settings, one per line, as well as the command
   needed to change them.
 
+show servers conn [<backend>]
+  Dump the current and idle connections state of the servers belonging to the
+  designated backend (or all backends if none specified). A backend name or
+  identifier may be used.
+
+  The output consists in a header line showing the fields titles, then one
+  server per line with for each, the backend name and ID, server name and ID,
+  the address, port and a series or values. The number of fields varies
+  depending on thread count.
+
+  Given the threaded nature of idle connections, it's important to understand
+  that some values may change once read, and that as such, consistency within a
+  line isn't granted. This output is mostly provided as a debugging tool and is
+  not relevant to be routinely monitored nor graphed.
+
 show servers state [<backend>]
   Dump the state of the servers found in the running configuration. A backend
   name or identifier may be provided to limit the output to this backend only.
index ebbfe4941dd90f3596606f57ddf807c6249a2ab5..93c46651cfce732f71d66d363984a830107b2678 100644 (file)
@@ -1723,14 +1723,17 @@ struct proxy *cli_find_backend(struct appctx *appctx, const char *arg)
 }
 
 
-/* parse a "show servers" CLI line, returns 0 if it wants to start the dump or
- * 1 if it stops immediately. If an argument is specified, it will set the proxy
- * pointer into cli.p0 and its ID into cli.i0.
+/* parse a "show servers [state|conn]" CLI line, returns 0 if it wants to start
+ * the dump or 1 if it stops immediately. If an argument is specified, it will
+ * set the proxy pointer into cli.p0 and its ID into cli.i0. It sets cli.o0 to
+ * 0 for "state", or 1 for "conn".
  */
 static int cli_parse_show_servers(char **args, char *payload, struct appctx *appctx, void *private)
 {
        struct proxy *px;
 
+       appctx->ctx.cli.o0 = *args[2] == 'c'; // "conn" vs "state"
+
        /* check if a backend name has been provided */
        if (*args[3]) {
                /* read server state from local file */
@@ -1794,19 +1797,38 @@ static int dump_servers_state(struct stream_interface *si)
                if (srv->srvrq && srv->srvrq->name)
                        srvrecord = srv->srvrq->name;
 
-               chunk_printf(&trash,
-                               "%d %s "
-                               "%d %s %s "
-                               "%d %d %d %d %ld "
-                               "%d %d %d %d %d "
-                               "%d %d %s %u %s"
-                               "\n",
-                               px->uuid, px->id,
-                               srv->puid, srv->id, srv_addr,
-                               srv->cur_state, srv->cur_admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
-                               srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
-                               bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port,
-                               srvrecord ? srvrecord : "-");
+               if (appctx->ctx.cli.o0 == 0) {
+                       /* show servers state */
+                       chunk_printf(&trash,
+                                    "%d %s "
+                                    "%d %s %s "
+                                    "%d %d %d %d %ld "
+                                    "%d %d %d %d %d "
+                                    "%d %d %s %u %s"
+                                    "\n",
+                                    px->uuid, px->id,
+                                    srv->puid, srv->id, srv_addr,
+                                    srv->cur_state, srv->cur_admin, srv->uweight, srv->iweight, (long int)srv_time_since_last_change,
+                                    srv->check.status, srv->check.result, srv->check.health, srv->check.state, srv->agent.state,
+                                    bk_f_forced_id, srv_f_forced_id, srv->hostname ? srv->hostname : "-", srv->svc_port,
+                                    srvrecord ? srvrecord : "-");
+               } else {
+                       /* show servers conn */
+                       int thr;
+
+                       chunk_printf(&trash,
+                                    "%s/%s %d/%d %s %u - %u %u %u %u %u %u %d %u",
+                                    px->id, srv->id, px->uuid, srv->puid, srv_addr,srv->svc_port,
+                                    srv->pool_purge_delay,
+                                    srv->curr_used_conns, srv->max_used_conns, srv->est_need_conns,
+                                    srv->curr_idle_nb, srv->curr_safe_nb, (int)srv->max_idle_conns, srv->curr_idle_conns);
+
+                       for (thr = 0; thr < global.nbthread; thr++)
+                               chunk_appendf(&trash, " %u", srv->curr_idle_thr[thr]);
+
+                       chunk_appendf(&trash, "\n");
+               }
+
                if (ci_putchk(si_ic(si), &trash) == -1) {
                        si_rx_room_blk(si);
                        return 0;
@@ -1833,7 +1855,13 @@ static int cli_io_handler_servers_state(struct appctx *appctx)
        }
 
        if (appctx->st2 == STAT_ST_HEAD) {
-               chunk_printf(&trash, "%d\n# %s\n", SRV_STATE_FILE_VERSION, SRV_STATE_FILE_FIELD_NAMES);
+               if (appctx->ctx.cli.o0 == 0)
+                       chunk_printf(&trash, "%d\n# %s\n", SRV_STATE_FILE_VERSION, SRV_STATE_FILE_FIELD_NAMES);
+               else
+                       chunk_printf(&trash,
+                                    "# bkname/svname bkid/svid addr port - purge_delay used_cur used_max need_est unsafe_nb safe_nb idle_lim idle_cur idle_per_thr[%d]\n",
+                                    global.nbthread);
+
                if (ci_putchk(si_ic(si), &trash) == -1) {
                        si_rx_room_blk(si);
                        return 0;
@@ -2343,6 +2371,7 @@ static struct cli_kw_list cli_kws = {{ },{
        { { "disable", "frontend",  NULL }, "disable frontend : temporarily disable specific frontend", cli_parse_disable_frontend, NULL, NULL },
        { { "enable", "frontend",  NULL }, "enable frontend : re-enable specific frontend", cli_parse_enable_frontend, NULL, NULL },
        { { "set", "maxconn", "frontend",  NULL }, "set maxconn frontend : change a frontend's maxconn setting", cli_parse_set_maxconn_frontend, NULL },
+       { { "show","servers", "conn",  NULL }, "show servers conn [id]: dump server connections status (for backend <id>)", cli_parse_show_servers, cli_io_handler_servers_state },
        { { "show","servers", "state",  NULL }, "show servers state [id]: dump volatile server information (for backend <id>)", cli_parse_show_servers, cli_io_handler_servers_state },
        { { "show", "backend", NULL }, "show backend   : list backends in the current running config", NULL, cli_io_handler_show_backend },
        { { "shutdown", "frontend",  NULL }, "shutdown frontend : stop a specific frontend", cli_parse_shutdown_frontend, NULL, NULL },