Tracing
The tracing feature emits a span and events to tracing as the crate works the link, with no new functions and no behaviour change. A subscriber reads them.
cargo add medius --features tracingOff by default. When off, the macros expand to nothing and cost nothing at runtime.
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 box 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 | Firmware update progress and refusals. |
Keepalive frames show up as ordinary medius::transport tx events.
connect span Spans wrap related events
The connect span wraps the handshake, and the retry and connected events nest inside it. The connected event carries the numbers query_version returns as a Version.
// With "medius=debug" and a box that replies 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=9 fw_major=3 fw_minor=4 fw_patch=2
// "connect:" is the span; the rest is the event with its fields.Frames, device logs, and reconnects Transport, log and recovery events
medius::transport events mirror the frames_tx / frames_rx counters per frame. A re-emitted LOG frame keeps its LogLevel and the text the logs stream yields. A recovered link fires reconnected with port and reason. Session recovery fires device chip restarted after a boot and the box released the session after a release.
// 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"
// a restarted device chip, and a session the box released:
// INFO medius::device: device chip restarted
// INFO medius::device: the box released the session session=3Install a subscriber Print the events to stderr
Add a subscriber alongside the feature, usually tracing-subscriber, whose fmt subscriber writes lines to stderr. Call init() once before opening. Without a subscriber, every span and event is discarded.
cargo add tracing-subscriberuse medius::Device;
tracing_subscriber::fmt::init();
let device = Device::find()?;
device.move_rel(10, 0)?;
// stderr carries the connect span and an INFO event, e.g.:
// INFO connect: medius::device: connected proto_ver=9 fw_major=3 fw_minor=4 fw_patch=2FilteringEnvFilter and RUST_LOG
Transport 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 at runtime, 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. Use it for wire-level bugs.
JSON output Structured events
The JSON formatter writes each event as one object, 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();
// one JSON line per event, e.g.:
// {"level":"INFO","target":"medius::device","fields":{"message":"connected","proto_ver":9}}