Mountain/IPC/Common/
PerformanceMetrics.rs1use std::time::{Duration, Instant};
7
8use serde::{Deserialize, 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)]
33 pub last_updated:Instant,
34}
35
36impl PerformanceMetrics {
37 pub fn new() -> Self {
39 Self {
40 messages_per_second:0.0,
41 average_latency_ms:0.0,
42 peak_latency_ms:0.0,
43 compression_ratio:1.0,
44 pool_utilization:0.0,
45 memory_usage_bytes:0,
46 cpu_usage_percent:0.0,
47 total_messages:0,
48 failed_messages:0,
49 last_updated:Instant::now(),
50 }
51 }
52
53 pub fn record_message(&mut self, latency:Duration) {
55 let latency_ms = latency.as_millis() as f64;
56
57 if self.total_messages > 0 {
59 self.average_latency_ms =
60 (self.average_latency_ms * self.total_messages as f64 + latency_ms) / (self.total_messages + 1) as f64;
61 } else {
62 self.average_latency_ms = latency_ms;
63 }
64
65 if latency_ms > self.peak_latency_ms {
67 self.peak_latency_ms = latency_ms;
68 }
69
70 self.total_messages += 1;
71 self.last_updated = Instant::now();
72 }
73
74 pub fn record_failure(&mut self) {
76 self.failed_messages += 1;
77 self.last_updated = Instant::now();
78 }
79
80 pub fn success_rate(&self) -> f64 {
82 if self.total_messages == 0 {
83 return 1.0;
84 }
85 1.0 - (self.failed_messages as f64 / self.total_messages as f64)
86 }
87
88 pub fn is_latency_acceptable(&self, threshold_ms:f64) -> bool {
90 self.average_latency_ms <= threshold_ms && self.peak_latency_ms <= threshold_ms * 2.0
91 }
92
93 pub fn success_rate_percent(&self) -> f64 { self.success_rate() * 100.0 }
95}
96
97impl Default for PerformanceMetrics {
98 fn default() -> Self { Self::new() }
99}
100
101#[derive(Debug, Clone)]
103pub struct ThroughputMetrics {
104 pub messages_received:u64,
106 pub messages_sent:u64,
108 pub bytes_received:u64,
110 pub bytes_sent:u64,
112 pub start_time:Instant,
114}
115
116impl ThroughputMetrics {
117 pub fn new() -> Self {
119 Self {
120 messages_received:0,
121 messages_sent:0,
122 bytes_received:0,
123 bytes_sent:0,
124 start_time:Instant::now(),
125 }
126 }
127
128 pub fn record_received(&mut self, bytes:u64) {
130 self.messages_received += 1;
131 self.bytes_received += bytes;
132 }
133
134 pub fn record_sent(&mut self, bytes:u64) {
136 self.messages_sent += 1;
137 self.bytes_sent += bytes;
138 }
139
140 pub fn messages_per_second_received(&self) -> f64 {
142 let elapsed = self.start_time.elapsed().as_secs_f64();
143 if elapsed > 0.0 { self.messages_received as f64 / elapsed } else { 0.0 }
144 }
145
146 pub fn messages_per_second_sent(&self) -> f64 {
148 let elapsed = self.start_time.elapsed().as_secs_f64();
149 if elapsed > 0.0 { self.messages_sent as f64 / elapsed } else { 0.0 }
150 }
151
152 pub fn bytes_per_second_received(&self) -> f64 {
154 let elapsed = self.start_time.elapsed().as_secs_f64();
155 if elapsed > 0.0 { self.bytes_received as f64 / elapsed } else { 0.0 }
156 }
157
158 pub fn bytes_per_second_sent(&self) -> f64 {
160 let elapsed = self.start_time.elapsed().as_secs_f64();
161 if elapsed > 0.0 { self.bytes_sent as f64 / elapsed } else { 0.0 }
162 }
163}
164
165impl Default for ThroughputMetrics {
166 fn default() -> Self { Self::new() }
167}