Ashiedu's picture
Sync unified workbench
0490201 verified

A newer version of the Gradio SDK is available: 6.14.0

Upgrade

T-011: tracing Log Infrastructure β€” Subscriber Init, RUST_LOG Filter, Rerun Sink Feature Flag

Type: Task
Phase: 0 β€” Foundation
Autonomy: agent:autonomous β€” Mechanical wiring, no decisions required.
Stack: stack:rust
Version: v0.1
Iteration: iter-1
Effort: XS (1 hour)


⚠️ Agent Scope: T-004 already calls tracing::info!, tracing::warn!, tracing::error! throughout audio/engine.rs. Right now those calls are silent β€” no subscriber is registered. T-011 initialises the subscriber so those calls produce output. Add the rerun-telemetry Cargo feature as a stub (prints "Rerun sink active" but does no real Rerun work β€” T-121 owns the real implementation). Nothing else.


Context

tracing is already a workspace dependency (AMENDMENT-001) and is called throughout kansas/. Without a subscriber, every tracing::info! call is a no-op and developers get no log output at all β€” including audio device errors, transport state transitions, and model inference latencies. This task is the one-line initialisation that activates all of it.

The rerun-telemetry feature flag gates the Rerun SDK dependency. Production builds ship without it (cargo tauri build β€” no Rerun). Development builds opt in with cargo tauri dev --features rerun-telemetry. T-121 fills the stub with real Rerun log calls.


Prerequisites

  • T-001 merged β€” workspace Cargo.toml with tracing and tracing-subscriber already listed

Verify both are present in [workspace.dependencies]. If missing, add:

tracing            = { version = "*" }
tracing-subscriber = { version = "*", features = ["env-filter", "fmt"] }

Acceptance Criteria

  • cargo tauri dev prints structured log lines to stdout β€” at minimum the [audio] lines from T-004
  • RUST_LOG=debug cargo tauri dev prints debug-level output
  • RUST_LOG=warn cargo tauri dev shows only warnings and errors
  • Without RUST_LOG set, default filter is kansas=info,warn (kansas at info, everything else at warn)
  • cargo tauri dev --features rerun-telemetry prints [logging] Rerun telemetry sink active (stub β€” see T-121) and does not crash
  • cargo tauri build (without rerun-telemetry) compiles without error β€” Rerun SDK is not linked
  • cargo check --workspace β€” zero errors
  • cargo clippy --workspace -- -D warnings β€” zero warnings

New Cargo Feature

Add to kansas/Cargo.toml:

[features]
default = []
rerun-telemetry = []   # T-121 adds: dep:rerun when this is filled in

[dependencies]
tracing            = { workspace = true }
tracing-subscriber = { workspace = true }
# rerun dep added by T-121 under rerun-telemetry feature

New File: kansas/src/logging.rs

//! Logging infrastructure for the Synesthesia Tauri backend.
//!
//! Initialise once at startup via [`setup`].
//! Log level controlled by the `RUST_LOG` environment variable.
//!
//! # Feature: `rerun-telemetry`
//! When compiled with `--features rerun-telemetry`, a stub Rerun sink is
//! registered alongside the stdout subscriber. T-121 replaces the stub with
//! real Rerun log calls.

use tracing_subscriber::{
    fmt,
    layer::SubscriberExt,
    util::SubscriberInitExt,
    EnvFilter,
};

/// Default log filter when `RUST_LOG` is not set.
/// - `kansas` crate: INFO and above (our own logs)
/// - Everything else: WARN and above (suppress noisy deps)
const DEFAULT_FILTER: &str = "kansas=info,warn";

