use std::{collections::BTreeMap, fmt::Write};
use super::{DurationMetricValue, escape_label, write_duration_metric};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct HttpMetricLabels {
pub method: String,
pub route: String,
pub status: u16,
}
impl HttpMetricLabels {
pub fn new(method: impl Into<String>, route: impl Into<String>, status: u16) -> Self {
Self {
method: method.into(),
route: route.into(),
status,
}
}
}
pub(crate) fn render(
output: &mut String,
metrics: &BTreeMap<HttpMetricLabels, DurationMetricValue>,
in_flight: i64,
) {
output.push_str("# HELP rs_zero_http_requests_total Total number of HTTP requests.\n");
output.push_str("# TYPE rs_zero_http_requests_total counter\n");
for (labels, value) in metrics {
write!(output, "rs_zero_http_requests_total{{").ok();
write_labels(output, labels, None);
writeln!(output, "}} {}", value.count).ok();
}
output.push_str("# HELP rs_zero_http_request_duration_seconds HTTP request duration.\n");
output.push_str("# TYPE rs_zero_http_request_duration_seconds histogram\n");
for (labels, value) in metrics {
write_duration_metric(
output,
"rs_zero_http_request_duration_seconds",
labels,
value,
write_labels,
);
}
output.push_str("# HELP rs_zero_http_requests_in_flight Current in-flight HTTP requests.\n");
output.push_str("# TYPE rs_zero_http_requests_in_flight gauge\n");
writeln!(output, "rs_zero_http_requests_in_flight {in_flight}").ok();
}
fn write_labels(output: &mut String, labels: &HttpMetricLabels, le: Option<&str>) {
write!(
output,
"method=\"{}\",route=\"{}\",status=\"{}\"",
escape_label(&labels.method),
escape_label(&labels.route),
labels.status
)
.ok();
if let Some(le) = le {
write!(output, ",le=\"{}\"", escape_label(le)).ok();
}
}