use std::time::Duration;
use opentelemetry::KeyValue;
use opentelemetry::metrics::{Histogram, Meter};
use opentelemetry_semantic_conventions::metric;
#[derive(Debug, Clone)]
pub(crate) struct Metrics {
duration: Histogram<f64>,
returned_rows: Histogram<f64>,
affected_rows: Histogram<f64>,
}
impl Metrics {
pub fn new() -> Self {
let meter: Meter = opentelemetry::global::meter("sqlx-otel");
let duration = meter
.f64_histogram(metric::DB_CLIENT_OPERATION_DURATION)
.with_unit("s")
.with_description("Duration of database client operations.")
.build();
let returned_rows = meter
.f64_histogram(metric::DB_CLIENT_RESPONSE_RETURNED_ROWS)
.with_description("Number of rows returned by database operations.")
.build();
let affected_rows = meter
.f64_histogram("db.client.response.affected_rows")
.with_description("Number of rows affected by database operations.")
.build();
Self {
duration,
returned_rows,
affected_rows,
}
}
pub fn record(
&self,
elapsed: Duration,
returned_rows: Option<u64>,
affected_rows: Option<u64>,
attributes: &[KeyValue],
) {
self.duration.record(elapsed.as_secs_f64(), attributes);
if let Some(count) = returned_rows {
#[allow(clippy::cast_precision_loss)]
self.returned_rows.record(count as f64, attributes);
}
if let Some(count) = affected_rows {
#[allow(clippy::cast_precision_loss)]
self.affected_rows.record(count as f64, attributes);
}
}
}