{"record":{"id":"bba2b17ad5655279","repo":"nautechsystems/nautilus_trader","slug":"tracing-subscriber-already-initialized","errorCode":null,"errorMessage":"Tracing subscriber already initialized","messagePattern":"Tracing subscriber already initialized","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/common/src/logging/bridge.rs","lineNumber":100,"sourceCode":"\n/// Initializes a tracing subscriber for external Rust crate logging.\n///\n/// This sets up a standard tracing subscriber that outputs to stdout with\n/// the format controlled by `RUST_LOG` environment variable. The output\n/// format uses nanosecond timestamps to align with Nautilus logging.\n///\n/// # Environment Variables\n///\n/// - `RUST_LOG`: Controls which modules emit tracing events and at what level.\n///   - Example: `RUST_LOG=hyper=debug,tokio=warn`.\n///   - Default: `warn` (if not set).\n///\n/// # Errors\n///\n/// Returns an error if the tracing subscriber has already been initialized.\npub fn init_tracing() -> anyhow::Result<()> {\n    if TRACING_INITIALIZED.load(Ordering::SeqCst) {\n        anyhow::bail!(\"Tracing subscriber already initialized\");\n    }\n\n    let filter = EnvFilter::try_from_default_env().unwrap_or_else(|_| EnvFilter::new(\"warn\"));\n\n    let subscriber = tracing_subscriber::registry()\n        .with(filter)\n        .with(fmt::layer().event_format(NautilusFormatter));\n\n    // Install only the tracing subscriber here. Python logging manages the\n    // global `log` logger separately, so we must not claim it through\n    // SubscriberInitExt::try_init().\n    tracing::subscriber::set_global_default(subscriber)\n        .map_err(|e| anyhow::anyhow!(\"Failed to initialize tracing subscriber: {e}\"))?;\n\n    TRACING_INITIALIZED.store(true, Ordering::SeqCst);\n    Ok(())\n}\n","sourceCodeStart":82,"sourceCodeEnd":118,"githubUrl":"https://github.com/nautechsystems/nautilus_trader/blob/18893faf8b356be3320add8de2f861b0b647cf06/crates/common/src/logging/bridge.rs#L82-L118","documentation":"init_tracing installs the process-global tracing subscriber exactly once, guarded by the TRACING_INITIALIZED atomic flag. If the subscriber has already been initialized (flag set), calling init_tracing again returns this error rather than re-installing or silently no-oping, because a global subscriber can only be set once per process.","triggerScenarios":"Calling init_tracing twice in the same process — e.g. once in a library/runner bootstrap and again in application main; re-running initialization in tests that share a process; restarting a subsystem that calls init as part of its setup.","commonSituations":"Test binaries where each #[test] calls a common setup helper that calls init_tracing; embedding the library in an app that already configured its own tracing subscriber; retry logic that re-invokes initialization after an unrelated failure.","solutions":["Call init_tracing only once at process startup; propagate the Result and skip on this specific error if double-init is expected.","In tests, use a OnceGuard/OnceCell or an integration-test harness so only one test (or a shared once-guard) initializes tracing.","If the host application already set a subscriber, remove the library-side init call instead of calling init_tracing."],"exampleFix":"// before\nsetup()?; // calls init_tracing every time\ninit_tracing()?;\n// after\nstatic INIT: Once = Once::new();\nINIT.call_once(|| {\n    if let Err(e) = init_tracing() {\n        eprintln!(\"tracing init skipped: {e}\");\n    }\n});","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"// rust\nmatch init_tracing() {\n    Ok(()) => tracing::info!(\"tracing initialized\"),\n    Err(e) if e.to_string() == \"Tracing subscriber already initialized\" => {\n        // expected in tests / multi-bootstrap: safe to ignore\n    }\n    Err(e) => return Err(e.into()),\n}","preventionTips":["Initialize tracing exactly once in process main, not inside libraries or per-test helpers.","Wrap init in std::sync::Once or a OnceLock so repeated calls are impossible.","In test suites, use a shared harness guarded by Once instead of calling init_tracing per test.","If embedding in an app with its own subscriber, make library tracing init opt-in via config."],"tags":["rust","tracing","logging","double-initialization"],"backgroundTag":"invalid-state-transition","analyzedSha":"18893faf8b356be3320add8de2f861b0b647cf06","analyzedAt":"2026-09-08T20:49:34.690Z","contentChangedAt":"2026-09-08T20:49:34.690Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}