use prometheus::{
Encoder, Result,
proto::{MetricFamily, MetricType},
};
use serde_json::{Map, Value};
use std::io::Write;
#[derive(Debug, Default)]
pub struct HRT;
impl HRT {
#[must_use]
pub fn new() -> Self {
Self
}
}
impl Encoder for HRT {
fn encode<W: Write>(&self, metric_families: &[MetricFamily], writer: &mut W) -> Result<()> {
let mut map = Map::new();
for metric_family in metric_families {
let name = metric_family.name();
if metric_family.get_field_type() != MetricType::COUNTER {
continue;
}
let mut metrics = Vec::new();
for metric in metric_family.get_metric() {
let mut metric_map = Map::new();
let mut labels = Map::new();
for pair in metric.get_label() {
let (Some(name), Some(value)) = (pair.name.as_ref(), pair.value.as_ref())
else {
continue;
};
labels.insert(name.to_string(), Value::String(value.to_string()));
}
let Some(counter) = metric.get_counter().0.as_ref() else {
continue;
};
if let Some(counter) = counter.value {
metric_map.insert("labels".to_owned(), Value::Object(labels));
metric_map.insert(
"value".to_owned(),
Value::Number(serde_json::Number::from_f64(counter).unwrap()),
);
metrics.push(Value::Object(metric_map));
}
}
map.insert(name.to_owned(), Value::Array(metrics));
}
let result =
serde_json::to_vec(&map).map_err(|e| prometheus::Error::Msg(format!("{e}")))?;
writer.write_all(&result)?;
Ok(())
}
fn format_type(&self) -> &'static str {
"application/json"
}
}