Re: relayctl: rework output and add -v flag
Kirill A. Korinsky <[email protected]>
| Newsgroups | gmane.os.openbsd.tech |
|---|---|
| Message-ID | <[email protected]> |
On Thu, 27 Aug 2026 15:05:30 +0200, Rafael Sadowski <[email protected]> wrote: > > Any feeback or better ideas? > I don't use relactl that much to actually have an opinion on this, but your code reads OK kirill@ So, if it makes your life a bit easy, I see no objection. > On Sat Aug 01, 2026 at 11:54:43AM +0200, Rafael Sadowski wrote: > > I find the current output: 1. Pointless by default, the keyword "imsg" > > appears in the monitor mode. 2. Unreadable with long names. 3. Inconsistent. > > The diff attempts to improve this. > > > > "relayctl show sessions" is a different story. Even using "watch -s 0.2 > > 'doas relayctl show sessions'" is of no use, as sessions are really > > short-lived. In my view, this would need to be a monitor. But that would > > involve more work. > > > > See the commit message below for impl details. > > > > > > Current: > > > > $ doas relayctl monitor > > sync: imsg type 38 len 0 peerid 4294967295 pid 1 > > timestamp: 1785577221, Sat Aug 1 11:40:21 2026 > > host_status: imsg type 37 len 32 peerid 4294967295 pid 1 > > timestamp: 1785577221, Sat Aug 1 11:40:21 2026 > > id: 3 > > state: down > > host_status: imsg type 37 len 32 peerid 4294967295 pid 1 > > timestamp: 1785577221, Sat Aug 1 11:40:21 2026 > > id: 1 > > state: up > > > > (Why someone should be interested in imsg?). > > > > $ doas relayctl show summary > > Id Type Name Avlblty Status > > 1 redirect db-redirect down > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% down > > 9 host 10.0.23.10 0.00% down > > 2 redirect cache-redirect down > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% down > > 3 redirect api-redirect down > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% down > > 1 relay https-gateway-way-to-long-name-for-testing active > > 1 table ap:6443 active (1 hosts) > > 1 host 10.0.23.6 100.00% up > > 2 relay https-api-gateway active > > > > $ doas relayctl show hosts > > Id Type Name Avlblty Status > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% down > > total: 0/3 checks, error: tcp connect timeout > > 9 host 10.0.23.10 0.00% down > > total: 0/3 checks, error: tcp connect timeout > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% down > > total: 0/3 checks, error: tcp connect timeout > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% down > > total: 0/3 checks, error: tcp connect timeout > > 1 table ap:6443 active (1 hosts) > > 1 host 10.0.23.6 100.00% up > > total: 3/3 checks > > 2 table api:8443 empty > > 2 host 10.0.23.8 0.00% down > > total: 0/3 checks, error: tcp connect timeout > > > > $ doas relayctl show relays > > Id Type Name Avlblty Status > > 1 relay https-gateway-way-to-long-name-for-testing active > > > > $ doas relayctl show hosts > > Id Type Name Avlblty Status > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 9 host 10.0.23.10 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 1 table ap:6443 active (1 hosts) > > 1 host 10.0.23.6 100.00% up > > total: 10/10 checksdoas relayctl show hosts > > Id Type Name Avlblty Status > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 9 host 10.0.23.10 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% down > > total: 0/10 checks, error: tcp connect timeout > > 1 table ap:6443 active (1 hosts) > > 1 host 10.0.23.6 100.00% up > > total: 10/10 checks > > > > With diff: > > > > $ doas relayctl show summary > > Id Type Name Avlblty Checks Status > > 1 rdr db-redirect down > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% 0/2 down > > 9 host 10.0.23.10 0.00% 0/2 down > > 2 rdr cache-redirect down > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% 0/2 down > > 3 rdr api-redirect down > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% 0/2 down > > 1 relay https-gateway-way-to-lon active > > 1 table ap:6443 active > > 1 host 10.0.23.6 100.00% 2/2 up > > > > $ doas relayctl -v show summary > > Id Type Name Avlblty Checks Status > > 1 rdr db-redirect down > > 6 table db:5432 empty > > 8 host 10.0.23.9 0.00% 0/3 down (tcp connect timeout) > > 9 host 10.0.23.10 0.00% 0/3 down (tcp connect timeout) > > 2 rdr cache-redirect down > > 7 table cache2:11211 empty > > 10 host 10.0.23.11 0.00% 0/3 down (tcp connect timeout) > > 3 rdr api-redirect down > > 8 table api:9000 empty > > 11 host 10.0.23.8 0.00% 0/3 down (tcp connect timeout) > > 1 relay https-gateway-way-to-lon active > > 1 table ap:6443 active (1 hosts) > > 1 host 10.0.23.6 100.00% 3/3 up > > > > $ doas relayctl show hosts > > Id Type Name Avlblty Checks Status > > 8 host 10.0.23.9 0.00% 0/5 down > > 9 host 10.0.23.10 0.00% 0/5 down > > 10 host 10.0.23.11 0.00% 0/5 down > > 11 host 10.0.23.8 0.00% 0/5 down > > 1 host 10.0.23.6 100.00% 5/5 up > > 2 host 10.0.23.8 0.00% 0/5 down > > 3 host 10.0.23.6 0.00% 0/5 down > > 4 host 10.0.23.7 0.00% 0/5 down > > 5 host 10.0.23.9 0.00% 0/5 down > > 6 host 10.0.23.10 0.00% 0/5 down > > 7 host 10.0.23.11 0.00% 0/5 down > > > > $ doas relayctl -v show hosts > > Id Type Name Avlblty Checks Status > > 8 host 10.0.23.9 0.00% 0/6 down (tcp connect timeout) > > 9 host 10.0.23.10 0.00% 0/6 down (tcp connect timeout) > > 10 host 10.0.23.11 0.00% 0/6 down (tcp connect timeout) > > 11 host 10.0.23.8 0.00% 0/6 down (tcp connect timeout) > > 1 host 10.0.23.6 100.00% 6/6 up > > 2 host 10.0.23.8 0.00% 0/6 down (tcp connect timeout) > > 3 host 10.0.23.6 0.00% 0/6 down (tls connect failed) > > 4 host 10.0.23.7 0.00% 0/6 down (tcp connect timeout) > > 5 host 10.0.23.9 0.00% 0/6 down (tcp connect timeout) > > 6 host 10.0.23.10 0.00% 0/6 down (tcp connect timeout) > > 7 host 10.0.23.11 0.00% 0/6 down (tcp connect timeout) > > > > $ doas relayctl show relays > > Id Type Name Avlblty Checks Status > > 1 relay https-gateway-way-to-lon active > > 2 relay https-api-gateway active > > 3 relay wiki-frontend active > > 4 relay ssh-tunnel active > > 5 relay cache-service active > > > > $ doas relayctl monitor > > host_status: id: 3 status: down > > host_status: id: 1 status: up > > host_status: id: 5 status: down > > host_status: id: 10 status: down > > host_status: id: 9 status: down > > > > $ doas relayctl -v monitor > > sync: imsg type 38 len 0 peerid 4294967295 pid 1 > > sync: timestamp: 1785577623, Sat Aug 1 11:47:03 2026 > > host_status: imsg type 37 len 32 peerid 4294967295 pid 1 > > host_status: timestamp: 1785577623, Sat Aug 1 11:47:03 2026 > > host_status: id: 3 status: down > > host_status: imsg type 37 len 32 peerid 4294967295 pid 1 > > host_status: timestamp: 1785577623, Sat Aug 1 11:47:03 2026 > > host_status: id: 1 status: up > > > > > > commit 900841a571028d4dd0dce801a3abcfdbfa95141c > > Author: Rafael Sadowski <[email protected]> > > Date: Sat Aug 1 09:52:26 2026 +0200 > > > > relayctl: rework show output and add -v flag > > > > - Added -v flag for more detailed output. > > - Replaced tab separators with space-padded, truncated columns (%.Ns) for > > stable alignment. > > - Added a new "Checks" column for host checks (N/N), replacing the total: N/N > > checks sub-line. > > - Shortened redirect to rdr in the Type column to stay under 80 columns. > > - Without -v: compact status (down); with -v: error inlined (down (tcp connect > > timeout)). > > - Table status shows host count (N hosts) only with -v. > > - retries sub-line only appears with show hosts -v. > > - show hosts no longer lists tables; use show summary for that. > > > > diff --git a/relayctl.8 b/relayctl.8 > > index 96e68a5..fcdf043 100644 > > --- a/relayctl.8 > > +++ b/relayctl.8 > > @@ -23,6 +23,7 @@ > > .Nd control the relay daemon > > .Sh SYNOPSIS > > .Nm > > +.Op Fl v > > .Op Fl s Ar socket > > .Ar command > > .Op Ar argument ... > > @@ -42,6 +43,8 @@ instead of the default > > .Pa /var/run/relayd.sock > > to communicate with > > .Xr relayd 8 . > > +.It Fl v > > +Verbose output. > > .El > > .Pp > > The following commands are available: > > @@ -78,7 +81,7 @@ the backup table as well. > > .It Cm reload > > Reload the configuration file. > > .It Cm show hosts > > -Show detailed status of hosts and tables. > > +Show detailed status of hosts. > > It will also print the last error for failed host checks; > > see the > > .Sx DIAGNOSTICS > > diff --git a/relayctl.c b/relayctl.c > > index b76d9fc..a47bf7a 100644 > > --- a/relayctl.c > > +++ b/relayctl.c > > @@ -50,6 +50,7 @@ char *print_host_status(int, int); > > char *print_table_status(int, int); > > char *print_relay_status(int); > > void print_statistics(struct ctl_stats [PROC_MAX_INSTANCES+1]); > > +void print_imsg(struct imsg *, const char *); > > > > struct imsgname { > > int type; > > @@ -82,13 +83,14 @@ struct imsgname imsgunknown = { > > > > struct imsgbuf *ibuf; > > int error = 0; > > +int verbose = 0; > > > > __dead void > > usage(void) > > { > > extern char *__progname; > > > > - fprintf(stderr, "usage: %s [-s socket] command [argument ...]\n", > > + fprintf(stderr, "usage: %s [-v] [-s socket] command [argument ...]\n", > > __progname); > > exit(1); > > } > > @@ -101,16 +103,19 @@ main(int argc, char *argv[]) > > struct imsg imsg; > > int ctl_sock; > > int done = 0; > > - int n, verbose = 0; > > + int n, relayd_log_level = 0; > > int ch; > > const char *sockname; > > > > sockname = RELAYD_SOCKET; > > - while ((ch = getopt(argc, argv, "s:")) != -1) { > > + while ((ch = getopt(argc, argv, "vs:")) != -1) { > > switch (ch) { > > case 's': > > sockname = optarg; > > break; > > + case 'v': > > + verbose++; > > + break; > > default: > > usage(); > > /* NOTREACHED */ > > @@ -163,8 +168,8 @@ main(int argc, char *argv[]) > > case SHOW_RELAYS: > > case SHOW_ROUTERS: > > imsg_compose(ibuf, IMSG_CTL_SHOW_SUM, 0, 0, -1, NULL, 0); > > - printf("%-4s\t%-8s\t%-24s\t%-7s\tStatus\n", > > - "Id", "Type", "Name", "Avlblty"); > > + printf("%-4s %-6s %-24.24s %-7.7s %-8.8s %s\n", > > + "Id", "Type", "Name", "Avlblty", "Checks", "Status"); > > break; > > case SHOW_SESSIONS: > > imsg_compose(ibuf, IMSG_CTL_SESSION, 0, 0, -1, NULL, 0); > > @@ -212,11 +217,11 @@ main(int argc, char *argv[]) > > imsg_compose(ibuf, IMSG_CTL_NOTIFY, 0, 0, -1, NULL, 0); > > break; > > case LOG_VERBOSE: > > - verbose = 2; > > + relayd_log_level = 2; > > /* FALLTHROUGH */ > > case LOG_BRIEF: > > imsg_compose(ibuf, IMSG_CTL_VERBOSE, 0, 0, -1, > > - &verbose, sizeof(verbose)); > > + &relayd_log_level, sizeof(relayd_log_level)); > > printf("logging request sent.\n"); > > done = 1; > > break; > > @@ -294,8 +299,7 @@ monitor_host_status(struct imsg *imsg) > > > > if (imsg_get_data(imsg, &cs, sizeof(cs)) == -1) > > errx(1, "imsg_get_data ctl status error"); > > - printf("\tid: %u\n", cs.id); > > - printf("\tstate: "); > > + printf("host_status: id: %u status: ", cs.id); > > switch (cs.up) { > > case HOST_UP: > > printf("up\n"); > > @@ -316,25 +320,19 @@ monitor_id(struct imsg *imsg) > > > > if (imsg_get_data(imsg, &id, sizeof(id)) == -1) > > errx(1, "imsg_get_data ctl id error"); > > - printf("\tid: %u\n", id.id); > > + printf("monitor_id: id: %u\n", id.id); > > if (strlen(id.name)) > > - printf("\tname: %s\n", id.name); > > + printf("name: %s\n", id.name); > > } > > > > int > > monitor(struct imsg *imsg) > > { > > - time_t now; > > int done = 0; > > struct imsgname *imn; > > > > - now = time(NULL); > > - > > imn = monitor_lookup(imsg_get_type(imsg)); > > - printf("%s: imsg type %u len %zu peerid %u pid %d\n", imn->name, > > - imsg_get_type(imsg), imsg_get_len(imsg), imsg_get_id(imsg), > > - imsg_get_pid(imsg)); > > - printf("\ttimestamp: %lld, %s", (long long)now, ctime(&now)); > > + print_imsg(imsg, imn->name); > > if (imn->type == -1) > > done = 1; > > if (imn->func != NULL) > > @@ -352,8 +350,10 @@ show_summary_msg(struct imsg *imsg, int type) > > struct relay rlay; > > struct router rt; > > struct netroute nr; > > - struct ctl_stats stats[PROC_MAX_INSTANCES]; > > + struct ctl_stats stats[PROC_MAX_INSTANCES + 1]; > > char name[HOST_NAME_MAX + 1]; > > + char checks[16]; > > + char status[128]; > > > > switch (imsg_get_type(imsg)) { > > case IMSG_CTL_RDR: > > @@ -362,18 +362,18 @@ show_summary_msg(struct imsg *imsg, int type) > > if (imsg_get_data(imsg, &rdr, sizeof(rdr)) == -1) > > errx(1, "imsg_get_data rdr error"); > > rdr.conf.name[sizeof(rdr.conf.name) - 1] = '\0'; > > - printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n", > > - rdr.conf.id, "redirect", rdr.conf.name, "", > > + printf("%-4u %-6s %-24.24s %-7.7s %-8.8s %s\n", > > + rdr.conf.id, "rdr", rdr.conf.name, "", "", > > print_rdr_status(rdr.conf.flags)); > > break; > > case IMSG_CTL_TABLE: > > - if (!(type == SHOW_SUM || type == SHOW_HOSTS)) > > + if (type != SHOW_SUM) > > break; > > if (imsg_get_data(imsg, &table, sizeof(table)) == -1) > > errx(1, "imsg_get_data table error"); > > table.conf.name[sizeof(table.conf.name) - 1] = '\0'; > > - printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n", > > - table.conf.id, "table", table.conf.name, "", > > + printf("%-4u %-6s %-24.24s %-7.7s %-8.8s %s\n", > > + table.conf.id, "table", table.conf.name, "", "", > > print_table_status(table.up, table.conf.flags)); > > break; > > case IMSG_CTL_HOST: > > @@ -387,19 +387,24 @@ show_summary_msg(struct imsg *imsg, int type) > > host.conf.name, host.conf.parentid); > > else > > strlcpy(name, host.conf.name, sizeof(name)); > > - printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n", > > + if (host.check_cnt) > > + snprintf(checks, sizeof(checks), "%lu/%lu", > > + host.up_cnt, host.check_cnt); > > + else > > + checks[0] = '\0'; > > + if (host.he && host.up == HOST_DOWN && verbose) > > + snprintf(status, sizeof(status), "%s (%s)", > > + print_host_status(host.up, host.flags), > > + host_error(host.he)); > > + else > > + strlcpy(status, print_host_status(host.up, host.flags), > > + sizeof(status)); > > + printf("%-4u %-6s %-24.24s %-7.7s %-8.8s %s\n", > > host.conf.id, "host", name, > > print_availability(host.check_cnt, host.up_cnt), > > - print_host_status(host.up, host.flags)); > > - if (type == SHOW_HOSTS && host.check_cnt) { > > - printf("\t%8s\ttotal: %lu/%lu checks", > > - "", host.up_cnt, host.check_cnt); > > - if (host.retry_cnt) > > - printf(", %d retries", host.retry_cnt); > > - if (host.he && host.up == HOST_DOWN) > > - printf(", error: %s", host_error(host.he)); > > - printf("\n"); > > - } > > + checks, status); > > + if (type == SHOW_HOSTS && verbose && host.retry_cnt) > > + printf("\t%8s\t%d retries\n", "", host.retry_cnt); > > break; > > case IMSG_CTL_RELAY: > > if (!(type == SHOW_SUM || type == SHOW_RELAYS)) > > @@ -407,8 +412,8 @@ show_summary_msg(struct imsg *imsg, int type) > > if (imsg_get_data(imsg, &rlay, sizeof(rlay)) == -1) > > errx(1, "imsg_get_data relay error"); > > rlay.rl_conf.name[sizeof(rlay.rl_conf.name) - 1] = '\0'; > > - printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n", > > - rlay.rl_conf.id, "relay", rlay.rl_conf.name, "", > > + printf("%-4u %-6s %-24.24s %-7.7s %-8.8s %s\n", > > + rlay.rl_conf.id, "relay", rlay.rl_conf.name, "", "", > > print_relay_status(rlay.rl_conf.flags)); > > break; > > case IMSG_CTL_RDR_STATS: > > @@ -433,8 +438,8 @@ show_summary_msg(struct imsg *imsg, int type) > > errx(1, "imsg_get_data router error"); > > rt.rt_conf.name[sizeof(rt.rt_conf.name) - 1] = '\0'; > > rt.rt_conf.label[sizeof(rt.rt_conf.label) - 1] = '\0'; > > - printf("%-4u\t%-8s\t%-24s\t%-7s\t%s\n", > > - rt.rt_conf.id, "router", rt.rt_conf.name, "", > > + printf("%-4u %-6s %-24.24s %-7.7s %-8.8s %s\n", > > + rt.rt_conf.id, "router", rt.rt_conf.name, "", "", > > print_relay_status(rt.rt_conf.flags)); > > if (type != SHOW_ROUTERS) > > break; > > @@ -483,7 +488,7 @@ show_session_msg(struct imsg *imsg) > > getmonotime(&tv_now); > > print_time(&tv_now, &con.se_tv_start, a, sizeof(a)); > > print_time(&tv_now, &con.se_tv_last, b, sizeof(b)); > > - printf("\tage %s, idle %s, relay %u, pid %u", > > + printf("age %s, idle %s, relay %u, pid %u", > > a, b, con.se_relayid, con.se_pid); > > /* XXX grab tagname instead of tag id */ > > if (con.se_tag) > > @@ -540,8 +545,10 @@ print_table_status(int up, int fl) > > snprintf(buf, sizeof(buf) - 1, "disabled"); > > } else if (!up) { > > snprintf(buf, sizeof(buf) - 1, "empty"); > > - } else > > + } else if (verbose) > > snprintf(buf, sizeof(buf) - 1, "active (%d hosts)", up); > > + else > > + snprintf(buf, sizeof(buf) - 1, "active"); > > return (buf); > > } > > > > @@ -600,3 +607,19 @@ print_statistics(struct ctl_stats stats[PROC_MAX_INSTANCES+1]) > > "", crs.avg, crs.interval, > > crs.avg_hour, crs.avg_day); > > } > > + > > +void > > +print_imsg(struct imsg *imsg, const char *name) > > +{ > > + time_t now; > > + > > + if (!verbose) > > + return; > > + > > + now = time(NULL); > > + > > + printf("%s: imsg type %u len %zu peerid %u pid %d\n", name, > > + imsg_get_type(imsg), imsg_get_len(imsg), imsg_get_id(imsg), > > + imsg_get_pid(imsg)); > > + printf("%s: timestamp: %lld, %s", name, (long long)now, ctime(&now)); > > +} > > -- wbr, Kirill