Medius - Rust LibraryTracing

Tracing

Structured diagnostics over the link

The 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 tracing

Off 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
TARGETS
TargetLevelsEmitted
medius::deviceINFO, DEBUG, WARNThe 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::transportTRACEOne event per frame written or read, with dir, opcode, seq, and len.
medius::flashINFO, ERRORReboot-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 events

The connect span wraps the handshake; retry and connected events nest inside it. Its fields are the numbers query_version returns as a Version.

EXAMPLE
// 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 knowing

medius::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.

EXAMPLE
// 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 stderr

The 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-subscriber
EXAMPLE
use 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=0

Filter by level and target

EnvFilter and RUST_LOG

Transport events sit below the default INFO floor. Lower it with a per-target EnvFilter (target names in targets).

EXAMPLE
// 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 frame

medius::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 events

Swap the formatter for JSON and each event becomes one object with its fields as keys. Needs tracing-subscriber's json feature.

EXAMPLE
// 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}}