agentic_payments/system/
metrics.rs1use serde::{Deserialize, Serialize};
4use std::sync::atomic::{AtomicU64, Ordering};
5use std::sync::Arc;
6use std::time::Instant;
7
8#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Metrics {
11 pub total_verifications: u64,
13 pub successful_verifications: u64,
15 pub failed_verifications: u64,
17 pub avg_verification_time_us: u64,
19 pub total_verification_time_us: u64,
21 pub uptime_seconds: u64,
23}
24
25impl Metrics {
26 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 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
45pub 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 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 pub fn record_verification(&self) {
68 self.total_verifications.fetch_add(1, Ordering::Relaxed);
69 }
70
71 pub fn record_success(&self) {
73 self.successful_verifications
74 .fetch_add(1, Ordering::Relaxed);
75 }
76
77 pub fn record_failure(&self) {
79 self.failed_verifications.fetch_add(1, Ordering::Relaxed);
80 }
81
82 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 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 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}