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