mirror of
https://github.com/element-hq/synapse.git
synced 2026-11-04 13:28:04 +00:00
Rust code now creates spans with the `tracing` crate. `JaegerLayer` gives each span Jaeger IDs and reports sampled ones through the homeserver's UDP reporter when they close. A span's parent is its `tracing` parent, else (for a span with no explicit parent) the Python span that was active when its task was spawned, from the task's logcontext handle, else the Python span set for the thread by `with_py_parent`. With no parent, the configured `const` or `probabilistic` sampler decides, and a sampled root gets jaeger-client's `sampler.type` and `sampler.param` tags. A child copies its parent's trace ID, flags and baggage, so sampling is decided once per trace and `force_tracing` carries over. A span ends when it is last exited, or when it closes if it was never entered. The registry keeps a parent open until its children close, so its duration must not be taken at close. Work that outlives its parent should start a trace with `parent: None` and `follows_from`. Span fields become tags (strings cut to 1024 bytes, as jaeger-client does), `otel.name` sets the operation name, and events inside a span become logs. Only Synapse's own spans and events are recorded, not those of hyper, h2 and other dependencies. The layer is the process-wide subscriber. It reports to the first homeserver that enables tracing until that homeserver shuts down or is dropped. Spans are disabled while no reporter is attached, so they cost almost nothing with tracing off. `is_sampled`, `span_context`, `inject_headers` (`uber-trace-id` plus `uberctx-*` baggage, as jaeger-client's HTTP codec writes them) and `follows_from` are there for the instrumentation that follows. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01W4zxygfJC93SsugxskhoJG