agentic_payments/system/
metrics.rs

1//! Performance metrics collection and monitoring
2
3use serde::{Deserialize, Serialize};
4use std::sync::atomic::{AtomicU64, Ordering};
5use std::sync::Arc;
6use std::time::Instant;
7
8/// System metrics
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Metrics {
11    /// Total number of verifications
12    pub total_verifications: u64,
13    /// Number of successful verifications
14    pub successful_verifications: u64,
15    /// Number of failed verifications
16    pub failed_verifications: u64,
17    /// Average verification time in microseconds
18    pub avg_verification_time_us: u64,
19    /// Total time spent in verification
20    pub total_verification_time_us: u64,
21    /// System uptime in seconds
22    pub uptime_seconds: u64,
23}
24
25impl Metrics {
26    /// Calculate success rate
27    pub fn success_rate(&self) -> f64 {
28        if self.total_verifications == 0 {
29            0.0
30        } else {
31            self.successful_verifications as f64 / self.total_verifications as f64
32        }
33    }
34
35    /// Calculate throughput (verifications per second)
36    pub fn throughput(&self) -> f64 {
37        if self.uptime_seconds == 0 {
38            0.0
39        } else {
40            self.total_verifications as f64 / self.uptime_seconds as f64
41        }
42    }
43}
44
45/// System metrics collector
46pub struct SystemMetrics {
47    total_verifications: Arc<AtomicU64>,
48    successful_verifications: Arc<AtomicU64>,
49    failed_verifications: Arc<AtomicU64>,
50    total_verification_time_us: Arc<AtomicU64>,
51    start_time: Instant,
52}
53
54impl SystemMetrics {
55    /// Create a new metrics collector
56    pub fn new() -> Self {
57        Self {
58            total_verifications: Arc::new(AtomicU64::new(0)),
59            successful_verifications: Arc::new(AtomicU64::new(0)),
60            failed_verifications: Arc::new(AtomicU64::new(0)),
61            total_verification_time_us: Arc::new(AtomicU64::new(0)),
62            start_time: Instant::now(),
63        }
64    }
65
66    /// Record a verification attempt
67    pub fn record_verification(&self) {
68        self.total_verifications.fetch_add(1, Ordering::Relaxed);
69    }
70
71    /// Record a successful verification
72    pub fn record_success(&self) {
73        self.successful_verifications
74            .fetch_add(1, Ordering::Relaxed);
75    }
76
77    /// Record a failed verification
78    pub fn record_failure(&self) {
79        self.failed_verifications.fetch_add(1, Ordering::Relaxed);
80    }
81
82    /// Record verification time
83    pub fn record_verification_time(&self, duration_us: u64) {
84        self.total_verification_time_us
85            .fetch_add(duration_us, Ordering::Relaxed);
86    }
87
88    /// Get a snapshot of current metrics
89    pub fn snapshot(&self) -> Metrics {
90        let total = self.total_verifications.load(Ordering::Relaxed);
91        let successful = self.successful_verifications.load(Ordering::Relaxed);
92        let failed = self.failed_verifications.load(Ordering::Relaxed);
93        let total_time = self.total_verification_time_us.load(Ordering::Relaxed);
94        let uptime = self.start_time.elapsed().as_secs();
95
96        let avg_time = if total > 0 {
97            total_time / total
98        } else {
99            0
100        };
101
102        Metrics {
103            total_verifications: total,
104            successful_verifications: successful,
105            failed_verifications: failed,
106            avg_verification_time_us: avg_time,
107            total_verification_time_us: total_time,
108            uptime_seconds: uptime,
109        }
110    }
111
112    /// Reset all metrics
113    pub fn reset(&self) {
114        self.total_verifications.store(0, Ordering::Relaxed);
115        self.successful_verifications.store(0, Ordering::Relaxed);
116        self.failed_verifications.store(0, Ordering::Relaxed);
117        self.total_verification_time_us.store(0, Ordering::Relaxed);
118    }
119}
120
121impl Default for SystemMetrics {
122    fn default() -> Self {
123        Self::new()
124    }
125}
126
127#[cfg(test)]
128mod tests {
129    use super::*;
130
131    #[test]
132    fn test_metrics_creation() {
133        let metrics = SystemMetrics::new();
134        let snapshot = metrics.snapshot();
135        assert_eq!(snapshot.total_verifications, 0);
136        assert_eq!(snapshot.successful_verifications, 0);
137        assert_eq!(snapshot.failed_verifications, 0);
138    }
139
140    #[test]
141    fn test_record_verification() {
142        let metrics = SystemMetrics::new();
143        metrics.record_verification();
144        metrics.record_success();
145
146        let snapshot = metrics.snapshot();
147        assert_eq!(snapshot.total_verifications, 1);
148        assert_eq!(snapshot.successful_verifications, 1);
149    }
150
151    #[test]
152    fn test_success_rate() {
153        let metrics = Metrics {
154            total_verifications: 10,
155            successful_verifications: 8,
156            failed_verifications: 2,
157            avg_verification_time_us: 100,
158            total_verification_time_us: 1000,
159            uptime_seconds: 60,
160        };
161
162        assert_eq!(metrics.success_rate(), 0.8);
163    }
164
165    #[test]
166    fn test_throughput() {
167        let metrics = Metrics {
168            total_verifications: 100,
169            successful_verifications: 95,
170            failed_verifications: 5,
171            avg_verification_time_us: 100,
172            total_verification_time_us: 10000,
173            uptime_seconds: 10,
174        };
175
176        assert_eq!(metrics.throughput(), 10.0);
177    }
178
179    #[test]
180    fn test_metrics_reset() {
181        let metrics = SystemMetrics::new();
182        metrics.record_verification();
183        metrics.record_success();
184        metrics.reset();
185
186        let snapshot = metrics.snapshot();
187        assert_eq!(snapshot.total_verifications, 0);
188    }
189}