{"record":{"id":"854cac97ac10208f","repo":"quickwit-oss/quickwit","slug":"failed-to-install-global-metrics-recorder","errorCode":null,"errorMessage":"failed to install global metrics recorder","messagePattern":"failed to install global metrics recorder","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"quickwit/quickwit-telemetry-exporters/src/metrics.rs","lineNumber":45,"sourceCode":"    let prometheus_recorder = crate::prometheus::metrics::build_recorder()?;\n\n    let (recorder, meter_provider) = if otlp_config.is_enabled() {\n        let (otlp_recorder, meter_provider) =\n            crate::otlp::metrics::build_recorder(service_version, otlp_config)?;\n        let recorder = FanoutBuilder::default()\n            .add_recorder(prometheus_recorder)\n            .add_recorder(otlp_recorder)\n            .build();\n        (recorder, Some(meter_provider))\n    } else {\n        let recorder = FanoutBuilder::default()\n            .add_recorder(prometheus_recorder)\n            .build();\n        (recorder, None)\n    };\n\n    metrics::set_global_recorder(recorder)\n        .map_err(|_| anyhow::anyhow!(\"failed to install global metrics recorder\"))?;\n    quickwit_metrics::describe_metrics();\n\n    Ok(meter_provider)\n}\n","sourceCodeStart":27,"sourceCodeEnd":50,"githubUrl":"https://github.com/quickwit-oss/quickwit/blob/a39730c5cdcd1a4fe798403737ae293999ea21f8/quickwit/quickwit-telemetry-exporters/src/metrics.rs#L27-L50","documentation":"init_metrics_provider builds a metrics recorder (Prometheus or OTLP-backed) and installs it as the process-wide global recorder via metrics::set_global_recorder. The metrics crate allows only ONE global recorder per process; if set_global_recorder returns Err, installation failed and Quickwit aborts startup with this anyhow error.","triggerScenarios":"Calling init_metrics_provider more than once in the same process (e.g. test harness calling it in multiple tests sharing a process, or double initialization in embedded usage); a recorder was already installed by another library before Quickwit init.","commonSituations":"Rust unit/integration tests that each call quickwit telemetry init in the same test binary; embedding quickwit as a library where the host app already set a global metrics recorder; duplicated init in CLI bootstrap paths.","solutions":["Ensure init_metrics_provider is called exactly once per process","In tests, guard initialization with OnceLock/Once so only the first call installs the recorder","If embedding Quickwit, reuse the host's recorder setup or skip Quickwit's global recorder init"],"exampleFix":"// before\nstatic INIT: OnceLock<()> = OnceLock::new();\nfn setup() { init_metrics_provider().unwrap(); }\n// after\nstatic INIT: OnceLock<()> = OnceLock::new();\nfn setup() { INIT.get_or_init(|| init_metrics_provider().unwrap()); }","handlingStrategy":"validation","validationCode":"// Rust: only init once per process\nstatic METRICS_INIT: OnceLock<MeterProvider> = OnceLock::new();\nfn provider() -> &MeterProvider { METRICS_INIT.get_or_init(|| init_metrics_provider().expect(\"metrics init\")) }","typeGuard":null,"tryCatchPattern":"init_metrics_provider().map_err(|e| {\n    if e.to_string().contains(\"already\") { /* recorder already installed - proceed */ }\n    else { bail!(e) }\n})?;","preventionTips":["Call init_metrics_provider exactly once per process","In tests use OnceLock/Once around initialization","Check whether the host application already installed a global metrics recorder before embedding Quickwit"],"tags":["metrics","initialization","global-state"],"backgroundTag":"module-init-failed","analyzedSha":"a39730c5cdcd1a4fe798403737ae293999ea21f8","analyzedAt":"2026-09-08T13:19:37.784Z","contentChangedAt":"2026-09-08T13:19:37.784Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}