Files
synapse/rust/Cargo.toml
T
Erik JohnstonandClaude Opus 5.5 d129d5620c Report tracing spans from Rust code to Jaeger
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
2026-10-19 09:25:22 +00:00

150 lines
4.7 KiB
TOML

[package]
# We name the package `synapse` so that things like logging have the right
# logging target.
name = "synapse"
# dummy version. See pyproject.toml for the Synapse's version number.
version = "0.1.0"
edition = "2021"
rust-version = "1.82.0"
[lib]
name = "synapse"
# We generate a `cdylib` for Python and a standard `lib` for running
# tests/benchmarks.
crate-type = ["lib", "cdylib"]
# This is deprecated, see tool.maturin in pyproject.toml.
# It is left here for compatibilty with maturin < 0.15.
[package.metadata.maturin]
# This is where we tell maturin where to place the built library.
name = "synapse.synapse_rust"
[dependencies]
async-trait = "0.1.89"
anyhow = "1.0.63"
base64 = "0.23.1"
bytes = "1.6.0"
# Matches the version postgres-protocol uses, for iterating a decoded array's
# elements (`ArrayValues` is a `FallibleIterator`); see database/postgres/value.rs.
fallible-iterator = "0.2"
headers = "0.4.0"
http = "1.1.0"
lazy_static = "1.4.0"
libc = "0.2.174"
log = "0.4.17"
tracing = { version = "0.1.41", default-features = false, features = ["std"] }
tracing-subscriber = { version = "0.3", default-features = false, features = ["registry", "std"] }
mime = "0.3.17"
pyo3 = { version = "0.29.0", features = [
"macros",
"anyhow",
"abi3",
"abi3-py310",
# So we can pass `bytes::Bytes` directly back to Python efficiently,
# https://docs.rs/pyo3/latest/pyo3/bytes/index.html
"bytes",
] }
pyo3-log = "0.13.4"
pythonize = { version = "0.29.0", features = ["arbitrary_precision"] }
regex = "1.6.0"
sha2 = "0.11.0"
serde = { version = "1.0.144", features = ["derive", "rc"] }
serde_json = { version = "1.0.85", features = [
"raw_value",
# We need to be able to parse arbitrary precision numbers, as some numbers
# in the database may be out of range of i64 (as Python uses arbitrary
# precision integers).
"arbitrary_precision",
] }
ulid = "3.0.0"
icu_segmenter = "2.0.0"
reqwest = { version = "0.12.15", default-features = false, features = [
"http2",
"stream",
"rustls-tls-native-roots",
] }
http-body-util = "0.1.3"
futures = "0.3.31"
tokio = { version = "1.44.2", features = [
"rt",
"rt-multi-thread",
"net",
"time",
"sync",
"io-util",
] }
tokio-postgres = "0.7"
# Connection pooling for the native Rust Postgres backend. We use the generic
# `deadpool::managed` pool with our own manager (rather than `deadpool-postgres`)
# so it reuses our `connect`/default-host logic and connection-task spawning.
# `rt_tokio_1` lets the pool enforce checkout timeouts (it sleeps via tokio time),
# which we drive on our own tokio runtime.
deadpool = { version = "0.12", features = ["rt_tokio_1"] }
once_cell = "1.18.0"
# Fast hashing for the integer-keyed maps in state resolution.
rustc-hash = "2.1.1"
itertools = "0.15.0"
# Maps that keep insertion order, as the Python dicts they port do.
indexmap = "2.10.0"
# Used by the `libpq` module to load the system libpq at runtime, so that
# libpq is an optional runtime dependency rather than a build-time one.
libloading = "0.8"
postgres-protocol = "0.6.10"
# Use the `ring` crypto provider (not the default `aws-lc-rs`, which needs cmake
# and isn't available here) — `ring` is already in the tree via reqwest.
rustls = { version = "0.23", default-features = false, features = [
"ring",
"logging",
"std",
"tls12",
] }
rustls-native-certs = "0.8"
rustls-pemfile = "2"
tokio-postgres-rustls = { version = "0.14.0", default-features = false, features = [
"ring",
] }
lru = "0.16.4"
# Outbound federation (`federation::agent`). We drive hyper's connection pool
# with our own connector, which does Matrix server name resolution, the IP
# range policy and the TLS policy.
hyper = { version = "1.6.0", features = ["client", "http1"] }
hyper-util = { version = "0.1.16", features = [
"client",
"client-legacy",
"http1",
"tokio",
] }
tokio-rustls = { version = "0.26.2", default-features = false, features = [
"ring",
"logging",
"tls12",
] }
tower-service = "0.3.3"
# SRV lookups. A/AAAA go through the system resolver, as in Python. 0.25
# rather than 0.26, which needs a newer rustc than our MSRV.
hickory-resolver = { version = "0.25.2", default-features = false, features = [
"tokio",
"system-config",
] }
# SRV record ordering and cache period jitter.
rand = "0.10.2"
# The `Expires` header of `.well-known` responses.
httpdate = "1.0.3"
# Resolving `.well-known` redirects.
url = "2.5.4"
# Signing outbound federation requests. 2.x rather than 3.x, which needs a
# newer rustc than our MSRV.
ed25519-dalek = "2.2.0"
# The IP range lists in config.
ipnet = "2.11.0"
[dev-dependencies]
tokio = { version = "1.44.2", features = ["macros", "test-util"] }
[build-dependencies]
blake2 = "0.11.0"
hex = "0.4.3"
rustc_version = "0.4.1"