diff --git a/src/endpoints.rs b/src/endpoints.rs index fe2104f..0268cf3 100644 --- a/src/endpoints.rs +++ b/src/endpoints.rs @@ -3,14 +3,28 @@ use axum::{ response::IntoResponse, http }; -use tracing_subscriber::field::debug; use crate::structs::v3::PrometheusMetrics; -use prometheus::{ Encoder, Gauge, Registry, TextEncoder}; -use std::sync::{ Arc, MutexGuard }; +use prometheus::{ core::Collector, Encoder, Gauge, Registry, TextEncoder}; +use std::{cell::RefCell, rc::Rc, sync::{ Arc, MutexGuard }}; use crate::AppState; use tracing::{ debug, error, info, warn, trace }; use crate::metrics::{MetricsProcesser, MetricsValueType}; +struct BoxCollectorProducer { + inner : *mut dyn Collector, +} + +impl BoxCollectorProducer { + pub fn new(target: Box) -> Self { + Self { + inner : Box::into_raw(target) + } + } + pub fn new_box(&self) -> Box { + unsafe { Box::from_raw(self.inner) } + } +} + /// An `Update` endpoint /// /// Used to registrate new metrics and to update already @@ -115,14 +129,17 @@ pub async fn metrics_handler(State(state): State>) -> String { /// `Registry` /// pub fn update_or_insert_metric<'a>( - metric: Gauge, + metric: Box, registry: MutexGuard<'a, Registry>, metric_name: &str ) -> anyhow::Result<()> { trace!("fn update_or_insert_metric is running"); use prometheus::Error; // let mut counter = 0; - match registry.register(Box::new(metric.clone())) { + // let ptr = Box::into_raw(metric); + let prod = BoxCollectorProducer::new(metric); + + match registry.register(prod.new_box()) { Ok(_) => { info!("Metric `{}` was registered!", metric_name); }, @@ -131,9 +148,9 @@ pub fn update_or_insert_metric<'a>( match er { Error::AlreadyReg => { trace!("processing already regged metric"); - match registry.unregister(Box::new(metric.clone())) { + match registry.unregister(prod.new_box()) { Ok(_) => { - if let Err(er) = registry.register(Box::new(metric)) { + if let Err(er) = registry.register(prod.new_box()) { warn!("Cannot update metric `{}`", metric_name); return Err(anyhow::Error::msg( format!("Cannot update metric `{}` due to {}", metric_name, er) diff --git a/src/main.rs b/src/main.rs index a424e45..02b6fb1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,6 +27,8 @@ struct AppState { #[tokio::main] async fn main() -> anyhow::Result<()> { + dotenv().ok(); + let log_level = std::env::var("PROMETHEUS_EXPORTER_LOG_LEVEL") .unwrap_or_else(|_| "INFO".to_owned()); @@ -41,7 +43,6 @@ async fn main() -> anyhow::Result<()> { .init(); info!("Loading env vars from .env if exists ..."); - dotenv().ok(); info!("Initializing local Prometehus metrics registry ..."); let registry = Registry::new(); diff --git a/src/metrics.rs b/src/metrics.rs index bc53f63..d561a6f 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -1,10 +1,11 @@ +use std::sync::Arc; + use crate::structs::v3::MetricOutput; -use serde::de; use serde_json::{Map, Value}; use prometheus::Gauge; use tracing::error; use prometheus::Opts; -use prometheus::GaugeVec; +use prometheus::{opts, GaugeVec, core::Collector}; use tracing::{debug, trace}; #[derive(Debug)] @@ -20,7 +21,6 @@ pub struct MetricsProcesser; impl MetricsProcesser { - pub fn get_type_of_value(metrics: &MetricOutput) -> MetricsValueType { trace!("defining metric type"); if Self::is_number(metrics) { @@ -48,8 +48,14 @@ impl MetricsProcesser { metric: &MetricOutput, metric_name: &str, metric_desc: &str - ) -> Option { + ) -> Option> { trace!("fn gauge_from_number is running"); + if let Some(status) = metric.status { + let vec = GaugeVec::new(opts!(metric_name, metric_desc), &["status"]).unwrap(); + vec.with_label_values(&[&status.to_string()]).set(metric.value.as_f64().unwrap_or_else(|| 0.0)); + return Some(Box::new(vec)); + } + let gauge = Gauge::new( metric_name, metric_desc @@ -57,10 +63,6 @@ impl MetricsProcesser { match gauge { Ok(gauge) => { - // let value = metric.value.as_number().unwrap_or({ - // error!("Cannot convert {} metric value to f64 type. Value was set to 0.0", &metric_name); - // }); - // let value = value.as_f64() let val = match metric.value.as_number() { Some(val) => { val.as_f64().unwrap_or_else(|| @@ -74,7 +76,7 @@ impl MetricsProcesser { }; gauge.set(val); debug!("processed metric: {:?}", &gauge); - return Some(gauge); + return Some(Box::new(gauge)); }, Err(er) => error!("Cannot create Gauge metric {} due to {}", &metric_name, er), }