use std::collections::HashMap;
use prometheus_client::{
encoding::{DescriptorEncoder, EncodeMetric},
metrics::{counter::ConstCounter, gauge::ConstGauge, info::Info},
registry::{Registry, Unit},
};
pub trait EncodeExt {
fn encode_e(
&self,
encoder: &mut DescriptorEncoder,
name: &str,
help: &str,
) -> Result<(), std::fmt::Error>;
fn encode_e_unit(
&self,
encoder: &mut DescriptorEncoder,
name: &str,
help: &str,
unit: &Unit,
) -> Result<(), std::fmt::Error>;
}
impl<T> EncodeExt for T
where
T: EncodeMetric,
{
fn encode_e(
&self,
encoder: &mut DescriptorEncoder,
name: &str,
help: &str,
) -> Result<(), std::fmt::Error> {
self.encode(encoder.encode_descriptor(name, help, None, self.metric_type())?)
}
fn encode_e_unit(
&self,
encoder: &mut DescriptorEncoder,
name: &str,
help: &str,
unit: &Unit,
) -> Result<(), std::fmt::Error> {
self.encode(encoder.encode_descriptor(name, help, Some(unit), self.metric_type())?)
}
}
pub(crate) trait AsMetrics {
fn register_as_metrics(self: Box<Self>, registry: &mut Registry);
}
pub fn encode_extra(
encoder: &mut DescriptorEncoder,
extra: &HashMap<String, String>,
mut info_fields: Vec<(String, String)>,
blacklist: &[&str],
) -> Result<(), std::fmt::Error> {
for (key, val) in extra
.iter()
.filter(|(k, _)| !blacklist.contains(&&***k))
.map(|(k, v)| (k.replace('-', "_"), v))
{
if let Ok(num) = val.parse::<f64>() {
if key.ends_with("_packet") || key.ends_with("_drop") || key.ends_with("byte") {
ConstCounter::new(num).encode_e(encoder, &key, "")?;
} else {
ConstGauge::new(num).encode_e(encoder, &key, "")?;
}
continue;
}
if let Ok(bool) = val.parse::<bool>() {
ConstGauge::new(i64::from(bool)).encode_e(encoder, &key, "")?;
continue;
}
info_fields.push((key, val.clone()));
}
Info::new(info_fields).encode_e(encoder, "", "")?;
Ok(())
}