v0.25.0
This commit is contained in:
1 parent
2e4aa4df4d
commit
87e571c170
106 files changed
+17952
-6185
No files matched your search
@@ -426,9 +426,24 @@ pub struct VhostMetrics {
|
||||
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,
|
||||
@@ -448,6 +463,23 @@ impl VhostMetrics {
|
||||
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);
|
||||
@@ -455,6 +487,26 @@ impl VhostMetrics {
|
||||
}
|
||||
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)]
|
||||
mod vhost_tests {
|
||||
@@ -470,6 +522,11 @@ mod vhost_tests {
|
||||
assert_eq!(n(&m.buckets[1]), 0);
|
||||
assert_eq!(n(&m.buckets[2]), 1);
|
||||
assert_eq!(n(&m.buckets[10]), 1);
|
||||
let view = m.view();
|
||||
assert_eq!(view.requests, 0);
|
||||
assert_eq!(view.completed, 1);
|
||||
assert_eq!(view.errors, 1);
|
||||
assert!(view.ewma_latency_ms >= 20.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user