nerve/integration/
performance.rs

1//! System Performance Monitoring
2//!
3//! Comprehensive performance monitoring for the integrated Nerve Framework system.
4
5use std::sync::atomic::{AtomicU64, Ordering};
6use std::sync::Arc;
7use std::time::{Duration, Instant};
8
9/// System-wide performance metrics
10#[derive(Debug)]
11pub struct SystemPerformance {
12    /// Total messages processed
13    messages_processed: AtomicU64,
14    /// Total errors encountered
15    errors_encountered: AtomicU64,
16    /// Total processing time in nanoseconds
17    total_processing_time: AtomicU64,
18    /// Memory usage in bytes
19    memory_usage: AtomicU64,
20    /// Thread utilization percentage
21    thread_utilization: AtomicU64,
22}
23
24impl SystemPerformance {
25    /// Create a new performance monitor
26    pub fn new() -> Arc<Self> {
27        Arc::new(Self {
28            messages_processed: AtomicU64::new(0),
29            errors_encountered: AtomicU64::new(0),
30            total_processing_time: AtomicU64::new(0),
31            memory_usage: AtomicU64::new(0),
32            thread_utilization: AtomicU64::new(0),
33        })
34    }
35
36    /// Record a message processing operation
37    pub fn record_message_processed(&self, processing_time: Duration) {
38        self.messages_processed.fetch_add(1, Ordering::Relaxed);
39        self.total_processing_time.fetch_add(
40            processing_time.as_nanos() as u64,
41            Ordering::Relaxed,
42        );
43    }
44
45    /// Record an error
46    pub fn record_error(&self) {
47        self.errors_encountered.fetch_add(1, Ordering::Relaxed);
48    }
49
50    /// Update memory usage
51    pub fn update_memory_usage(&self, usage_bytes: u64) {
52        self.memory_usage.store(usage_bytes, Ordering::Relaxed);
53    }
54
55    /// Update thread utilization
56    pub fn update_thread_utilization(&self, utilization_percent: u64) {
57        self.thread_utilization.store(utilization_percent, Ordering::Relaxed);
58    }
59
60    /// Get current performance statistics
61    pub fn get_statistics(&self) -> SystemStatistics {
62        let messages = self.messages_processed.load(Ordering::Relaxed);
63        let errors = self.errors_encountered.load(Ordering::Relaxed);
64        let total_time = self.total_processing_time.load(Ordering::Relaxed);
65        let memory = self.memory_usage.load(Ordering::Relaxed);
66        let threads = self.thread_utilization.load(Ordering::Relaxed);
67
68        let avg_processing_time = if messages > 0 {
69            Duration::from_nanos(total_time / messages)
70        } else {
71            Duration::from_nanos(0)
72        };
73
74        let error_rate = if messages > 0 {
75            (errors as f64 / messages as f64) * 100.0
76        } else {
77            0.0
78        };
79
80        SystemStatistics {
81            messages_processed: messages,
82            errors_encountered: errors,
83            average_processing_time: avg_processing_time,
84            error_rate_percent: error_rate,
85            memory_usage_bytes: memory,
86            thread_utilization_percent: threads,
87        }
88    }
89}
90
91/// System performance statistics
92#[derive(Debug, Clone)]
93pub struct SystemStatistics {
94    /// Total messages processed
95    pub messages_processed: u64,
96    /// Total errors encountered
97    pub errors_encountered: u64,
98    /// Average processing time per message
99    pub average_processing_time: Duration,
100    /// Error rate as percentage
101    pub error_rate_percent: f64,
102    /// Current memory usage in bytes
103    pub memory_usage_bytes: u64,
104    /// Thread utilization percentage
105    pub thread_utilization_percent: u64,
106}
107
108impl SystemStatistics {
109    /// Check if system is healthy based on performance metrics
110    pub fn is_healthy(&self) -> bool {
111        // System is considered healthy if:
112        // - Error rate is below 1%
113        // - Memory usage is reasonable (< 1GB)
114        // - Thread utilization is reasonable (10-90%)
115        self.error_rate_percent < 1.0
116            && self.memory_usage_bytes < 1_000_000_000
117            && self.thread_utilization_percent >= 10
118            && self.thread_utilization_percent <= 90
119    }
120
121    /// Get system health status
122    pub fn health_status(&self) -> SystemHealth {
123        if self.is_healthy() {
124            SystemHealth::Healthy
125        } else if self.error_rate_percent > 5.0 || self.memory_usage_bytes > 2_000_000_000 {
126            SystemHealth::Critical
127        } else {
128            SystemHealth::Warning
129        }
130    }
131}
132
133/// System health status
134#[derive(Debug, Clone, PartialEq)]
135pub enum SystemHealth {
136    /// System is operating normally
137    Healthy,
138    /// System has some issues but is still operational
139    Warning,
140    /// System has critical issues and may need intervention
141    Critical,
142}
143
144/// Performance measurement utility
145pub struct PerformanceTimer {
146    start_time: Instant,
147    performance_monitor: Arc<SystemPerformance>,
148}
149
150impl PerformanceTimer {
151    /// Start a new performance timer
152    pub fn start(performance_monitor: Arc<SystemPerformance>) -> Self {
153        Self {
154            start_time: Instant::now(),
155            performance_monitor,
156        }
157    }
158
159    /// Record the elapsed time and update performance metrics
160    pub fn record(self) {
161        let elapsed = self.start_time.elapsed();
162        self.performance_monitor.record_message_processed(elapsed);
163    }
164}
165
166impl Drop for PerformanceTimer {
167    fn drop(&mut self) {
168        if !std::thread::panicking() {
169            // We can't call self.record() here because it consumes self
170            // Instead, we'll record the elapsed time directly
171            let elapsed = self.start_time.elapsed();
172            self.performance_monitor.record_message_processed(elapsed);
173        }
174    }
175}