use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use async_trait::async_trait;
use memory_stats::memory_stats;
use metrics::histogram;
use metrics_exporter_prometheus::PrometheusBuilder;
use tokio::sync::RwLock;
use tokio::time::sleep;
use crate::{database, vm, LongLivedService, Network};
#[derive(Default)]
pub struct TelemetrySrv {
addr: Option<String>,
}
#[async_trait]
impl<N: Network, DB: database::DB, VM: vm::VMExecution>
LongLivedService<N, DB, VM> for TelemetrySrv
{
fn name(&self) -> &'static str {
"telemetry"
}
async fn execute(
&mut self,
network: Arc<RwLock<N>>,
_: Arc<RwLock<DB>>,
_: Arc<RwLock<VM>>,
) -> anyhow::Result<usize> {
if let Some(addr) = &self.addr {
let addr = addr.parse::<SocketAddr>()?;
let (recorder, exporter) =
PrometheusBuilder::new().with_http_listener(addr).build()?;
metrics::set_global_recorder(recorder)?;
tokio::spawn(exporter);
loop {
sleep(Duration::from_secs(5)).await;
if let Some(usage) = memory_stats() {
histogram!("dusk_physical_mem")
.record(usage.physical_mem as f64);
histogram!("dusk_virtual_mem")
.record(usage.virtual_mem as f64);
}
let count = network.read().await.alive_nodes_count().await;
histogram!("dusk_kadcast_peers").record(count as f64);
}
}
Ok(0)
}
}
impl TelemetrySrv {
pub fn new(addr: Option<String>) -> Self {
Self { addr }
}
}