mpl_proxy/
metrics.rs

1//! Metrics collection for the proxy
2
3use std::sync::atomic::{AtomicU64, Ordering};
4
5/// Thread-safe metrics state
6pub struct MetricsState {
7    pub requests_total: AtomicU64,
8    pub schema_pass: AtomicU64,
9    pub schema_fail: AtomicU64,
10    pub qom_pass: AtomicU64,
11    pub qom_fail: AtomicU64,
12    pub handshakes: AtomicU64,
13    pub downgrades: AtomicU64,
14}
15
16impl MetricsState {
17    /// Create a new metrics state
18    pub fn new() -> Self {
19        Self {
20            requests_total: AtomicU64::new(0),
21            schema_pass: AtomicU64::new(0),
22            schema_fail: AtomicU64::new(0),
23            qom_pass: AtomicU64::new(0),
24            qom_fail: AtomicU64::new(0),
25            handshakes: AtomicU64::new(0),
26            downgrades: AtomicU64::new(0),
27        }
28    }
29
30    /// Increment total requests
31    pub fn inc_requests(&self) {
32        self.requests_total.fetch_add(1, Ordering::Relaxed);
33    }
34
35    /// Increment schema pass count
36    pub fn inc_schema_pass(&self) {
37        self.schema_pass.fetch_add(1, Ordering::Relaxed);
38    }
39
40    /// Increment schema fail count
41    pub fn inc_schema_fail(&self) {
42        self.schema_fail.fetch_add(1, Ordering::Relaxed);
43    }
44
45    /// Increment QoM pass count
46    pub fn inc_qom_pass(&self) {
47        self.qom_pass.fetch_add(1, Ordering::Relaxed);
48    }
49
50    /// Increment QoM fail count
51    pub fn inc_qom_fail(&self) {
52        self.qom_fail.fetch_add(1, Ordering::Relaxed);
53    }
54
55    /// Increment handshake count
56    pub fn inc_handshakes(&self) {
57        self.handshakes.fetch_add(1, Ordering::Relaxed);
58    }
59
60    /// Increment downgrade count
61    pub fn inc_downgrades(&self) {
62        self.downgrades.fetch_add(1, Ordering::Relaxed);
63    }
64
65    /// Calculate schema pass rate
66    pub fn schema_pass_rate(&self) -> f64 {
67        let pass = self.schema_pass.load(Ordering::Relaxed);
68        let fail = self.schema_fail.load(Ordering::Relaxed);
69        let total = pass + fail;
70        if total == 0 {
71            1.0
72        } else {
73            pass as f64 / total as f64
74        }
75    }
76
77    /// Calculate QoM pass rate
78    pub fn qom_pass_rate(&self) -> f64 {
79        let pass = self.qom_pass.load(Ordering::Relaxed);
80        let fail = self.qom_fail.load(Ordering::Relaxed);
81        let total = pass + fail;
82        if total == 0 {
83            1.0
84        } else {
85            pass as f64 / total as f64
86        }
87    }
88
89    /// Calculate downgrade rate
90    pub fn downgrade_rate(&self) -> f64 {
91        let downgrades = self.downgrades.load(Ordering::Relaxed);
92        let handshakes = self.handshakes.load(Ordering::Relaxed);
93        if handshakes == 0 {
94            0.0
95        } else {
96            downgrades as f64 / handshakes as f64
97        }
98    }
99}
100
101impl Default for MetricsState {
102    fn default() -> Self {
103        Self::new()
104    }
105}