kubert 0.25.0

Kubernetes runtime helpers. Based on kube-rs.
use super::*;
use hyper::header;

#[derive(Clone, Debug)]
pub(super) struct Prometheus {
    registry: Arc<prometheus_client::registry::Registry>,
}

impl Prometheus {
    pub(super) fn new(reg: prometheus_client::registry::Registry) -> Self {
        Self {
            registry: reg.into(),
        }
    }

    pub(super) fn handle_metrics(&self, req: Request) -> Response {
        if !matches!(*req.method(), hyper::Method::GET | hyper::Method::HEAD) {
            return hyper::Response::builder()
                .status(hyper::StatusCode::METHOD_NOT_ALLOWED)
                .header(header::ALLOW, "GET, HEAD")
                .body(Body::default())
                .unwrap();
        }

        let body = match self.encode_body() {
            Ok(body) => body,
            Err(error) => {
                tracing::error!(%error, "Failed to encode metrics");
                return hyper::Response::builder()
                    .status(hyper::StatusCode::INTERNAL_SERVER_ERROR)
                    .body(Body::default())
                    .unwrap();
            }
        };

        const OPENMETRICS_CONTENT_TYPE: &str =
            "application/openmetrics-text; version=1.0.0; charset=utf-8";
        hyper::Response::builder()
            .status(hyper::StatusCode::OK)
            .header(header::CONTENT_TYPE, OPENMETRICS_CONTENT_TYPE)
            .body(body)
            .expect("response must be valid")
    }

    fn encode_body(&self) -> std::result::Result<super::Body, std::fmt::Error> {
        let mut buf = String::with_capacity(16 * 1024);
        prometheus_client::encoding::text::encode(&mut buf, &self.registry)?;
        Ok(super::Body::new(buf.into()))
    }
}