agent_tui/daemon/
metrics.rs

1use std::sync::atomic::{AtomicU64, Ordering};
2use std::time::Instant;
3
4pub struct DaemonMetrics {
5    pub requests_total: AtomicU64,
6    pub errors_total: AtomicU64,
7    pub lock_timeouts: AtomicU64,
8    pub poison_recoveries: AtomicU64,
9    start_time: Instant,
10}
11
12impl Default for DaemonMetrics {
13    fn default() -> Self {
14        Self::new()
15    }
16}
17
18impl DaemonMetrics {
19    pub fn new() -> Self {
20        Self {
21            requests_total: AtomicU64::new(0),
22            errors_total: AtomicU64::new(0),
23            lock_timeouts: AtomicU64::new(0),
24            poison_recoveries: AtomicU64::new(0),
25            start_time: Instant::now(),
26        }
27    }
28
29    pub fn record_request(&self) {
30        self.requests_total.fetch_add(1, Ordering::Relaxed);
31    }
32
33    pub fn record_error(&self) {
34        self.errors_total.fetch_add(1, Ordering::Relaxed);
35    }
36
37    pub fn record_lock_timeout(&self) {
38        self.lock_timeouts.fetch_add(1, Ordering::Relaxed);
39    }
40
41    pub fn record_poison_recovery(&self) {
42        self.poison_recoveries.fetch_add(1, Ordering::Relaxed);
43    }
44
45    pub fn requests(&self) -> u64 {
46        self.requests_total.load(Ordering::Relaxed)
47    }
48
49    pub fn errors(&self) -> u64 {
50        self.errors_total.load(Ordering::Relaxed)
51    }
52
53    pub fn lock_timeouts(&self) -> u64 {
54        self.lock_timeouts.load(Ordering::Relaxed)
55    }
56
57    pub fn poison_recoveries(&self) -> u64 {
58        self.poison_recoveries.load(Ordering::Relaxed)
59    }
60
61    pub fn uptime_ms(&self) -> u64 {
62        self.start_time.elapsed().as_millis() as u64
63    }
64}
65
66#[cfg(test)]
67mod tests {
68    use super::*;
69
70    #[test]
71    fn test_metrics_initial_values() {
72        let metrics = DaemonMetrics::new();
73        assert_eq!(metrics.requests(), 0);
74        assert_eq!(metrics.errors(), 0);
75        assert_eq!(metrics.lock_timeouts(), 0);
76        assert_eq!(metrics.poison_recoveries(), 0);
77    }
78
79    #[test]
80    fn test_metrics_increment() {
81        let metrics = DaemonMetrics::new();
82        metrics.record_request();
83        metrics.record_request();
84        metrics.record_error();
85        assert_eq!(metrics.requests(), 2);
86        assert_eq!(metrics.errors(), 1);
87    }
88
89    #[test]
90    fn test_uptime_increases() {
91        let metrics = DaemonMetrics::new();
92        std::thread::sleep(std::time::Duration::from_millis(10));
93        assert!(metrics.uptime_ms() >= 10);
94    }
95}