coerce 0.8.11

Async actor runtime and distributed systems framework
Documentation
use crate::remote::api::Routes;
use crate::remote::system::{NodeId, RemoteActorSystem};

use axum::response::IntoResponse;
use axum::routing::get;
use axum::Router;
use metrics_exporter_prometheus::{BuildError, PrometheusBuilder, PrometheusHandle};
use metrics_util::MetricKindMask;

use std::time::Duration;

pub struct MetricsApi {
    recorder_handle: PrometheusHandle,
}

impl From<PrometheusHandle> for MetricsApi {
    fn from(recorder_handle: PrometheusHandle) -> Self {
        Self { recorder_handle }
    }
}

impl MetricsApi {
    pub fn create(
        node_id: NodeId,
        node_tag: &str,
        cluster_name: Option<&str>,
    ) -> Result<Self, BuildError> {
        let prometheus_builder = PrometheusBuilder::new();

        let mut builder = prometheus_builder.idle_timeout(
            MetricKindMask::COUNTER | MetricKindMask::HISTOGRAM,
            Some(Duration::from_secs(60 * 30)),
        );

        if let Some(cluster_name) = cluster_name {
            builder = builder.add_global_label("cluster", cluster_name.to_string());
        }

        builder = builder
            .add_global_label("node_id", format!("{}", node_id))
            .add_global_label("node_tag", node_tag);

        let recorder = builder.install_recorder()?;
        Ok(Self {
            recorder_handle: recorder,
        })
    }

    pub fn new(system: RemoteActorSystem) -> Result<MetricsApi, BuildError> {
        let node_id = system.node_id();
        let node_tag = system.node_tag();
        let cluster_name = system
            .config()
            .get_attributes()
            .get("cluster")
            .map(|s| s.as_ref());

        Self::create(node_id, node_tag, cluster_name)
    }
}

impl Routes for MetricsApi {
    fn routes(&self, router: Router) -> Router {
        router.route("/metrics", {
            let handle = self.recorder_handle.clone();

            get(|| async move {
                let handle = handle;
                handle.render().into_response()
            })
        })
    }
}