zentinel_proxy/agents/
metrics.rs1use std::sync::atomic::{AtomicU64, Ordering};
4
5#[derive(Default)]
9pub struct AgentMetrics {
10 pub calls_total: AtomicU64,
12 pub calls_success: AtomicU64,
14 pub calls_failed: AtomicU64,
16 pub calls_timeout: AtomicU64,
18 pub circuit_breaker_trips: AtomicU64,
20 pub duration_total_us: AtomicU64,
22 pub decisions_allow: AtomicU64,
24 pub decisions_block: AtomicU64,
25 pub decisions_redirect: AtomicU64,
26 pub decisions_challenge: AtomicU64,
27 pub body_size_skips: AtomicU64,
29}
30
31impl AgentMetrics {
32 pub fn new() -> Self {
34 Self::default()
35 }
36
37 pub fn record_success(&self, duration_us: u64) {
39 self.calls_total.fetch_add(1, Ordering::Relaxed);
40 self.calls_success.fetch_add(1, Ordering::Relaxed);
41 self.duration_total_us
42 .fetch_add(duration_us, Ordering::Relaxed);
43 }
44
45 pub fn record_failure(&self) {
47 self.calls_total.fetch_add(1, Ordering::Relaxed);
48 self.calls_failed.fetch_add(1, Ordering::Relaxed);
49 }
50
51 pub fn record_timeout(&self) {
53 self.calls_total.fetch_add(1, Ordering::Relaxed);
54 self.calls_timeout.fetch_add(1, Ordering::Relaxed);
55 }
56
57 pub fn record_body_size_skip(&self) {
59 self.body_size_skips.fetch_add(1, Ordering::Relaxed);
60 }
61
62 pub fn average_duration_us(&self) -> f64 {
64 let total = self.duration_total_us.load(Ordering::Relaxed) as f64;
65 let success = self.calls_success.load(Ordering::Relaxed) as f64;
66 if success > 0.0 {
67 total / success
68 } else {
69 0.0
70 }
71 }
72}