1use std::net::SocketAddr;
8use std::sync::Arc;
9use std::time::Duration;
10
11use async_trait::async_trait;
12use memory_stats::memory_stats;
13use metrics::histogram;
14use metrics_exporter_prometheus::PrometheusBuilder;
15use tokio::sync::RwLock;
16use tokio::time::sleep;
17
18use crate::{database, vm, LongLivedService, Network};
19
20#[derive(Default)]
21pub struct TelemetrySrv {
22 addr: Option<String>,
23}
24
25#[async_trait]
26impl<N: Network, DB: database::DB, VM: vm::VMExecution>
27 LongLivedService<N, DB, VM> for TelemetrySrv
28{
29 fn name(&self) -> &'static str {
31 "telemetry"
32 }
33
34 async fn execute(
36 &mut self,
37 network: Arc<RwLock<N>>,
38 _: Arc<RwLock<DB>>,
39 _: Arc<RwLock<VM>>,
40 ) -> anyhow::Result<usize> {
41 if let Some(addr) = &self.addr {
44 let addr = addr.parse::<SocketAddr>()?;
45 let (recorder, exporter) =
46 PrometheusBuilder::new().with_http_listener(addr).build()?;
47 metrics::set_global_recorder(recorder)?;
48 tokio::spawn(exporter);
49
50 loop {
51 sleep(Duration::from_secs(5)).await;
52 if let Some(usage) = memory_stats() {
54 histogram!("dusk_physical_mem")
55 .record(usage.physical_mem as f64);
56 histogram!("dusk_virtual_mem")
57 .record(usage.virtual_mem as f64);
58 }
59
60 let count = network.read().await.alive_nodes_count().await;
62 histogram!("dusk_kadcast_peers").record(count as f64);
63 }
64 }
65 Ok(0)
66 }
67}
68
69impl TelemetrySrv {
70 pub fn new(addr: Option<String>) -> Self {
71 Self { addr }
72 }
73}