diff --git a/include/villas/log.h b/include/villas/log.h index 5300f9d3d..928150eca 100644 --- a/include/villas/log.h +++ b/include/villas/log.h @@ -92,6 +92,7 @@ struct log { struct timespec epoch; /**< A global clock used to prefix the log messages. */ struct winsize window; /**< Size of the terminal window. */ + int width; /**< The real usable log output width which fits into one line. */ /** Debug level used by the debug() macro. * It defaults to V (defined by the Makefile) and can be @@ -189,41 +190,6 @@ void error(const char *fmt, ...) void serror(const char *fmt, ...) __attribute__ ((format(printf, 1, 2))); -/** @addtogroup table Print fancy tables - * @{ - */ - -struct table_column { - int width; /**< Width of the column. */ - char *title; /**< The title as shown in the table header. */ - char *format; /**< The format which is used to print the table rows. */ - char *unit; /**< An optional unit which will be shown in the table header. */ - - enum { - TABLE_ALIGN_LEFT, - TABLE_ALIGN_RIGHT - } align; - - int _width; /**< The real width of this column. Calculated by table_header() */ -}; - -struct table { - int ncols; - int width; - struct table_column *cols; -}; - -/** Print a table header consisting of \p n columns. */ -void table_header(struct table *t); - -/** Print table rows. */ -void table_row(struct table *t, ...); - -/** Print the table footer. */ -void table_footer(struct table *t); - -/** @} */ - #ifdef __cplusplus } #endif diff --git a/include/villas/table.h b/include/villas/table.h new file mode 100644 index 000000000..f11a0d5d9 --- /dev/null +++ b/include/villas/table.h @@ -0,0 +1,57 @@ +/** Print fancy tables + * + * @file + * @author Steffen Vogel + * @copyright 2017, Institute for Automation of Complex Power Systems, EONERC + * @license GNU General Public License (version 3) + * + * VILLASnode + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + *********************************************************************************/ + +/** @addtogroup table Print fancy tables + * @{ + */ + +struct table_column { + int width; /**< Width of the column. */ + char *title; /**< The title as shown in the table header. */ + char *format; /**< The format which is used to print the table rows. */ + char *unit; /**< An optional unit which will be shown in the table header. */ + + enum { + TABLE_ALIGN_LEFT, + TABLE_ALIGN_RIGHT + } align; + + int _width; /**< The real width of this column. Calculated by table_header() */ +}; + +struct table { + int ncols; + int width; + struct table_column *cols; +}; + +/** Print a table header consisting of \p n columns. */ +void table_header(struct table *t); + +/** Print table rows. */ +void table_row(struct table *t, ...); + +/** Print the table footer. */ +void table_footer(struct table *t); + +/** @} */ diff --git a/lib/Makefile.villas.inc b/lib/Makefile.villas.inc index b3a09c715..8d600e212 100644 --- a/lib/Makefile.villas.inc +++ b/lib/Makefile.villas.inc @@ -33,7 +33,7 @@ LIB_SRCS += $(addprefix lib/kernel/, kernel.c rt.c) \ utils.c super_node.c hist.c timing.c pool.c list.c queue.c \ queue_signalled.c memory.c advio.c plugin.c node_type.c stats.c \ mapping.c io.c shmem.c config_helper.c crypt.c compat.c \ - log_table.c log_helper.c io_format.c task.c buffer.c \ + log_helper.c io_format.c task.c buffer.c table.c \ ) LIB_LDFLAGS = -shared diff --git a/lib/hist.c b/lib/hist.c index 0b65d7efc..7d4484270 100644 --- a/lib/hist.c +++ b/lib/hist.c @@ -30,6 +30,7 @@ #include "utils.h" #include "hist.h" #include "config.h" +#include "table.h" #define VAL(h, i) ((h)->low + (i) * (h)->resolution) #define INDEX(h, v) round((v - (h)->low) / (h)->resolution) diff --git a/lib/log.c b/lib/log.c index 2ca7cfe82..f20c29e49 100644 --- a/lib/log.c +++ b/lib/log.c @@ -118,6 +118,8 @@ static void log_resize(int signal, siginfo_t *sinfo, void *ctx) if (ret) return; + global_log->width = global_log->window.ws_col - 25 - strlenp(global_log->prefix); + debug(LOG_LOG | 15, "New terminal size: %dx%x", global_log->window.ws_row, global_log->window.ws_col); } @@ -133,8 +135,6 @@ int log_init(struct log *l, int level, long facilitites) l->facilities = facilitites; l->file = stderr; l->path = NULL; - l->window.ws_col = LOG_WIDTH; - l->window.ws_row = LOG_HEIGHT; l->epoch = time_now(); l->prefix = getenv("VILLAS_LOG_PREFIX"); @@ -156,6 +156,12 @@ int log_init(struct log *l, int level, long facilitites) /* Try to get initial window size */ ioctl(STDERR_FILENO, TIOCGWINSZ, &global_log->window); } + else { + l->window.ws_col = LOG_WIDTH; + l->window.ws_row = LOG_HEIGHT; + } + + l->width = l->window.ws_col - 25 - strlenp(l->prefix); l->state = STATE_INITIALIZED; diff --git a/lib/stats.c b/lib/stats.c index a2f4ad6ac..84b5af177 100644 --- a/lib/stats.c +++ b/lib/stats.c @@ -30,6 +30,7 @@ #include "utils.h" #include "log.h" #include "node.h" +#include "table.h" static struct stats_desc { const char *name; @@ -129,16 +130,16 @@ void stats_reset(struct stats *s) } static struct table_column stats_cols[] = { - { 10, "Node", "%s", NULL, TABLE_ALIGN_LEFT }, - { 10, "Recv", "%ju", "p", TABLE_ALIGN_RIGHT }, - { 10, "Sent", "%ju", "p", TABLE_ALIGN_RIGHT }, - { 10, "OWD last", "%f", "S", TABLE_ALIGN_RIGHT }, - { 10, "OWD mean", "%f", "S", TABLE_ALIGN_RIGHT }, - { 10, "Rate last", "%f", "p/S", TABLE_ALIGN_RIGHT }, - { 10, "Rate mean", "%f", "p/S", TABLE_ALIGN_RIGHT }, - { 10, "Drop", "%ju", "p", TABLE_ALIGN_RIGHT }, - { 10, "Skip", "%ju", "p", TABLE_ALIGN_RIGHT }, - { 10, "Time", "%f", "S", TABLE_ALIGN_RIGHT } + { 10, "Node", "%s", NULL, TABLE_ALIGN_LEFT }, + { 10, "Recv", "%ju", "pkts", TABLE_ALIGN_RIGHT }, + { 10, "Sent", "%ju", "pkts", TABLE_ALIGN_RIGHT }, + { 10, "OWD last", "%f", "secs", TABLE_ALIGN_RIGHT }, + { 10, "OWD mean", "%f", "secs", TABLE_ALIGN_RIGHT }, + { 10, "Rate last", "%f", "pkt/sec", TABLE_ALIGN_RIGHT }, + { 10, "Rate mean", "%f", "pkt/sec", TABLE_ALIGN_RIGHT }, + { 10, "Drop", "%ju", "pkts", TABLE_ALIGN_RIGHT }, + { 10, "Skip", "%ju", "pkts", TABLE_ALIGN_RIGHT }, + { 10, "Time", "%f", "secs", TABLE_ALIGN_RIGHT } }; static struct table stats_table = { diff --git a/lib/log_table.c b/lib/table.c similarity index 75% rename from lib/log_table.c rename to lib/table.c index 1e30b56db..054cb6db4 100644 --- a/lib/log_table.c +++ b/lib/table.c @@ -24,6 +24,7 @@ #include #include "utils.h" +#include "table.h" #include "log.h" static int table_resize(struct table *t, int width) @@ -63,40 +64,46 @@ void table_header(struct table *t) { NOINDENT struct log *l = global_log ? global_log : &default_log; - if (t->width != l->window.ws_col - 30) - table_resize(t, l->window.ws_col - 30); + if (t->width != l->width) + table_resize(t, l->width); + - char *line1 = strf("\b\b" BOX_UD); char *line0 = strf("\b"); - char *line2 = strf("\b"); + char *line1 = strf("\b\b" BOX_UD); + char *line2 = strf("\b\b" BOX_UD); + char *line3 = strf("\b"); for (int i = 0; i < t->ncols; i++) { - char *col = strf(CLR_BLD("%s"), t->cols[i].title); + int w, u; + char *col, *unit; - if (t->cols[i].unit) - strcatf(&col, " (" CLR_YEL("%s") ")", t->cols[i].unit); + col = strf(CLR_BLD("%s"), t->cols[i].title); + unit = t->cols[i].unit ? strf(CLR_YEL("%s"), t->cols[i].unit) : ""; - int l = strlenp(col); - int r = strlen(col); - int w = t->cols[i]._width + r - l; + w = t->cols[i]._width + strlen(col) - strlenp(col); + u = t->cols[i]._width + strlen(unit) - strlenp(unit); - if (t->cols[i].align == TABLE_ALIGN_LEFT) - strcatf(&line1, " %-*.*s " BOX_UD, w, w, col); - else - strcatf(&line1, " %*.*s " BOX_UD, w, w, col); + if (t->cols[i].align == TABLE_ALIGN_LEFT) { + strcatf(&line1, " %-*.*s\e[0m " BOX_UD, w, w, col); + strcatf(&line2, " %-*.*s\e[0m " BOX_UD, u, u, unit); + } + else { + strcatf(&line1, " %*.*s\e[0m " BOX_UD, w, w, col); + strcatf(&line2, " %*.*s\e[0m " BOX_UD, u, u, unit); + } for (int j = 0; j < t->cols[i]._width + 2; j++) { strcatf(&line0, "%s", BOX_LR); - strcatf(&line2, "%s", BOX_LR); + strcatf(&line3, "%s", BOX_LR); } if (i == t->ncols - 1) { strcatf(&line0, "%s", BOX_DL); - strcatf(&line2, "%s", BOX_UDL); + strcatf(&line3, "%s", BOX_UDL); } else { strcatf(&line0, "%s", BOX_DLR); - strcatf(&line2, "%s", BOX_UDLR); + strcatf(&line3, "%s", BOX_UDLR); } free(col); @@ -105,18 +112,20 @@ void table_header(struct table *t) stats("%s", line0); stats("%s", line1); stats("%s", line2); + stats("%s", line3); free(line0); free(line1); free(line2); + free(line3); } void table_row(struct table *t, ...) { NOINDENT struct log *l = global_log ? global_log : &default_log; - if (t->width != l->window.ws_col - 30) { - table_resize(t, l->window.ws_col - 30); + if (t->width != l->width) { + table_resize(t, l->width); table_header(t); } @@ -133,9 +142,9 @@ void table_row(struct table *t, ...) int w = t->cols[i]._width + r - l; if (t->cols[i].align == TABLE_ALIGN_LEFT) - strcatf(&line, " %-*.*s " BOX_UD, w, w, col); + strcatf(&line, " %-*.*s\e[0m " BOX_UD, w, w, col); else - strcatf(&line, " %*.*s " BOX_UD, w, w, col); + strcatf(&line, " %*.*s\e[0m " BOX_UD, w, w, col); free(col); } @@ -150,8 +159,8 @@ void table_footer(struct table *t) { NOINDENT struct log *l = global_log ? global_log : &default_log; - if (t->width != l->window.ws_col - 30) - table_resize(t, l->window.ws_col - 30); + if (t->width != l->width) + table_resize(t, l->width); char *line = strf("\b");