diff --git a/lightningd/json.c b/lightningd/json.c index 015cd9a7c..b28012ecc 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -429,3 +429,14 @@ void json_add_timeabs(struct json_stream *result, const char *fieldname, json_add_member(result, fieldname, "%" PRIu64 ".%03" PRIu64, (u64)t.ts.tv_sec, (u64)t.ts.tv_nsec / 1000000); } + +void json_add_time(struct json_stream *result, const char *fieldname, + struct timespec ts) +{ + char timebuf[100]; + + snprintf(timebuf, sizeof(timebuf), "%lu.%09u", + (unsigned long)ts.tv_sec, + (unsigned)ts.tv_nsec); + json_add_string(result, fieldname, timebuf); +} diff --git a/lightningd/json.h b/lightningd/json.h index c880ef7fd..514a6d323 100644 --- a/lightningd/json.h +++ b/lightningd/json.h @@ -204,4 +204,8 @@ enum address_parse_result json_tok_address_scriptpubkey(const tal_t *ctx, void json_add_timeabs(struct json_stream *result, const char *fieldname, struct timeabs t); +/* used in log.c and notification.c*/ +void json_add_time(struct json_stream *result, const char *fieldname, + struct timespec ts); + #endif /* LIGHTNING_LIGHTNINGD_JSON_H */ diff --git a/lightningd/log.c b/lightningd/log.c index 37d76c1c7..28f7e4e95 100644 --- a/lightningd/log.c +++ b/lightningd/log.c @@ -4,7 +4,6 @@ #include #include #include -#include #include #include #include @@ -19,6 +18,7 @@ #include #include #include +#include #include #include #include @@ -31,39 +31,6 @@ /* Once we're up and running, this is set up. */ struct log *crashlog; -struct log_entry { - struct list_node list; - struct timeabs time; - enum log_level level; - unsigned int skipped; - const char *prefix; - char *log; - /* Iff LOG_IO */ - const u8 *io; -}; - -struct log_book { - size_t mem_used; - size_t max_mem; - void (*print)(const char *prefix, - enum log_level level, - bool continued, - const struct timeabs *time, - const char *str, - const u8 *io, size_t io_len, - void *arg); - void *print_arg; - enum log_level print_level; - struct timeabs init_time; - - struct list_head log; -}; - -struct log { - struct log_book *lr; - const char *prefix; -}; - static void log_to_file(const char *prefix, enum log_level level, bool continued, @@ -664,17 +631,6 @@ static void add_skipped(struct log_info *info) } } -static void json_add_time(struct json_stream *result, const char *fieldname, - struct timespec ts) -{ - char timebuf[100]; - - snprintf(timebuf, sizeof(timebuf), "%lu.%09u", - (unsigned long)ts.tv_sec, - (unsigned)ts.tv_nsec); - json_add_string(result, fieldname, timebuf); -} - static void log_to_json(unsigned int skipped, struct timerel diff, enum log_level level, diff --git a/lightningd/log.h b/lightningd/log.h index 0e74bc4aa..de8a4932e 100644 --- a/lightningd/log.h +++ b/lightningd/log.h @@ -1,6 +1,7 @@ #ifndef LIGHTNING_LIGHTNINGD_LOG_H #define LIGHTNING_LIGHTNINGD_LOG_H #include "config.h" +#include #include #include #include @@ -14,6 +15,39 @@ struct json_stream; struct lightningd; struct timerel; +struct log_entry { + struct list_node list; + struct timeabs time; + enum log_level level; + unsigned int skipped; + const char *prefix; + char *log; + /* Iff LOG_IO */ + const u8 *io; +}; + +struct log_book { + size_t mem_used; + size_t max_mem; + void (*print)(const char *prefix, + enum log_level level, + bool continued, + const struct timeabs *time, + const char *str, + const u8 *io, size_t io_len, + void *arg); + void *print_arg; + enum log_level print_level; + struct timeabs init_time; + + struct list_head log; +}; + +struct log { + struct log_book *lr; + const char *prefix; +}; + /* We can have a single log book, with multiple logs in it: it's freed by * the last struct log itself. */ struct log_book *new_log_book(size_t max_mem, diff --git a/lightningd/notification.c b/lightningd/notification.c index 0486a31a5..d133b9083 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -1,9 +1,11 @@ #include "lightningd/notification.h" #include +#include const char *notification_topics[] = { "connect", "disconnect", + "warning" }; bool notifications_have_topic(const char *topic) @@ -33,3 +35,28 @@ void notify_disconnect(struct lightningd *ld, struct node_id *nodeid) jsonrpc_notification_end(n); plugins_notify(ld->plugins, take(n)); } + +/*'warning' is based on LOG_UNUSUAL/LOG_BROKEN level log + *(in plugin module, they're 'warn'/'error' level). */ +void notify_warning(struct lightningd *ld, struct log_entry *l) +{ + struct jsonrpc_notification *n = + jsonrpc_notification_start(NULL, notification_topics[2]); + json_object_start(n->stream, "warning"); + /* Choose "BROKEN"/"UNUSUAL" to keep consistent with the habit + * of plugin. But this may confuses the users who want to 'getlog' + * with the level indicated by notifications. It is the duty of a + * plugin to eliminate this misunderstanding. + */ + json_add_string(n->stream, "level", + l->level == LOG_BROKEN ? "error" + : "warn"); + /* unsuaul/broken event is rare, plugin pay more attentions on + * the absolute time, like when channels failed. */ + json_add_time(n->stream, "time", l->time.ts); + json_add_string(n->stream, "source", l->prefix); + json_add_string(n->stream, "log", l->log); + json_object_end(n->stream); /* .warning */ + jsonrpc_notification_end(n); + plugins_notify(ld->plugins, take(n)); +} \ No newline at end of file diff --git a/lightningd/notification.h b/lightningd/notification.h index 081232894..dcc8d261a 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -3,6 +3,7 @@ #include "config.h" #include #include +#include #include bool notifications_have_topic(const char *topic); @@ -11,4 +12,6 @@ void notify_connect(struct lightningd *ld, struct node_id *nodeid, struct wireaddr_internal *addr); void notify_disconnect(struct lightningd *ld, struct node_id *nodeid); +void notify_warning(struct lightningd *ld, struct log_entry *l); + #endif /* LIGHTNING_LIGHTNINGD_NOTIFICATION_H */