From c274a55c0eb63bd01ccc9bcbe9fb1bbf4632076c Mon Sep 17 00:00:00 2001 From: Aaron Cook Date: Tue, 30 Apr 2024 16:20:38 -0500 Subject: [PATCH] #17 Add feature to prepend timestamp to output logfile lines --- README.md | 7 ++++++- src/bytenuts.c | 25 ++++++++++++++++++++++++- src/bytenuts.h | 6 +++++- src/cheerios.c | 17 +++++++++++++++++ 4 files changed, 52 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index d516ae4..a0c3a82 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,9 @@ Configs get loaded from ${HOME}/.bytenuts/config (if file exists) --inter_cmd_to= Set the intercommand timeout in milliseconds (default is 10ms). + +--time_fmt= + Time format as used by strftime to prepend to every log line. ``` ## Navigation @@ -85,7 +88,7 @@ If the output window reaches the current line of output, then the output will co ## Configuration File -There are only three supported configs currently. Each config is defined like `=`. Here is a sample config: +Many of the launch options have a corresponding configuration token that can be saved to a config file. Each config is defined like `=`. Here is a sample config: ``` colors=1 @@ -93,6 +96,7 @@ echo=0 no_crlf=0 escape=a inter_cmd_to=100 +time_fmt=%X %m/%d %Z|> ``` - `colors` - enable parsing of 8-bit ANSI color codes @@ -100,6 +104,7 @@ inter_cmd_to=100 - `no_crlf` - just send a line feed (`\n`) for user input rather than carriage return + line feed (`\r\n`) - `escape` - change what character is used as an escape sequence for commands (e.g. if set to `escape=a`, Bytenuts can be exited with `ctrl+a, q`) - `inter_cmd_to` - Set a timeout in milliseconds that must be met. Useful for pasting in multiple lines and ensuring a short delay in between the commands. +- `time_fmt` - The time format string (see `man 3 strftime`) to be prepended to every line in the log file (will not get printed in the console view) Bytenuts looks for the configs at `~/.config/bytenuts/config`. diff --git a/src/bytenuts.c b/src/bytenuts.c index ff6a585..7d8af20 100644 --- a/src/bytenuts.c +++ b/src/bytenuts.c @@ -29,7 +29,8 @@ "--echo=<0|1>\n Turn input echoing off/on.\n\n" \ "--no_crlf=<0|1>\n Choose to send LF and not CRLF on input.\n\n" \ "--escape=\n Change the default ctrl+b escape character.\n\n" \ -"--inter_cmd_to=\n Set the intercommand timeout in milliseconds (default is 10ms).\n" \ +"--inter_cmd_to=\n Set the intercommand timeout in milliseconds (default is 10ms).\n\n" \ +"--time_fmt=\n Time format as used by strftime to prepend to every log line.\n" \ ) static int parse_args(int argc, char **argv); @@ -191,6 +192,8 @@ bytenuts_print_stats() cheerios_insert(st_line, strlen(st_line)); sprintf(st_line, "inter_cmd_to: %d\r\n", bytenuts.config.inter_cmd_to); cheerios_insert(st_line, strlen(st_line)); + sprintf(st_line, "time_fmt: %s\r\n", bytenuts.config.time_fmt); + cheerios_insert(st_line, strlen(st_line)); return 0; } @@ -385,6 +388,10 @@ parse_args(int argc, char **argv) bytenuts.config_overrides[4] = 1; } } + else if (arg_len > 11 && !memcmp(argv[i], "--time_fmt=", 11)) { + bytenuts.config.time_fmt = strdup(&argv[i][11]); + bytenuts.config_overrides[5] = 1; + } else if (!strcmp(argv[i], "--resume") || !strcmp(argv[i], "-r")) { bytenuts.resume = 1; } @@ -438,6 +445,22 @@ load_configs() bytenuts.config.inter_cmd_to = cmd_to; } } + else if (!bytenuts.config_overrides[5] && !memcmp(line, "time_fmt=", 9)) { + size_t time_fmt_len; + bytenuts.config.time_fmt = strdup(&line[9]); + + time_fmt_len = strlen(bytenuts.config.time_fmt); + while ( + time_fmt_len > 0 && + ( + bytenuts.config.time_fmt[time_fmt_len-1] == '\r' || + bytenuts.config.time_fmt[time_fmt_len-1] == '\n' + ) + ) { + bytenuts.config.time_fmt[time_fmt_len-1] = 0; + time_fmt_len--; + } + } } return 0; diff --git a/src/bytenuts.h b/src/bytenuts.h index 6198db5..0bb0ce3 100644 --- a/src/bytenuts.h +++ b/src/bytenuts.h @@ -33,6 +33,9 @@ typedef struct bytenuts_config_struct { char *log_path; /* path to the log file (if it exists) */ char *serial_path; /* path to the target serial device */ uint32_t inter_cmd_to; /* inter command timeout in ms */ + /* time format to be prepended to all log lines in the output file only, + * NULL for no time prepended */ + char *time_fmt; } bytenuts_config_t; #define CONFIG_DEFAULT (bytenuts_config_t){ \ @@ -45,12 +48,13 @@ typedef struct bytenuts_config_struct { .log_path = NULL, \ .serial_path = NULL, \ .inter_cmd_to = 10, \ + .time_fmt = NULL, \ } typedef struct bytenuts_struct { serial_t serial_fd; bytenuts_config_t config; - int config_overrides[5]; + int config_overrides[6]; int resume; bytenuts_state_t state; WINDOW *status_win; diff --git a/src/cheerios.c b/src/cheerios.c index 9c25d7c..40f1eff 100644 --- a/src/cheerios.c +++ b/src/cheerios.c @@ -667,5 +667,22 @@ newline(line_buffer_t *lines) lines->line_lens = realloc(lines->line_lens, sizeof(int) * lines->n_lines); lines->line_lens[lines->n_lines - 1] = 0; lines->pos = 0; + + if (cheerios.config->time_fmt && (cheerios.log || cheerios.backup)) { + char tstr[128]; + time_t now; + struct tm *tinfo; + size_t tstr_len; + + time(&now); + tinfo = localtime(&now); + tstr_len = strftime(tstr, 128, cheerios.config->time_fmt, tinfo); + + if (cheerios.log) + fwrite(tstr, 1, tstr_len, cheerios.log); + if (cheerios.backup) + fwrite(tstr, 1, tstr_len, cheerios.backup); + } + return 0; }