← ClaudeAtlas

rust-observabilitylisted

Instrument, review, and debug Rust diagnostics built on tracing — spans and events, a redacting visitor over a closed field vocabulary, one process-wide dispatcher shared by every FFI boundary, control-plane versus data-plane logging, bounded event queues with drop accounting, relaxed atomic counters, snapshot polling instead of per-event host callbacks, and deterministic emission ordering. Use when you add a log field, wire a host or embedded log sink, keep a hot path free of tracing macros, design a telemetry snapshot for a foreign caller, diagnose a library that emits nothing, or review whether a diagnostic can leak sensitive data.
po4yka/rust-skills · ★ 2 · Code & Development · score 76
Install: claude install-skill po4yka/rust-skills
# Rust Observability This skill covers diagnostic emission in a Rust library that other processes, languages, or runtimes embed. It applies to a cdylib behind an FFI boundary, a staticlib linked into an application, and a plain crate consumed by a host CLI. ## The six rules that are not style 1. **One dispatcher per process.** `tracing::subscriber::set_global_default` succeeds once. A second call returns `Err(SetGlobalDefaultError)`. If you discard that error, the boundary that lost emits nothing for the life of the process, and nothing reports it. 2. **`skip_all` on every `#[instrument]`.** Without it the macro records every argument through `Debug`. 3. **No `?` and no `%` sigils, and no `format!` inside an emission** that can reach a sink you do not control. All three produce free text. 4. **Field names come from one declared vocabulary.** A name that is not in the vocabulary does not compile past the gate. 5. **Nothing on the data plane emits an event.** Data-plane work increments an atomic counter or pushes into a bounded queue. It never calls a log macro. 6. **Diagnostics are observational.** No code path reads the outcome of an emission. Turning a subscriber on must not change a single output byte. ## Add an emission ```rust #[tracing::instrument(skip_all, fields(stage = stage.code()))] fn decode(stage: DecodeStage, items: &[Item]) -> Result<Output, EngineError> { tracing::debug!(item_count = items.len(), "decoding"); // ... } ``` W