From 57328f740cfa650a1dd91412675d53358e3f689b Mon Sep 17 00:00:00 2001 From: Mollusk Date: Mon, 25 May 2026 02:39:20 -0400 Subject: [PATCH] fix(output): route tracing to stderr so --output json stdout stays clean MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit common::output documents the contract: JSON events on stdout, banner + tracing on stderr, so a parser reading stdout sees only events. But init_tracing relied on tracing_subscriber::fmt()'s default writer, which is stdout — so every log line was interleaved into the JSON event stream the --gui front-end parses. The GUI tolerated it (non-JSON lines are skipped), but two real consequences: a tracing write could corrupt a JSON event line intermittently, and all diagnostics landed on stdout where the GUI discards them — leaving its stderr-tail ring empty, so a failed host/viewer child surfaced no clue in the window. Pin the fmt writer to stderr. Verified: every stdout line now parses as JSON; iroh/tracing output appears on stderr. Co-Authored-By: Claude Opus 4.7 --- src/main.rs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main.rs b/src/main.rs index 0254c67..98ea6cb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -75,5 +75,14 @@ async fn main() -> Result<()> { fn init_tracing(verbose: bool) { let default = if verbose { "pixelpass=trace,iroh=info" } else { "pixelpass=info,iroh=warn" }; let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(default)); - tracing_subscriber::fmt().with_env_filter(filter).with_target(false).init(); + // Tracing MUST write to stderr. `tracing_subscriber::fmt()` defaults its + // writer to stdout, but with `--output json` stdout carries the JSON event + // stream the `--gui` front-end parses (see `common::output`) — logging there + // interleaves log lines into that stream (corrupting events and starving the + // GUI's stderr-tail diagnostics). Pin it to stderr to honor that contract. + tracing_subscriber::fmt() + .with_writer(std::io::stderr) + .with_env_filter(filter) + .with_target(false) + .init(); }