diff --git a/lightningd/jsonrpc.c b/lightningd/jsonrpc.c index f4a4166f43f0..d8b099ee225f 100644 --- a/lightningd/jsonrpc.c +++ b/lightningd/jsonrpc.c @@ -527,6 +527,33 @@ static void json_command_malformed(struct json_connection *jcon, json_stream_close(js, NULL); } +void json_notify_fmt(struct command *cmd, + enum log_level level, + const char *fmt, ...) +{ + va_list ap; + struct json_stream *js; + + if (!cmd->send_notifications) + return; + + js = json_stream_raw_for_cmd(cmd); + + va_start(ap, fmt); + json_object_start(js, NULL); + json_add_string(js, "jsonrpc", "2.0"); + json_add_string(js, "method", "message"); + json_object_start(js, "params"); + json_add_string(js, "id", cmd->id); + json_add_string(js, "level", log_level_name(level)); + json_add_string(js, "message", tal_vfmt(tmpctx, fmt, ap)); + json_object_end(js); + json_object_end(js); + + json_stream_double_cr(js); + json_stream_flush(js); +} + struct json_stream *json_stream_raw_for_cmd(struct command *cmd) { struct json_stream *js; diff --git a/lightningd/jsonrpc.h b/lightningd/jsonrpc.h index da80d4ad95ce..b01a03046165 100644 --- a/lightningd/jsonrpc.h +++ b/lightningd/jsonrpc.h @@ -7,6 +7,7 @@ #include #include #include +#include #include struct jsonrpc; @@ -154,6 +155,12 @@ static inline void fixme_ignore(const struct command_result *res) { } +/* Notifier to the caller. */ +void json_notify_fmt(struct command *cmd, + enum log_level level, + const char *fmt, ...) + PRINTF_FMT(3, 4); + /* FIXME: For the few cases where return value is indeterminate */ struct command_result *command_its_complicated(const char *why); diff --git a/lightningd/test/run-jsonrpc.c b/lightningd/test/run-jsonrpc.c index 444401c08f2c..7bde86ac3ec0 100644 --- a/lightningd/test/run-jsonrpc.c +++ b/lightningd/test/run-jsonrpc.c @@ -50,6 +50,9 @@ void log_io(struct log *log UNNEEDED, enum log_level dir UNNEEDED, const char *comment UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED) { fprintf(stderr, "log_io 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 memleak_remove_strmap_ */ void memleak_remove_strmap_(struct htable *memtable UNNEEDED, const struct strmap *m UNNEEDED) { fprintf(stderr, "memleak_remove_strmap_ called!\n"); abort(); }