MINOR: cli/proxy: add a new "show servers conn" command
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.
diff --git a/doc/management.txt b/doc/management.txt
index 0877992..0585d38 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -2290,6 +2290,21 @@
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.
diff --git a/src/proxy.c b/src/proxy.c
index ebbfe49..93c4665 100644
--- a/src/proxy.c
+++ b/src/proxy.c
@@ -1723,14 +1723,17 @@
}
-/* 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 @@
if (srv->srvrq && srv->srvrq->name)
srvrecord = srv->srvrq->name;
+ 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_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 : "-");
+ chunk_appendf(&trash, "\n");
+ }
+
if (ci_putchk(si_ic(si), &trash) == -1) {
si_rx_room_blk(si);
return 0;
@@ -1833,7 +1855,13 @@
}
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 @@
{ { "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 },