Send spans from Rust to the Jaeger agent over UDP

`enable_tracing` now starts a reporter for the homeserver. A finished
span is queued on a bounded channel and dropped if the queue is full,
so reporting never blocks. A `jaeger-reporter` std thread encodes the
spans and sends them as `emitBatch` datagrams to the agent the Python
tracer uses. A batch goes when the next span would not fit in a 65000
byte datagram, at 100 spans, or a second after its first span. Every
batch carries the Python tracer's service name and process tags.

Like jaeger-client, the reporter sends from an unconnected socket and
resolves the agent's host name when it sends: again every 30 seconds
and after a failed send. A name that does not resolve at startup, or an
agent that moves, does not lose Rust spans for good, and an ICMP error
from a down agent cannot fail a later send.

Homeserver shutdown sends the queued spans, waiting up to a second.
The counters are exported as `synapse_rust_tracing_*` metrics, and a
changed send error is logged.

Nothing reports spans yet: the span API comes next.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W4zxygfJC93SsugxskhoJG
This commit is contained in:
Erik JohnstonandClaude Opus 5.5 committed 2026-10-19 09:05:37 +00:00
1 parent 45b0dd1d1c
commit 78b0598a59
10 files changed
+1084 -15

No files matched your search

+1
View File
@@ -152,6 +152,7 @@ prometheus_metric_fullname_to_label_arg_map: Mapping[str, ArgLocation | None] =
"synapse.util.metrics.DynamicCollectorRegistry": None,
"synapse.metrics.background_process_metrics._Collector": None,
"synapse.storage.rust_pool._RustPoolStatsCollector": None,
"synapse.logging.rust_tracing_metrics._RustTracingCollector": None,
#
# `Metric` subclasses:
"prometheus_client.metrics_core.Metric": None,