Skip to content

Commit 2d25462

Browse files
committed
trace: use a static buffer instead of tal_fmt().
There's an EBPF limit anyway, so stick with a 512-byte buffer. This brings us back to 621ns per trace: Before: real 0m13.441000-14.592000(14.2686+/-0.43)s user 0m11.265000-12.289000(11.9626+/-0.37)s sys 0m2.175000-2.381000(2.3048+/-0.072)s After: real 0m5.819000-6.472000(6.2064+/-0.26)s user 0m3.779000-4.101000(3.956+/-0.12)s sys 0m2.040000-2.431000(2.2496+/-0.15)s Signed-off-by: Rusty Russell <[email protected]>
1 parent 049e78c commit 2d25462

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

common/trace.c

+31-19
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
#include <assert.h>
33
#include <ccan/htable/htable.h>
44
#include <ccan/str/hex/hex.h>
5-
#include <ccan/tal/str/str.h>
65
#include <ccan/tal/tal.h>
76
#include <ccan/time/time.h>
87
#include <common/json_stream.h>
@@ -214,11 +213,15 @@ static struct span *trace_span_slot(void)
214213
return s;
215214
}
216215

216+
#define MAX_BUF_SIZE 512
217+
217218
static void trace_emit(struct span *s)
218219
{
219220
char span_id[HEX_SPAN_ID_SIZE];
220221
char trace_id[HEX_TRACE_ID_SIZE];
221222
char parent_span_id[HEX_SPAN_ID_SIZE];
223+
char buffer[MAX_BUF_SIZE + 1];
224+
size_t len;
222225

223226
/* If this is a remote span it's not up to us to emit it. Make
224227
* this a no-op. `trace_span_end` will take care of cleaning
@@ -232,32 +235,41 @@ static void trace_emit(struct span *s)
232235
if (s->parent)
233236
hex_encode(s->parent_id, SPAN_ID_SIZE, parent_span_id, HEX_SPAN_ID_SIZE);
234237

235-
char *res = tal_fmt(
236-
NULL,
237-
"[{\"id\": \"%s\", \"name\": \"%s\", "
238-
"\"timestamp\": %" PRIu64 ", \"duration\": %" PRIu64 ",",
239-
span_id, s->name, s->start_time, s->end_time - s->start_time);
240-
241-
tal_append_fmt(&res, "\"localEndpoint\": { \"serviceName\": \"%s\"}, ",
242-
trace_service_name);
238+
len = snprintf(buffer, MAX_BUF_SIZE,
239+
"[{\"id\": \"%s\", \"name\": \"%s\", "
240+
"\"timestamp\": %" PRIu64 ", \"duration\": %" PRIu64 ","
241+
"\"localEndpoint\": { \"serviceName\": \"%s\"}, ",
242+
span_id, s->name, s->start_time, s->end_time - s->start_time, trace_service_name);
243243

244244
if (s->parent != NULL) {
245-
tal_append_fmt(&res, "\"parentId\": \"%s\",", parent_span_id);
245+
len += snprintf(buffer + len, MAX_BUF_SIZE - len,
246+
"\"parentId\": \"%s\",",
247+
parent_span_id);
248+
if (len > MAX_BUF_SIZE)
249+
len = MAX_BUF_SIZE;
246250
}
247251

248-
tal_append_fmt(&res, "\"tags\": {");
252+
len += snprintf(buffer + len, MAX_BUF_SIZE - len,
253+
"\"tags\": {");
254+
if (len > MAX_BUF_SIZE)
255+
len = MAX_BUF_SIZE;
249256
for (size_t i = 0; i < SPAN_MAX_TAGS; i++) {
250257
if (!s->tags[i].name)
251258
continue;
252-
tal_append_fmt(&res, "%s\"%s\": \"%.*s\"", i == 0 ? "" : ", ",
253-
s->tags[i].name,
254-
s->tags[i].valuelen,
255-
s->tags[i].valuestr);
259+
len += snprintf(buffer + len, MAX_BUF_SIZE - len,
260+
"%s\"%s\": \"%.*s\"", i == 0 ? "" : ", ",
261+
s->tags[i].name,
262+
s->tags[i].valuelen,
263+
s->tags[i].valuestr);
264+
if (len > MAX_BUF_SIZE)
265+
len = MAX_BUF_SIZE;
256266
}
257-
258-
tal_append_fmt(&res, "}, \"traceId\": \"%s\"}]", trace_id);
259-
DTRACE_PROBE2(lightningd, span_emit, span_id, res);
260-
tal_free(res);
267+
len += snprintf(buffer + len, MAX_BUF_SIZE - len,
268+
"}, \"traceId\": \"%s\"}]", trace_id);
269+
if (len > MAX_BUF_SIZE)
270+
len = MAX_BUF_SIZE;
271+
buffer[len] = '\0';
272+
DTRACE_PROBE2(lightningd, span_emit, span_id, buffer);
261273
}
262274

263275
/**

0 commit comments

Comments
 (0)