From becd4fe5766b4365e43f0acfc308c26386c71783 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 12 Oct 2020 16:03:36 +1030 Subject: [PATCH] common: add routines for log level names. Signed-off-by: Rusty Russell --- common/Makefile | 1 + common/status_levels.c | 49 +++++++++++++++++++++++ common/status_levels.h | 5 +++ lightningd/Makefile | 1 + lightningd/log.c | 65 ++++++------------------------- lightningd/plugin.c | 15 ++++--- lightningd/test/run-log-pruning.c | 7 ++++ 7 files changed, 82 insertions(+), 61 deletions(-) create mode 100644 common/status_levels.c diff --git a/common/Makefile b/common/Makefile index 1c13cc258..b330a5e5f 100644 --- a/common/Makefile +++ b/common/Makefile @@ -95,6 +95,7 @@ COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) \ common/overflows.h \ common/status_levels.h \ common/tx_roles.h + COMMON_HEADERS_GEN := common/htlc_state_names_gen.h common/status_wiregen.h common/peer_status_wiregen.h COMMON_HEADERS := $(COMMON_HEADERS_GEN) $(COMMON_HEADERS_NOGEN) diff --git a/common/status_levels.c b/common/status_levels.c new file mode 100644 index 000000000..fda05be58 --- /dev/null +++ b/common/status_levels.c @@ -0,0 +1,49 @@ +#include +#include +#include + +static const char *ll_names[] = { + "io", + "io", + "debug", + "info", + "unusual", + "broken", +}; + +const char *log_level_name(enum log_level level) +{ + BUILD_ASSERT(ARRAY_SIZE(ll_names) == LOG_LEVEL_MAX+1); + if ((int)level <= LOG_LEVEL_MAX) + return ll_names[level]; + return "***unknown***"; +} + +static bool streq_case(const char *str, const char *s, size_t len) +{ + if (len != strlen(str)) + return false; + return strncasecmp(str, s, len) == 0; +} + +bool log_level_parse(const char *levelstr, size_t len, + enum log_level *level) +{ + for (size_t i = 0; i < ARRAY_SIZE(ll_names); i++) { + if (streq_case(ll_names[i], levelstr, len)) { + *level = i; + return true; + } + } + /* We also allow "error" and "warn" */ + if (streq_case("error", levelstr, len)) { + *level = LOG_BROKEN; + return true; + } + if (streq_case("warn", levelstr, len)) { + *level = LOG_UNUSUAL; + return true; + } + + return false; +} diff --git a/common/status_levels.h b/common/status_levels.h index 939d5ac6a..32d3338c9 100644 --- a/common/status_levels.h +++ b/common/status_levels.h @@ -1,6 +1,7 @@ #ifndef LIGHTNING_COMMON_STATUS_LEVELS_H #define LIGHTNING_COMMON_STATUS_LEVELS_H #include "config.h" +#include enum log_level { /* Logging all IO. */ @@ -17,6 +18,10 @@ enum log_level { }; #define LOG_LEVEL_MAX LOG_BROKEN +const char *log_level_name(enum log_level level); +bool log_level_parse(const char *levelstr, size_t len, + enum log_level *level); + /* * These errors shouldn't happen: */ diff --git a/lightningd/Makefile b/lightningd/Makefile index 227c0bd8d..968e0b21d 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -83,6 +83,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/features.o \ common/fee_states.o \ common/peer_status_wiregen.o \ + common/status_levels.o \ common/status_wiregen.o \ common/gossip_rcvd_filter.o \ common/hash_u5.o \ diff --git a/lightningd/log.c b/lightningd/log.c index a5e57fd05..47628e35b 100644 --- a/lightningd/log.c +++ b/lightningd/log.c @@ -543,57 +543,24 @@ static void log_one_line(unsigned int skipped, data->prefix = "\n"; } -static const struct level { - const char *name; - enum log_level level; -} log_levels[] = { - { "IO", LOG_IO_OUT }, - { "DEBUG", LOG_DBG }, - { "INFO", LOG_INFORM }, - { "UNUSUAL", LOG_UNUSUAL }, - { "BROKEN", LOG_BROKEN } -}; - -static const struct level *str_to_level(const char *str, size_t len) -{ - for (size_t i = 0; i < ARRAY_SIZE(log_levels); i++) { - if (strlen(log_levels[i].name) != len) - continue; - if (strncasecmp(str, log_levels[i].name, len) != 0) - continue; - return &log_levels[i]; - } - return NULL; -} - -static const char *level_to_str(enum log_level level) -{ - for (size_t i = 0; i < ARRAY_SIZE(log_levels); i++) { - if (level == log_levels[i].level) - return log_levels[i].name; - } - return NULL; -} - char *opt_log_level(const char *arg, struct log *log) { - const struct level *level; + enum log_level level; int len; len = strcspn(arg, ":"); - level = str_to_level(arg, len); - if (!level) + if (!log_level_parse(arg, len, &level)) return tal_fmt(NULL, "unknown log level %.*s", len, arg); if (arg[len]) { struct print_filter *f = tal(log->lr, struct print_filter); f->prefix = arg + len + 1; - f->level = level->level; + f->level = level; list_add_tail(&log->lr->print_filters, &f->list); } else { tal_free(log->lr->default_print_level); log->lr->default_print_level = tal(log->lr, enum log_level); - *log->lr->default_print_level = level->level; + *log->lr->default_print_level = level; } return NULL; } @@ -604,7 +571,7 @@ void json_add_opt_log_levels(struct json_stream *response, struct log *log) list_for_each(&log->lr->print_filters, i, list) { json_add_member(response, "log-level", true, "%s:%s", - level_to_str(i->level), i->prefix); + log_level_name(i->level), i->prefix); } } @@ -616,7 +583,7 @@ static void show_log_level(char buf[OPT_SHOW_LEN], const struct log *log) l = *log->lr->default_print_level; else l = DEFAULT_LOGLEVEL; - strncpy(buf, level_to_str(l), OPT_SHOW_LEN-1); + strncpy(buf, log_level_name(l), OPT_SHOW_LEN-1); } static char *arg_log_prefix(const char *arg, struct log *log) @@ -907,20 +874,12 @@ struct command_result *param_loglevel(struct command *cmd, enum log_level **level) { *level = tal(cmd, enum log_level); - if (json_tok_streq(buffer, tok, "io")) - **level = LOG_IO_OUT; - else if (json_tok_streq(buffer, tok, "debug")) - **level = LOG_DBG; - else if (json_tok_streq(buffer, tok, "info")) - **level = LOG_INFORM; - else if (json_tok_streq(buffer, tok, "unusual")) - **level = LOG_UNUSUAL; - else { - return command_fail_badparam(cmd, name, buffer, tok, - "should be 'io', 'debug', 'info', or " - "'unusual'"); - } - return NULL; + if (log_level_parse(buffer + tok->start, tok->end - tok->start, *level)) + return NULL; + + return command_fail_badparam(cmd, name, buffer, tok, + "should be 'io', 'debug', 'info', or " + "'unusual'"); } static struct command_result *json_getlog(struct command *cmd, diff --git a/lightningd/plugin.c b/lightningd/plugin.c index 7db3a2afb..c737a08c6 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -277,15 +277,14 @@ static const char *plugin_log_handle(struct plugin *plugin, "a string \"message\" field"); } - if (!leveltok || json_tok_streq(plugin->buffer, leveltok, "info")) + if (!leveltok) level = LOG_INFORM; - else if (json_tok_streq(plugin->buffer, leveltok, "debug")) - level = LOG_DBG; - else if (json_tok_streq(plugin->buffer, leveltok, "warn")) - level = LOG_UNUSUAL; - else if (json_tok_streq(plugin->buffer, leveltok, "error")) - level = LOG_BROKEN; - else { + else if (!log_level_parse(plugin->buffer + leveltok->start, + leveltok->end - leveltok->start, + &level) + /* FIXME: Allow io logging? */ + || level == LOG_IO_IN + || level == LOG_IO_OUT) { return tal_fmt(plugin, "Unknown log-level %.*s, valid values are " "\"debug\", \"info\", \"warn\", or \"error\".", diff --git a/lightningd/test/run-log-pruning.c b/lightningd/test/run-log-pruning.c index f55266ab3..df384865c 100644 --- a/lightningd/test/run-log-pruning.c +++ b/lightningd/test/run-log-pruning.c @@ -60,6 +60,13 @@ void json_stream_log_suppress_for_cmd(struct json_stream *js UNNEEDED, /* Generated stub for json_stream_success */ struct json_stream *json_stream_success(struct command *cmd UNNEEDED) { fprintf(stderr, "json_stream_success called!\n"); abort(); } +/* Generated stub for log_level_name */ +const char *log_level_name(enum log_level level UNNEEDED) +{ fprintf(stderr, "log_level_name called!\n"); abort(); } +/* Generated stub for log_level_parse */ +bool log_level_parse(const char *levelstr UNNEEDED, size_t len UNNEEDED, + enum log_level *level UNNEEDED) +{ fprintf(stderr, "log_level_parse called!\n"); abort(); } /* Generated stub for node_id_to_hexstr */ char *node_id_to_hexstr(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED) { fprintf(stderr, "node_id_to_hexstr called!\n"); abort(); }