common: add routines for log level names.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2020-10-12 16:03:36 +10:30
parent 0dec593aa8
commit becd4fe576
7 changed files with 82 additions and 61 deletions

View File

@ -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)

49
common/status_levels.c Normal file
View File

@ -0,0 +1,49 @@
#include <ccan/array_size/array_size.h>
#include <ccan/build_assert/build_assert.h>
#include <common/status_levels.h>
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;
}

View File

@ -1,6 +1,7 @@
#ifndef LIGHTNING_COMMON_STATUS_LEVELS_H
#define LIGHTNING_COMMON_STATUS_LEVELS_H
#include "config.h"
#include <ccan/tal/tal.h>
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:
*/

View File

@ -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 \

View File

@ -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,

View File

@ -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\".",

View File

@ -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(); }