scouter_sql/sql/traits/
observability.rs1use crate::sql::query::Queries;
2use crate::sql::schema::ObservabilityResult;
3
4use crate::sql::error::SqlError;
5use scouter_types::TimeInterval;
6use scouter_types::{ObservabilityMetricRequest, ObservabilityMetrics};
7
8use sqlx::{postgres::PgQueryResult, Pool, Postgres};
9
10use async_trait::async_trait;
11
12#[async_trait]
13pub trait ObservabilitySqlLogic {
14 async fn insert_observability_record(
22 pool: &Pool<Postgres>,
23 record: &ObservabilityMetrics,
24 ) -> Result<PgQueryResult, SqlError> {
25 let query = Queries::InsertObservabilityRecord.get_query();
26 let route_metrics = serde_json::to_value(&record.route_metrics)?;
27
28 sqlx::query(&query.sql)
29 .bind(&record.space)
30 .bind(&record.name)
31 .bind(&record.version)
32 .bind(record.request_count)
33 .bind(record.error_count)
34 .bind(route_metrics)
35 .execute(pool)
36 .await
37 .map_err(SqlError::SqlxError)
38 }
39
40 async fn get_binned_observability_metrics(
41 pool: &Pool<Postgres>,
42 params: &ObservabilityMetricRequest,
43 ) -> Result<Vec<ObservabilityResult>, SqlError> {
44 let query = Queries::GetBinnedObservabilityMetrics.get_query();
45
46 let time_interval = TimeInterval::from_string(¶ms.time_interval).to_minutes();
47
48 let bin = time_interval as f64 / params.max_data_points as f64;
49
50 sqlx::query_as(&query.sql)
51 .bind(bin)
52 .bind(time_interval)
53 .bind(¶ms.name)
54 .bind(¶ms.space)
55 .bind(¶ms.version)
56 .fetch_all(pool)
57 .await
58 .map_err(SqlError::SqlxError)
59 }
60}