use std::{
mem,
sync::{Arc, LazyLock, RwLock},
};
use crate::{
error::{ErrorKind, GlobalTelemetryProviderError},
provider::{GlobalTelemetryProvider, TelemetryProvider},
ObservabilityError,
};
static GLOBAL_TELEMETRY_PROVIDER: LazyLock<RwLock<GlobalTelemetryProvider>> =
LazyLock::new(|| RwLock::new(GlobalTelemetryProvider::new(TelemetryProvider::default())));
pub fn set_telemetry_provider(new_provider: TelemetryProvider) -> Result<(), ObservabilityError> {
if let Ok(mut old_provider) = GLOBAL_TELEMETRY_PROVIDER.try_write() {
let new_global_provider = GlobalTelemetryProvider::new(new_provider);
let _ = mem::replace(&mut *old_provider, new_global_provider);
Ok(())
} else {
Err(ObservabilityError::new(
ErrorKind::Other,
GlobalTelemetryProviderError::new("Failed to set global TelemetryProvider."),
))
}
}
pub fn get_telemetry_provider() -> Result<Arc<TelemetryProvider>, ObservabilityError> {
if let Ok(tp) = GLOBAL_TELEMETRY_PROVIDER.try_read() {
Ok(tp.telemetry_provider().clone())
} else {
Err(ObservabilityError::new(
ErrorKind::Other,
GlobalTelemetryProviderError::new("Failed to get global TelemetryProvider"),
))
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::provider::TelemetryProvider;
use serial_test::serial;
#[test]
#[serial]
fn can_set_global_telemetry_provider() {
let my_provider = TelemetryProvider::default();
set_telemetry_provider(my_provider).unwrap();
}
#[test]
#[serial]
fn can_get_global_telemetry_provider() {
let curr_provider = get_telemetry_provider().unwrap();
let curr_mp = curr_provider.meter_provider();
let curr_meter = curr_mp.get_meter("TestMeter", None);
let instrument = curr_meter
.create_monotonic_counter("TestMonoCounter")
.build();
instrument.add(4, None, None);
}
}