Tracing
Structured diagnostics over the linkThe tracing feature wires the crate into tracing: it emits a span and events as it works the link, but adds no medius functions and changes no behavior. The sections below are what it emits; you read them by installing a subscriber.
cargo add medius --features tracingOff by default; with the feature off the macros expand to nothing, so there's no runtime cost.
Targets and levels
What the crate emits and where| Target | Levels | Emitted |
|---|---|---|
medius::device | INFO, DEBUG, WARN | The connect span and connected event (INFO), handshake retries (DEBUG) and failures (WARN), query resolved (DEBUG) and timed out (WARN), the reconnected event (INFO), plus the box's own logs re-emitted with device_log=true. |
medius::transport | TRACE | One event per frame written or read, with dir, opcode, seq, and len. |
medius::flash | INFO, ERROR | Reboot-into-download and esptool progress, then tool failure. Present only with the flash feature. |
Keepalive has no target of its own; its periodic frame shows up as an ordinary medius::transport tx event.
The connect span
A span wraps related eventsThe connect span wraps the handshake; retry and connected events nest inside it. Its fields are the numbers query_version returns as a Version.
// With "medius=debug" and a box that answers on the second probe, the
// fmt subscriber prints the span name on each nested event:
// DEBUG connect: medius::device: handshake: version probe timed out, retrying
// INFO connect: medius::device: connected proto_ver=3 fw_major=1 fw_minor=3 fw_patch=0
// "connect:" is the span; the rest is the event with its fields.Frames, device logs, and reconnects
The events worth knowingmedius::transport emits one TRACE per frame, the per-frame mirror of the frames_tx / frames_rx counters. Each LOG frame the box sends is re-emitted on medius::device with device_log=true at its matching LogLevel (the same data the logs stream hands back). A recovered link fires an INFO reconnected event with port and reason.
// medius::transport=trace, one line per frame:
// TRACE medius::transport: dir="tx" opcode=1 seq=7 len=4
// a box log, mirrored:
// WARN medius::device: mouse detached device_log=true
// a recovered link:
// INFO medius::device: reconnected port="/dev/ttyACM0" reason="rescan"Install a subscriber
Print the events to stderrThe crate ships no subscriber, so add one alongside the feature, usually tracing-subscriber. The fmt subscriber writes lines to stderr; call init() once before opening. Without one, every span and event is dropped silently.
cargo add tracing-subscriberuse medius::Device;
tracing_subscriber::fmt::init();
let device = Device::find()?;
device.move_rel(10, 0)?;
// stderr now carries the connect span and an INFO event, e.g.:
// INFO connect: medius::device: connected proto_ver=3 fw_major=1 fw_minor=3 fw_patch=0Filter by level and target
EnvFilter and RUST_LOGTransport events sit below the default INFO floor. Lower it with a per-target EnvFilter (target names in targets).
// Code-side: medius events at DEBUG, everything else at the default.
tracing_subscriber::fmt()
.with_env_filter("medius=debug")
.init();
// Or set it at runtime instead, no recompile:
// RUST_LOG=medius=debug ./your-program
// RUST_LOG=medius::transport=trace ./your-program # every framemedius::transport=trace emits one line per frame in both directions. Leave it off unless you're chasing a wire-level bug.
JSON output
Ship structured eventsSwap the formatter for JSON and each event becomes one object with its fields as keys. Needs tracing-subscriber's json feature.
// cargo add tracing-subscriber --features json
tracing_subscriber::fmt()
.json()
.with_env_filter("medius=debug")
.init();
// Each event is now a JSON line, e.g.:
// {"level":"INFO","target":"medius::device","fields":{"message":"connected","proto_ver":3}}