use std::{fmt::Display, future::Future, time::Instant};
use tracing::Instrument;
use crate::observability::{MetricsRegistry, SqlMetricLabels};
pub async fn observe_sql_query<T, E, Fut>(
metrics: Option<&MetricsRegistry>,
db_kind: &str,
repository: &str,
method: &str,
operation: &str,
future: Fut,
) -> Result<T, E>
where
E: Display,
Fut: Future<Output = Result<T, E>>,
{
let started = Instant::now();
let span = tracing::debug_span!(
"rs_zero.sql.query",
db_kind = db_kind,
repository = repository,
method = method,
operation = operation,
result = tracing::field::Empty
);
let result = future.instrument(span.clone()).await;
let result_label = if result.is_ok() { "success" } else { "error" };
span.record("result", tracing::field::display(result_label));
if let Some(metrics) = metrics {
metrics.record_sql_query(
SqlMetricLabels::new(db_kind, repository, method, operation, result_label),
started.elapsed(),
);
}
result
}