This commit is contained in:
Mateusz Gruszczyński committed 2026-10-04 11:15:58 +02:00
1 parent 87e571c170
commit fa7abc9e53
308 files changed
+49746 -50237

No files matched your search

+96
View File
@@ -0,0 +1,96 @@
#[derive(Default, Debug)]
pub struct VhostMetrics {
pub requests: AtomicU64,
pub completed: AtomicU64,
pub active: AtomicU64,
pub rejected: AtomicU64,
pub errors: AtomicU64,
pub bytes_in: AtomicU64,
pub bytes_out: AtomicU64,
pub duration_us: AtomicU64,
pub ewma_duration_us: AtomicU64,
pub status: [AtomicU64; 5],
pub buckets: [AtomicU64; 11],
}
#[derive(Debug, Clone, Serialize)]
pub struct VhostMetricsView {
pub requests: u64,
pub completed: u64,
pub active: u64,
pub rejected: u64,
pub errors: u64,
pub bytes_in: u64,
pub bytes_out: u64,
pub average_latency_ms: f64,
pub ewma_latency_ms: f64,
}
impl VhostMetrics {
pub fn complete(
&self,
status: u16,
failed: bool,
duration: std::time::Duration,
bytes_in: u64,
bytes_out: u64,
) {
self.active.fetch_sub(1, Ordering::Relaxed);
self.completed.fetch_add(1, Ordering::Relaxed);
if failed || status >= 500 {
self.errors.fetch_add(1, Ordering::Relaxed);
}
self.bytes_in.fetch_add(bytes_in, Ordering::Relaxed);
self.bytes_out.fetch_add(bytes_out, Ordering::Relaxed);
self.status[(status as usize / 100).clamp(1, 5) - 1].fetch_add(1, Ordering::Relaxed);
let micros = duration.as_micros().min(u64::MAX as u128) as u64;
self.duration_us.fetch_add(micros, Ordering::Relaxed);
let mut current = self.ewma_duration_us.load(Ordering::Relaxed);
loop {
let next = if current == 0 {
micros
} else {
current.saturating_mul(7).saturating_add(micros) / 8
};
match self.ewma_duration_us.compare_exchange_weak(
current,
next,
Ordering::Relaxed,
Ordering::Relaxed,
) {
Ok(_) => break,
Err(observed) => current = observed,
}
}
for (index, threshold) in DURATION_BUCKETS_US.iter().enumerate() {
if micros <= *threshold {
self.buckets[index].fetch_add(1, Ordering::Relaxed);
}
}
self.buckets[DURATION_BUCKETS_US.len()].fetch_add(1, Ordering::Relaxed);
}
pub fn view(&self) -> VhostMetricsView {
let completed = n(&self.completed);
let duration_us = n(&self.duration_us);
VhostMetricsView {
requests: n(&self.requests),
completed,
active: n(&self.active),
rejected: n(&self.rejected),
errors: n(&self.errors),
bytes_in: n(&self.bytes_in),
bytes_out: n(&self.bytes_out),
average_latency_ms: if completed == 0 {
0.0
} else {
duration_us as f64 / completed as f64 / 1000.0
},
ewma_latency_ms: n(&self.ewma_duration_us) as f64 / 1000.0,
}
}
}
#[cfg(test)]
include!("vhost/tests.rs");