diff --git a/common/trace.c b/common/trace.c index dd6df82b7063..bf62c7776ade 100644 --- a/common/trace.c +++ b/common/trace.c @@ -269,6 +269,12 @@ void trace_span_tag(const void *key, const char *name, const char *value) size_t s = tal_count(span->tags); tal_resize(&span->tags, s + 1); span->tags[s].name = tal_strdup(span->tags, name); + if (strstarts(value, "\"") + && strlen(value) > 1 + && strends(value, "\"")) { + value = tal_strndup(tmpctx, value + 1, + strlen(value) - 2); + } span->tags[s].value = tal_strdup(span->tags, value); } diff --git a/plugins/Makefile b/plugins/Makefile index 3c34f72481e0..53652eaea54a 100644 --- a/plugins/Makefile +++ b/plugins/Makefile @@ -23,8 +23,8 @@ PLUGIN_COMMANDO_OBJS := $(PLUGIN_COMMANDO_SRC:.c=.o) PLUGIN_KEYSEND_SRC := plugins/keysend.c PLUGIN_KEYSEND_OBJS := $(PLUGIN_KEYSEND_SRC:.c=.o) -PLUGIN_LIB_SRC := plugins/libplugin.c -PLUGIN_LIB_HEADER := plugins/libplugin.h +PLUGIN_LIB_SRC := plugins/libplugin.c common/trace.c +PLUGIN_LIB_HEADER := plugins/libplugin.h common/trace.h PLUGIN_LIB_OBJS := $(PLUGIN_LIB_SRC:.c=.o) PLUGIN_PAY_LIB_SRC := plugins/libplugin-pay.c diff --git a/plugins/bkpr/test/run-bkpr_db.c b/plugins/bkpr/test/run-bkpr_db.c index bd9104d80ff4..42ef7fcce082 100644 --- a/plugins/bkpr/test/run-bkpr_db.c +++ b/plugins/bkpr/test/run-bkpr_db.c @@ -246,6 +246,21 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* Generated stub for towire_wirestring */ void towire_wirestring(u8 **pptr UNNEEDED, const char *str UNNEEDED) { fprintf(stderr, "towire_wirestring called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_resume */ +void trace_span_resume(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_resume called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_suspend */ +void trace_span_suspend(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_suspend called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ static char *tmp_dsn(const tal_t *ctx) diff --git a/plugins/bkpr/test/run-recorder.c b/plugins/bkpr/test/run-recorder.c index 62c317746102..f23a1b4790f7 100644 --- a/plugins/bkpr/test/run-recorder.c +++ b/plugins/bkpr/test/run-recorder.c @@ -252,6 +252,21 @@ void towire_u8_array(u8 **pptr UNNEEDED, const u8 *arr UNNEEDED, size_t num UNNE /* Generated stub for towire_wirestring */ void towire_wirestring(u8 **pptr UNNEEDED, const char *str UNNEEDED) { fprintf(stderr, "towire_wirestring called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_resume */ +void trace_span_resume(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_resume called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_suspend */ +void trace_span_suspend(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_suspend called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ static char *tmp_dsn(const tal_t *ctx) diff --git a/plugins/libplugin-pay.c b/plugins/libplugin-pay.c index 3e23aa9328f8..c347c90f3782 100644 --- a/plugins/libplugin-pay.c +++ b/plugins/libplugin-pay.c @@ -10,9 +10,11 @@ #include #include #include +#include #include #include #include +#include #include #include @@ -2252,6 +2254,18 @@ static void payment_finished(struct payment *p) } } +const char * const payment_step_str[] = +{ + [PAYMENT_STEP_INITIALIZED] = "PAYMENT_STEP_INITIALIZED", + [PAYMENT_STEP_GOT_ROUTE] = "PAYMENT_STEP_GOT_ROUTE", + [PAYMENT_STEP_RETRY_GETROUTE] = "PAYMENT_STEP_RETRY_GETROUTE", + [PAYMENT_STEP_ONION_PAYLOAD] = "PAYMENT_STEP_ONION_PAYLOAD", + [PAYMENT_STEP_SPLIT] = "PAYMENT_STEP_SPLIT", + [PAYMENT_STEP_RETRY] = "PAYMENT_STEP_RETRY", + [PAYMENT_STEP_FAILED] = "PAYMENT_STEP_FAILED", + [PAYMENT_STEP_SUCCESS] = "PAYMENT_STEP_SUCCESS", +}; + void payment_set_step(struct payment *p, enum payment_step newstep) { p->current_modifier = -1; @@ -2266,12 +2280,17 @@ void payment_continue(struct payment *p) { struct payment_modifier *mod; void *moddata; + + trace_span_start("payment_continue", p); /* If we are in the middle of calling the modifiers, continue calling * them, otherwise we can continue with the payment state-machine. */ p->current_modifier++; mod = p->modifiers[p->current_modifier]; if (mod != NULL) { + char *str = tal_fmt(tmpctx, "%d", p->current_modifier); + trace_span_tag(p, "modifier", str); + trace_span_end(p); /* There is another modifier, so call it. */ moddata = p->modifier_data[p->current_modifier]; return mod->post_step_cb(moddata, p); @@ -2279,6 +2298,8 @@ void payment_continue(struct payment *p) /* There are no more modifiers, so reset the call chain and * proceed to the next state. */ p->current_modifier = -1; + trace_span_tag(p, "step", payment_step_str[p->step]); + trace_span_end(p); switch (p->step) { case PAYMENT_STEP_INITIALIZED: case PAYMENT_STEP_RETRY_GETROUTE: @@ -2305,6 +2326,7 @@ void payment_continue(struct payment *p) return; } } + trace_span_end(p); /* We should never get here, it'd mean one of the state machine called * `payment_continue` after the final state. */ abort(); diff --git a/plugins/libplugin.c b/plugins/libplugin.c index 6687fe838f93..5a756b9cab36 100644 --- a/plugins/libplugin.c +++ b/plugins/libplugin.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -973,10 +974,18 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks) if (out->cmd) tal_del_destructor2(out->cmd, disable_request_cb, out); + trace_span_resume(out); + /* We want to free this if callback doesn't. */ tal_steal(tmpctx, out); contenttok = json_get_member(buf, toks, "error"); + + /* Annotate the JSON-RPC span whether it succeeded or failed, + * and then emit it. */ + trace_span_tag(out, "error", contenttok == NULL ? "true" : "false"); + trace_span_end(out); + if (contenttok) { if (out->errcb) res = out->errcb(out->cmd, buf, contenttok, out->arg); @@ -1007,6 +1016,13 @@ send_outreq(struct plugin *plugin, const struct out_req *req) json_object_end(req->js); json_stream_close(req->js, req->cmd); + /* We are about to hand control over to the RPC, so suspend + * the current span. It'll be resumed as soon as we have a + * result to pass to either the error or the success + * callback. */ + trace_span_start("jsonrpc", req); + trace_span_tag(req, "id", req->id); + trace_span_suspend(req); ld_rpc_send(plugin, req->js); if (req->cmd != NULL) diff --git a/plugins/test/run-route-calc.c b/plugins/test/run-route-calc.c index 5cee7ad8e5c8..4d25fbdbc1e8 100644 --- a/plugins/test/run-route-calc.c +++ b/plugins/test/run-route-calc.c @@ -276,6 +276,15 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED) /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #ifndef SUPERVERBOSE diff --git a/plugins/test/run-route-overlong.c b/plugins/test/run-route-overlong.c index 3e55dc4cb7a7..a64376b35160 100644 --- a/plugins/test/run-route-overlong.c +++ b/plugins/test/run-route-overlong.c @@ -273,6 +273,15 @@ void towire_bigsize(u8 **pptr UNNEEDED, const bigsize_t val UNNEEDED) /* Generated stub for towire_channel_id */ void towire_channel_id(u8 **pptr UNNEEDED, const struct channel_id *channel_id UNNEEDED) { fprintf(stderr, "towire_channel_id called!\n"); abort(); } +/* Generated stub for trace_span_end */ +void trace_span_end(const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_end called!\n"); abort(); } +/* Generated stub for trace_span_start */ +void trace_span_start(const char *name UNNEEDED, const void *key UNNEEDED) +{ fprintf(stderr, "trace_span_start called!\n"); abort(); } +/* Generated stub for trace_span_tag */ +void trace_span_tag(const void *key UNNEEDED, const char *name UNNEEDED, const char *value UNNEEDED) +{ fprintf(stderr, "trace_span_tag called!\n"); abort(); } /* AUTOGENERATED MOCKS END */ #ifndef SUPERVERBOSE