Skip to main content

provide_telemetry/
setup.rs

1// SPDX-FileCopyrightText: Copyright (C) 2026 provide.io llc
2// SPDX-License-Identifier: Apache-2.0
3// SPDX-Comment: Part of provide-telemetry.
4//
5
6use std::sync::{Mutex, OnceLock};
7
8use crate::config::TelemetryConfig;
9use crate::errors::TelemetryError;
10use crate::otel::{setup_otel, shutdown_otel};
11use crate::runtime::{get_runtime_config, set_active_config};
12
13#[derive(Clone, Copy, Debug, Default)]
14struct SetupState {
15    done: bool,
16}
17
18static SETUP_STATE: OnceLock<Mutex<SetupState>> = OnceLock::new();
19
20fn setup_state() -> &'static Mutex<SetupState> {
21    SETUP_STATE.get_or_init(|| Mutex::new(SetupState::default()))
22}
23
24pub fn setup_telemetry() -> Result<TelemetryConfig, TelemetryError> {
25    let mut state = setup_state().lock().expect("setup state lock poisoned");
26    if state.done {
27        return get_runtime_config()
28            .ok_or_else(|| TelemetryError::new("telemetry setup state is inconsistent"));
29    }
30
31    let config = TelemetryConfig::from_env().map_err(|err| TelemetryError::new(err.message))?;
32    setup_otel(&config)?;
33    set_active_config(Some(config.clone()));
34    state.done = true;
35    Ok(config)
36}
37
38pub fn shutdown_telemetry() -> Result<(), TelemetryError> {
39    let mut state = setup_state().lock().expect("setup state lock poisoned");
40    state.done = false;
41    shutdown_otel();
42    set_active_config(None);
43    Ok(())
44}