Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
trapy
Python logging facade that emits real Rust tracing events with structured kwargs.
In a process that mixes Python and Rust (PyO3 cdylibs), trapy gives both sides one tracing pipeline: trapy.info("msg", cat="planning", x=1) produces an event indistinguishable from tracing::info!(cat = "planning", x = 1, "msg") to any subscriber — including category routing, level filtering, and per-field structured access. Caller file/line/module are pulled from the Python frame and woven into the event metadata (target = "py:<module>"), so subscribers report Python locations and can route by Python module.
Events
Each kwarg becomes a real tracing field. Primitives (bool/int/float/str/None) flow through natively; lists, tuples, dicts, dataclasses, and anything implementing __array__ (numpy arrays, tensors) flow through valuable as structured values. Anything else is stringified rather than raising.
Spans
...
=
# closes the previous epoch span, opens the next
Every span emits cat="timing" events on enter and exit (with elapsed_ms), so <dir>/timing.log doubles as a wall-clock record. For aggregate statistics install the timing layer (below) and call trapy.dump_timing().
Subscriber backend
The backend is compiled behind the subscribers cargo feature (the wheel enables it). Configure any number of layers, then install once:
# tracing-catty: events route to <dir>/<cat>.log
# tracing-timing HDR histograms
# stream to a Tracy profiler
# OTLP span export
# one-shot; add_* calls fail afterwards
Or the one-call convenience for the file-router-only setup: trapy.init_tracing(dir).
Available layers:
| call | layer |
|---|---|
add_file_router(dir, ...) |
tracing-catty per-category file router. Defaults: cat="progress" mirrors to stdout, cat="console" is stdout-only, ERROR events fan out to errors.log; override via console_cats= / console_only_cats= / split_errors= / split_warnings= |
add_fmt_layer(...) |
tracing_subscriber::fmt with the full builder surface: format= full/compact/pretty/json, stdout/stderr or file=, span_events=, thread/file/line knobs |
add_env_filter(directive) / add_env_filter_from_env(var) |
EnvFilter with RUST_LOG syntax; rejected events never reach downstream layers |
add_json_file(path) |
JSON-per-line file, for Loki/Promtail-style shipping |
add_timing_layer(...) + dump_timing() |
tracing-timing inter-event HDR histograms keyed by (span, event) |
add_tracy_layer() |
tracing-tracy; starts the Tracy client eagerly so the profiler can attach before the first span |
add_opentelemetry_layer(endpoint, service_name) |
tracing-opentelemetry OTLP span export over HTTP + binary protobuf (no embedded tokio runtime) |
Flushing: flush_tracing() (async), flush_tracing_sync() (blocks until the writer acks — call before process exit), flush_opentelemetry() / shutdown_opentelemetry() for the OTLP batch exporter.
Multi-cdylib forwarding
Every PyO3 cdylib statically links its own copy of tracing-core, so a subscriber installed in trapy._trapy.so is invisible to events emitted from another cdylib. trapy bridges this with a C-ABI capsule (trapy._capsule): the host cdylib links trapy as an rlib without default features and installs a forwarding subscriber at module init —
= { = "0.1.0", = false }
Events from the host's tracing::*! macros then flow through trapy's full layer chain. The handshake is fail-safe: if trapy isn't importable, the host still loads and its events are dropped. set_log_level() / get_log_level() gate the FFI boundary coarsely so foreign cdylibs can drop events before paying for formatting; in-process filtering is EnvFilter's job.
Building
Cargo features:
| feature | meaning |
|---|---|
subscribers |
the whole backend: layer builders, the file router, the capsule owner side. The wheel enables it via pyproject.toml |
extension-module |
pyo3/extension-module, for standalone wheel builds only |
Crates that consume trapy as an rlib (capsule forwarding) must enable neither — they stay consumer-only and skip compiling every subscriber crate.
The valuable field support rides tracing's unstable API: builds need --cfg tracing_unstable (the workspace .cargo/config.toml sets it).