use std::{collections::BTreeMap, fmt::Write};
use super::{DurationMetricValue, escape_label, write_duration_metric};
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub struct SqlMetricLabels {
pub db_kind: String,
pub repository: String,
pub method: String,
pub operation: String,
pub result: String,
}
impl SqlMetricLabels {
pub fn new(
db_kind: impl Into<String>,
repository: impl Into<String>,
method: impl Into<String>,
operation: impl Into<String>,
result: impl Into<String>,
) -> Self {
Self {
db_kind: db_kind.into(),
repository: repository.into(),
method: method.into(),
operation: operation.into(),
result: result.into(),
}
}
}
pub(crate) fn render(
output: &mut String,
metrics: &BTreeMap<SqlMetricLabels, DurationMetricValue>,
) {
output.push_str("# HELP rs_zero_sql_queries_total Total number of SQL queries.\n");
output.push_str("# TYPE rs_zero_sql_queries_total counter\n");
for (labels, value) in metrics {
write!(output, "rs_zero_sql_queries_total{{").ok();
write_labels(output, labels, None);
writeln!(output, "}} {}", value.count).ok();
}
output.push_str("# HELP rs_zero_sql_query_errors_total Total number of failed SQL queries.\n");
output.push_str("# TYPE rs_zero_sql_query_errors_total counter\n");
for (labels, value) in metrics
.iter()
.filter(|(labels, _)| labels.result != "success")
{
write!(output, "rs_zero_sql_query_errors_total{{").ok();
write_labels(output, labels, None);
writeln!(output, "}} {}", value.count).ok();
}
output.push_str("# HELP rs_zero_sql_query_duration_seconds SQL query duration.\n");
output.push_str("# TYPE rs_zero_sql_query_duration_seconds histogram\n");
for (labels, value) in metrics {
write_duration_metric(
output,
"rs_zero_sql_query_duration_seconds",
labels,
value,
write_labels,
);
}
}
fn write_labels(output: &mut String, labels: &SqlMetricLabels, le: Option<&str>) {
write!(
output,
"db_kind=\"{}\",repository=\"{}\",method=\"{}\",operation=\"{}\",result=\"{}\"",
escape_label(&labels.db_kind),
escape_label(&labels.repository),
escape_label(&labels.method),
escape_label(&labels.operation),
escape_label(&labels.result)
)
.ok();
if let Some(le) = le {
write!(output, ",le=\"{}\"", escape_label(le)).ok();
}
}