From: Willy Tarreau Date: Thu, 4 May 2023 12:22:36 +0000 (+0200) Subject: MINOR: cli: add an option to display the uptime in the CLI's prompt X-Git-Tag: v2.8-dev12~54 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=225555711fb67298777cdf2203d23b36803f1ef4;p=thirdparty%2Fhaproxy.git MINOR: cli: add an option to display the uptime in the CLI's prompt Entering "prompt timed" toggles reporting of the process' uptime in the prompt, which will report days, hours, minutes and seconds since it was started. As discussed with Tim in issue #2145, this can be convenient to roughly estimate the time between two outputs, as well as detecting that a process failed to be reloaded for example. --- diff --git a/doc/management.txt b/doc/management.txt index 4a5e033614..f226d997b7 100644 --- a/doc/management.txt +++ b/doc/management.txt @@ -1497,6 +1497,20 @@ For this reason, when debugging by hand, it's quite common to start with the ... > +Optionally the process' uptime may be displayed in the prompt. In order to +enable this, the "prompt timed" command will enable the prompt and toggle the +displaying of the time. The uptime is displayed in format "d:hh:mm:ss" where +"d" is the number of days, and "hh", "mm", "ss" are respectively the number +of hours, minutes and seconds on two digits each: + + # socat /var/run/haproxy readline + prompt timed + + [23:03:34:39]> show version + 2.8-dev9-e5e622-18 + + [23:03:34:41]> quit + Since multiple commands may be issued at once, haproxy uses the empty line as a delimiter to mark an end of output for each command, and takes care of ensuring that no command can emit an empty line on output. A script can thus easily diff --git a/include/haproxy/cli-t.h b/include/haproxy/cli-t.h index 104b0b157e..0570b69db6 100644 --- a/include/haproxy/cli-t.h +++ b/include/haproxy/cli-t.h @@ -42,6 +42,7 @@ #define APPCTX_CLI_ST1_PROMPT (1 << 0) #define APPCTX_CLI_ST1_PAYLOAD (1 << 1) #define APPCTX_CLI_ST1_NOLF (1 << 2) +#define APPCTX_CLI_ST1_TIMED (1 << 3) #define CLI_PREFIX_KW_NB 5 #define CLI_MAX_MATCHES 5 diff --git a/src/cli.c b/src/cli.c index d66e483508..f81cfa6529 100644 --- a/src/cli.c +++ b/src/cli.c @@ -319,7 +319,7 @@ static char *cli_gen_usage_msg(struct appctx *appctx, char * const *args) /* always show the prompt/help/quit commands */ chunk_strcat(tmp, " help [] : list matching or all commands\n" - " prompt : toggle interactive mode with prompt\n" + " prompt [timed] : toggle interactive mode with prompt\n" " quit : disconnect\n"); chunk_init(&out, NULL, 0); @@ -1115,6 +1115,7 @@ static void cli_io_handler(struct appctx *appctx) /* The post-command prompt is either LF alone or LF + '> ' in interactive mode */ if (appctx->st0 == CLI_ST_PROMPT) { + char prompt_buf[20]; const char *prompt = ""; if (appctx->st1 & APPCTX_CLI_ST1_PROMPT) { @@ -1124,6 +1125,13 @@ static void cli_io_handler(struct appctx *appctx) */ if (appctx->chunk->data && appctx->st1 & APPCTX_CLI_ST1_PAYLOAD) prompt = "+ "; + else if (appctx->st1 & APPCTX_CLI_ST1_TIMED) { + uint up = ns_to_sec(now_ns - start_time_ns); + snprintf(prompt_buf, sizeof(prompt_buf), + "\n[%u:%02u:%02u:%02u]> ", + (up / 86400), (up / 3600) % 24, (up / 60) % 60, up % 60); + prompt = prompt_buf; + } else prompt = "\n> "; } @@ -2187,7 +2195,12 @@ static int cli_parse_simple(char **args, char *payload, struct appctx *appctx, v cli_gen_usage_msg(appctx, args); else if (*args[0] == 'p') /* prompt */ - appctx->st1 ^= APPCTX_CLI_ST1_PROMPT; + if (strcmp(args[1], "timed") == 0) { + appctx->st1 |= APPCTX_CLI_ST1_PROMPT; + appctx->st1 ^= APPCTX_CLI_ST1_TIMED; + } + else + appctx->st1 ^= APPCTX_CLI_ST1_PROMPT; else if (*args[0] == 'q') { /* quit */ se_fl_set(appctx->sedesc, SE_FL_EOI);