Mountain/IPC/Common/
PerformanceMetrics.rs1use std::time::{Duration, Instant};
7
8use serde::Serialize;
9
10#[derive(Debug, Clone, Serialize)]
12pub struct PerformanceMetrics {
13 pub messages_per_second:f64,
15 pub average_latency_ms:f64,
17 pub peak_latency_ms:f64,
19 pub compression_ratio:f64,
21 pub pool_utilization:f64,
23 pub memory_usage_bytes:u64,
25 pub cpu_usage_percent:f64,
27 pub total_messages:u64,
29 pub failed_messages:u64,
31 #[serde(skip)]
34 pub last_updated:Instant,
35}
36
37impl PerformanceMetrics {
38 pub fn new() -> Self {
40 Self {
41 messages_per_second:0.0,
42 average_latency_ms:0.0,
43 peak_latency_ms:0.0,
44 compression_ratio:1.0,
45 pool_utilization:0.0,
46 memory_usage_bytes:0,
47 cpu_usage_percent:0.0,
48 total_messages:0,
49 failed_messages:0,
50 last_updated:Instant::now(),
51 }
52 }
53
54 pub fn record_message(&mut self, latency:Duration) {
56 let latency_ms = latency.as_millis() as f64;
57
58 if self.total_messages > 0 {
60 self.average_latency_ms =
61 (self.average_latency_ms * self.total_messages as f64 + latency_ms) / (self.total_messages + 1) as f64;
62 } else {
63 self.average_latency_ms = latency_ms;
64 }
65
66 if latency_ms > self.peak_latency_ms {
68 self.peak_latency_ms = latency_ms;
69 }
70
71 self.total_messages += 1;
72 self.last_updated = Instant::now();
73 }
74
75 pub fn record_failure(&mut self) {
77 self.failed_messages += 1;
78 self.last_updated = Instant::now();
79 }
80
81 pub fn success_rate(&self) -> f64 {
83 if self.total_messages == 0 {
84 return 1.0;
85 }
86 1.0 - (self.failed_messages as f64 / self.total_messages as f64)
87 }
88
89 pub fn is_latency_acceptable(&self, threshold_ms:f64) -> bool {
91 self.average_latency_ms <= threshold_ms && self.peak_latency_ms <= threshold_ms * 2.0
92 }
93
94 pub fn success_rate_percent(&self) -> f64 { self.success_rate() * 100.0 }
96}
97
98impl Default for PerformanceMetrics {
99 fn default() -> Self { Self::new() }
100}
101
102#[derive(Debug, Clone)]
104pub struct ThroughputMetrics {
105 pub messages_received:u64,
107 pub messages_sent:u64,
109 pub bytes_received:u64,
111 pub bytes_sent:u64,
113 pub start_time:Instant,
115}
116
117impl ThroughputMetrics {
118 pub fn new() -> Self {
120 Self {
121 messages_received:0,
122 messages_sent:0,
123 bytes_received:0,
124 bytes_sent:0,
125 start_time:Instant::now(),
126 }
127 }
128
129 pub fn record_received(&mut self, bytes:u64) {
131 self.messages_received += 1;
132 self.bytes_received += bytes;
133 }
134
135 pub fn record_sent(&mut self, bytes:u64) {
137 self.messages_sent += 1;
138 self.bytes_sent += bytes;
139 }
140
141 pub fn messages_per_second_received(&self) -> f64 {
143 let elapsed = self.start_time.elapsed().as_secs_f64();
144 if elapsed > 0.0 { self.messages_received as f64 / elapsed } else { 0.0 }
145 }
146
147 pub fn messages_per_second_sent(&self) -> f64 {
149 let elapsed = self.start_time.elapsed().as_secs_f64();
150 if elapsed > 0.0 { self.messages_sent as f64 / elapsed } else { 0.0 }
151 }
152
153 pub fn bytes_per_second_received(&self) -> f64 {
155 let elapsed = self.start_time.elapsed().as_secs_f64();
156 if elapsed > 0.0 { self.bytes_received as f64 / elapsed } else { 0.0 }
157 }
158
159 pub fn bytes_per_second_sent(&self) -> f64 {
161 let elapsed = self.start_time.elapsed().as_secs_f64();
162 if elapsed > 0.0 { self.bytes_sent as f64 / elapsed } else { 0.0 }
163 }
164}
165
166impl Default for ThroughputMetrics {
167 fn default() -> Self { Self::new() }
168}