linkrs_metrics/manager/
query_metrics.rs1use serde::{Deserialize, Serialize};
3use std::sync::Arc;
4
5use crate::metrics::QueryMetrics;
6
7use super::core::StatsManager;
8use super::metric_type::MetricType;
9use super::metric_value::MetricValue;
10
11#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
13pub struct QueryLatencySnapshot {
14 pub count: usize,
15 pub avg_us: u64,
16 pub p50_us: u64,
17 pub p95_us: u64,
18 pub p99_us: u64,
19}
20
21impl StatsManager {
22 pub fn record_query_metrics(&self, metrics: &QueryMetrics) {
23 {
26 let mut last_metrics = self.last_query_metrics.write();
27 *last_metrics = Some(metrics.clone());
28 }
29 {
30 let mut history = self.query_metrics_history.write();
31 if history.len() >= 1000 {
32 history.pop_front();
33 }
34 history.push_back(metrics.clone());
35 }
36
37 {
39 let mut histogram = self.query_latency_histogram.write();
40 histogram.record_micros(metrics.total_time_us);
41 }
42
43 let updates = [
46 (MetricType::QueryParseTimeUs, metrics.parse_time_us),
47 (MetricType::QueryValidateTimeUs, metrics.validate_time_us),
48 (MetricType::QueryPlanTimeUs, metrics.plan_time_us),
49 (MetricType::QueryOptimizeTimeUs, metrics.optimize_time_us),
50 (MetricType::QueryExecuteTimeUs, metrics.execute_time_us),
51 (MetricType::QueryTotalTimeUs, metrics.total_time_us),
52 (
53 MetricType::QueryPlanNodeCount,
54 metrics.plan_node_count as u64,
55 ),
56 (
57 MetricType::QueryResultRowCount,
58 metrics.result_row_count as u64,
59 ),
60 ];
61
62 for (metric_type, value) in updates {
63 let metric = self
64 .metrics
65 .entry(metric_type)
66 .or_insert_with(|| Arc::new(MetricValue::new(0)));
67 metric.add(value);
68 }
69 self.add_value(MetricType::NumQueries);
70 }
71
72 pub fn get_latency_percentiles(&self) -> (u64, u64, u64, u64) {
74 let histogram = self.query_latency_histogram.read();
75 (
76 histogram.avg(),
77 histogram.p50(),
78 histogram.p95(),
79 histogram.p99(),
80 )
81 }
82
83 pub fn query_latency_snapshot(&self) -> QueryLatencySnapshot {
84 let histogram = self.query_latency_histogram.read();
85 QueryLatencySnapshot {
86 count: histogram.count(),
87 avg_us: histogram.avg(),
88 p50_us: histogram.p50(),
89 p95_us: histogram.p95(),
90 p99_us: histogram.p99(),
91 }
92 }
93
94 pub fn get_search_latency_percentiles(&self) -> (u64, u64, u64, u64) {
96 let histogram = self.search_latency_histogram.read();
97 (
98 histogram.avg(),
99 histogram.p50(),
100 histogram.p95(),
101 histogram.p99(),
102 )
103 }
104
105 pub fn get_latency_report(&self) -> String {
107 let histogram = self.query_latency_histogram.read();
108 histogram.report()
109 }
110
111 pub fn clear_latency_histogram(&self) {
113 let mut histogram = self.query_latency_histogram.write();
114 histogram.clear();
115 }
116
117 pub fn get_last_query_metrics(&self) -> Option<QueryMetrics> {
118 let last_metrics = self.last_query_metrics.read();
119 last_metrics.clone()
120 }
121
122 pub fn get_query_metrics_history(&self) -> Vec<QueryMetrics> {
124 self.query_metrics_history.read().iter().cloned().collect()
125 }
126
127 pub fn get_query_metrics(&self) -> Option<QueryMetrics> {
128 self.get_last_query_metrics()
129 }
130}