| 187 | } |
| 188 | |
| 189 | static void trace_init(void) |
| 190 | { |
| 191 | const char *dev_trace_file; |
| 192 | const char *trace_socket_path; |
| 193 | |
| 194 | if (spans) |
| 195 | return; |
| 196 | |
| 197 | /* We can't use new_htable here because we put non-tal |
| 198 | * objects in our htable, and that breaks memleak_scan_htable! */ |
| 199 | spans = notleak(tal(NULL, struct span_htable)); |
| 200 | memleak_add_helper(spans, memleak_scan_spans); |
| 201 | span_htable_init(spans); |
| 202 | |
| 203 | current = NULL; |
| 204 | dev_trace_file = getenv("CLN_DEV_TRACE_FILE"); |
| 205 | if (dev_trace_file) { |
| 206 | const char *fname = tal_fmt(tmpctx, "%s.%u", dev_trace_file, |
| 207 | (unsigned)getpid()); |
| 208 | trace_to_file = fopen(fname, "a+"); |
| 209 | if (!trace_to_file) |
| 210 | err(1, "Opening CLN_DEV_TRACE_FILE %s", fname); |
| 211 | } |
| 212 | |
| 213 | /* Open a non-blocking UDS datagram socket for trace emission. */ |
| 214 | trace_socket_path = getenv("CLN_TRACE_SOCKET"); |
| 215 | if (trace_socket_path) { |
| 216 | trace_socket_fd = socket(AF_UNIX, SOCK_DGRAM, 0); |
| 217 | if (trace_socket_fd >= 0) { |
| 218 | fcntl(trace_socket_fd, F_SETFL, O_NONBLOCK); |
| 219 | memset(&trace_socket_addr, 0, |
| 220 | sizeof(trace_socket_addr)); |
| 221 | trace_socket_addr.sun_family = AF_UNIX; |
| 222 | strncpy(trace_socket_addr.sun_path, trace_socket_path, |
| 223 | sizeof(trace_socket_addr.sun_path) - 1); |
| 224 | trace_socket_addrlen = |
| 225 | sizeof(trace_socket_addr.sun_family) + |
| 226 | strlen(trace_socket_addr.sun_path) + 1; |
| 227 | } |
| 228 | } |
| 229 | |
| 230 | /* If no output backend is active, disable tracing to skip |
| 231 | * all the expensive span management work. */ |
| 232 | if (!trace_to_file && trace_socket_fd < 0 && !HAVE_USDT) |
| 233 | disable_trace = true; |
| 234 | |
| 235 | if (!disable_trace) |
| 236 | trace_inject_traceparent(); |
| 237 | } |
| 238 | |
| 239 | /** |
| 240 | * Convert the pointer to a context object to a numeric key. |
no test coverage detected