MINOR: quic: implement oneline format for "show quic"
Add a new output format "oneline" for "show quic" command. This prints
one connection per line with minimal information. The objective is to
have an equivalent of the netstat/ss tools with just enough information
to quickly find connection which are misbehaving.
A legend is printed on the first line to describe the field columns
starting with a dash character.
This should be backported up to 2.7.
diff --git a/doc/management.txt b/doc/management.txt
index 42cf204..978b048 100644
--- a/doc/management.txt
+++ b/doc/management.txt
@@ -2988,10 +2988,10 @@
Dump information on all active QUIC frontend connections. This command is
restricted and can only be issued on sockets configured for levels "operator"
or "admin". An optional format can be specified as first argument to control
- the verbosity. Currently only supported value is "full" which is the default
- if format is unspecified. By default, connections on closing or draining
- state are not displayed. Use the extra argument "all" to include them in the
- output.
+ the verbosity. Currently supported values are "oneline" which is the default
+ if format is unspecified or "full". By default, connections on closing or
+ draining state are not displayed. Use the extra argument "all" to include
+ them in the output.
show servers conn [<backend>]
Dump the current and idle connections state of the servers belonging to the
diff --git a/src/quic_conn.c b/src/quic_conn.c
index 1d43cd8..c3e0bec 100644
--- a/src/quic_conn.c
+++ b/src/quic_conn.c
@@ -8596,6 +8596,7 @@
}
enum quic_dump_format {
+ QUIC_DUMP_FMT_ONELINE,
QUIC_DUMP_FMT_FULL,
};
@@ -8621,12 +8622,16 @@
ctx->epoch = _HA_ATOMIC_FETCH_ADD(&qc_epoch, 1);
ctx->thr = 0;
ctx->flags = 0;
- ctx->format = QUIC_DUMP_FMT_FULL;
+ ctx->format = QUIC_DUMP_FMT_ONELINE;
- if (strcmp(args[argc], "full") == 0) {
+ if (strcmp(args[argc], "oneline") == 0) {
/* format already used as default value */
++argc;
}
+ else if (strcmp(args[argc], "full") == 0) {
+ ctx->format = QUIC_DUMP_FMT_FULL;
+ ++argc;
+ }
while (*args[argc]) {
if (strcmp(args[argc], "all") == 0)
@@ -8640,6 +8645,54 @@
return 0;
}
+/* Dump for "show quic" with "oneline" format. */
+static void dump_quic_oneline(struct show_quic_ctx *ctx, struct quic_conn *qc)
+{
+ char bufaddr[INET6_ADDRSTRLEN], bufport[6];
+ unsigned char cid_len;
+
+ chunk_appendf(&trash, "%p[%02u]/%-.12s ", qc, ctx->thr,
+ qc->li->bind_conf->frontend->id);
+
+ /* State */
+ if (qc->flags & QUIC_FL_CONN_CLOSING)
+ chunk_appendf(&trash, "CLOSE ");
+ else if (qc->flags & QUIC_FL_CONN_DRAINING)
+ chunk_appendf(&trash, "DRAIN ");
+ else if (qc->state < QUIC_HS_ST_COMPLETE)
+ chunk_appendf(&trash, "HDSHK ");
+ else
+ chunk_appendf(&trash, "ESTAB ");
+
+ /* Bytes in flight / Lost packets */
+ chunk_appendf(&trash, "%9llu %6llu %6llu ",
+ (ullong)qc->path->in_flight,
+ (ullong)qc->path->ifae_pkts,
+ (ullong)qc->path->loss.nb_lost_pkt);
+
+ /* Socket */
+ if (qc->local_addr.ss_family == AF_INET ||
+ qc->local_addr.ss_family == AF_INET6) {
+ addr_to_str(&qc->peer_addr, bufaddr, sizeof(bufaddr));
+ port_to_str(&qc->peer_addr, bufport, sizeof(bufport));
+ chunk_appendf(&trash, "%15s:%s ", bufaddr, bufport);
+
+ addr_to_str(&qc->local_addr, bufaddr, sizeof(bufaddr));
+ port_to_str(&qc->local_addr, bufport, sizeof(bufport));
+ chunk_appendf(&trash, "%15s:%s ", bufaddr, bufport);
+ }
+
+ /* CIDs */
+ for (cid_len = 0; cid_len < qc->scid.len; ++cid_len)
+ chunk_appendf(&trash, "%02x", qc->scid.data[cid_len]);
+
+ chunk_appendf(&trash, " ");
+ for (cid_len = 0; cid_len < qc->dcid.len; ++cid_len)
+ chunk_appendf(&trash, "%02x", qc->dcid.data[cid_len]);
+
+ chunk_appendf(&trash, "\n");
+}
+
/* Dump for "show quic" with "full" format. */
static void dump_quic_full(struct show_quic_ctx *ctx, struct quic_conn *qc)
{
@@ -8779,6 +8832,15 @@
else if (!ctx->bref.ref) {
/* First invocation. */
ctx->bref.ref = ha_thread_ctx[ctx->thr].quic_conns.n;
+
+ /* Print legend for oneline format. */
+ if (ctx->format == QUIC_DUMP_FMT_ONELINE) {
+ chunk_appendf(&trash, "# conn/frontend state "
+ "in_flight infl_p lost_p "
+ "from to "
+ "local & remote CIDs\n");
+ applet_putchk(appctx, &trash);
+ }
}
while (1) {
@@ -8822,6 +8884,9 @@
case QUIC_DUMP_FMT_FULL:
dump_quic_full(ctx, qc);
break;
+ case QUIC_DUMP_FMT_ONELINE:
+ dump_quic_oneline(ctx, qc);
+ break;
}
if (applet_putchk(appctx, &trash) == -1) {