Skip to main content

dr_metrix_core/
collector.rs

1use std::collections::HashMap;
2use std::sync::Arc;
3use std::time::Duration;
4
5use async_trait::async_trait;
6use tokio::task::JoinHandle;
7use tokio::time::MissedTickBehavior;
8
9use crate::error::Result;
10
11pub struct CollectorConfig {
12    pub namespace: String,
13    pub collect_interval: Duration,
14    pub const_labels: HashMap<String, String>,
15}
16
17impl Default for CollectorConfig {
18    fn default() -> Self {
19        Self {
20            namespace: String::new(),
21            collect_interval: Duration::from_secs(15),
22            const_labels: HashMap::new(),
23        }
24    }
25}
26
27impl Clone for CollectorConfig {
28    fn clone(&self) -> Self {
29        Self {
30            namespace: self.namespace.clone(),
31            collect_interval: self.collect_interval,
32            const_labels: self.const_labels.clone(),
33        }
34    }
35}
36
37#[async_trait]
38pub trait MetricsCollector: Send + Sync + 'static {
39    fn name(&self) -> &'static str;
40    fn register(&self, registry: &prometheus::Registry) -> Result<()>;
41    async fn collect(&self) -> Result<()>;
42
43    fn spawn_collect_loop(self: Arc<Self>, interval: Duration) -> JoinHandle<()> {
44        tokio::spawn(async move {
45            let mut ticker = tokio::time::interval(interval);
46            ticker.set_missed_tick_behavior(MissedTickBehavior::Delay);
47            loop {
48                ticker.tick().await;
49                if let Err(e) = self.collect().await {
50                    tracing::warn!(
51                        collector = self.name(),
52                        error = %e,
53                        "collector error"
54                    );
55                }
56            }
57        })
58    }
59}