use crossbeam_channel::{bounded, Sender};
use std::sync::Arc;
use parking_lot::RwLock;
use crate::metrics::Metrics;
pub trait MetricsExporter: Send + Sync {
fn export(&self, metrics: &Metrics);
}
pub struct MetricsExporterManager {
sender: Sender<Metrics>,
}
impl MetricsExporterManager {
pub fn new(buffer_size: usize, exporters: Vec<Box<dyn MetricsExporter>>) -> Arc<Self> {
let (sender, receiver) = bounded(buffer_size);
let exporters = Arc::new(RwLock::new(exporters));
std::thread::spawn(move || {
while let Ok(metrics) = receiver.recv() {
let exporters = exporters.read();
for exporter in exporters.iter() {
exporter.export(&metrics);
}
}
});
Arc::new(Self { sender })
}
pub fn send_metrics(&self, metrics: Metrics) {
if let Err(_) = self.sender.try_send(metrics) {
eprintln!("Failed to send metrics.");
}
}
}
pub static METRICS_EXPORTER_MANAGER: once_cell::sync::Lazy<RwLock<Option<Arc<MetricsExporterManager>>>> =
once_cell::sync::Lazy::new(|| RwLock::new(None));