/// Initialise the global tracing subscriber.
/// Must be called exactly once, before any `tracing::` calls.
/// Panics if called a second time (tracing subscriber is a global singleton).
pub fn setup() {
    let filter = EnvFilter::try_from_default_env()
        .unwrap_or_else(|_| EnvFilter::new(DEFAULT_FILTER));

    let fmt_layer = fmt::layer()
        .with_target(true)          // show module path
        .with_thread_names(false)   // too noisy for audio threads
        .with_file(false)           // file:line in DEBUG only
        .compact();

    let registry = tracing_subscriber::registry()
        .with(filter)
        .with(fmt_layer);

    #[cfg(feature = "rerun-telemetry")]
    let registry = registry.with(RerunStubLayer);

    registry.init();

    #[cfg(feature = "rerun-telemetry")]
    tracing::info!("[logging] Rerun telemetry sink active (stub β€” see T-121)");

    tracing::info!("[logging] Tracing initialised β€” RUST_LOG={}", 
        std::env::var("RUST_LOG").unwrap_or_else(|_| DEFAULT_FILTER.into()));
}

// ─── Rerun stub layer ─────────────────────────────────────────────────────────

#[cfg(feature = "rerun-telemetry")]
struct RerunStubLayer;

#[cfg(feature = "rerun-telemetry")]
impl<S: tracing::Subscriber> tracing_subscriber::Layer<S> for RerunStubLayer {
    // T-121 overrides on_event() to forward structured log data to the Rerun SDK.
    // Stub: no-op layer that satisfies the trait bound.
}

Update kansas/src/main.rs

Add one line at the top of main(), before anything else:

mod logging;
// ... other mods

fn main() {
    // MUST be first β€” initialises global tracing subscriber before any
    // tracing::* calls in AudioEngine::new(), TransportHandle::new(), etc.
    logging::setup();

    let audio_engine = AudioEngine::new()
        .expect("Failed to initialise audio engine");

    tauri::Builder::default()
        // ...

Add logging Module to kansas/src/lib.rs

pub mod logging;

Implementation Notes

Why compact() not pretty()

pretty() emits multi-line ANSI output. In a terminal it looks great; in a Windows file redirect or CI log it produces garbled escape codes and hard-to-grep output. compact() gives single-line structured output readable in both.

tracing::instrument for hot paths

Do not add #[tracing::instrument] to the audio callback or the tick loop β€” these fire 200+ times per second and the span overhead accumulates. Reserve #[instrument] for IPC command handlers and one-shot initialisation paths. T-011 does not add any #[instrument] attributes; that is left to individual task authors.

The RerunStubLayer no-op trait impl

tracing_subscriber::Layer<S> has default implementations for all methods. The empty impl is valid Rust β€” it compiles to a zero-cost abstraction that adds no overhead when rerun-telemetry is disabled (the feature gates the entire struct out of the binary). When T-121 arrives it fills in fn on_event(...) to forward log fields to the Rerun SDK.

Log output format

After T-011, cargo tauri dev produces lines like:

2026-03-19T18:45:01.234Z  INFO kansas::logging: [logging] Tracing initialised β€” RUST_LOG=kansas=info,warn
2026-03-19T18:45:01.235Z  INFO kansas::audio::engine: [audio] Output: Speakers (Realtek) | 48000Hz | 2ch
2026-03-19T18:45:01.236Z  INFO kansas::audio::engine: [audio] Input: Microphone (USB) | 48000Hz | 2ch

Testing

# Default filter β€” should see INFO from kansas, WARN from deps
cargo tauri dev

# Debug filter β€” verbose output
RUST_LOG=debug cargo tauri dev

# Warn only β€” mostly silent
RUST_LOG=warn cargo tauri dev

# Rerun stub
cargo tauri dev --features rerun-telemetry
# Expected line: [logging] Rerun telemetry sink active (stub β€” see T-121)

# Release build must NOT include rerun
cargo tauri build
# Verify: ldd/dumpbin on the .exe shows no rerun .dll

GitHub CLI

gh issue create \
  --title "T-011: tracing log infrastructure β€” subscriber init, RUST_LOG filter, Rerun sink stub" \
  --label "type:task,stack:rust,agent:autonomous,priority:high,status:ready,day:1" \
  --body-file T-011.md

Parent: GENESIS
Blocks: T-121 (fills RerunStubLayer::on_event with real Rerun calls)
Blocked By: T-001
Version: v0.1 Β· Iteration: iter-1 Β· Effort: XS (1 hour)