use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
#[derive(Debug, Default)]
pub(crate) struct Metrics {
connections: AtomicU64,
commands_total: AtomicU64,
commands_error_total: AtomicU64,
command_duration_microseconds_total: AtomicU64,
frame_bytes_in_total: AtomicU64,
frame_bytes_out_total: AtomicU64,
slow_commands_total: AtomicU64,
non_hello_first_frames_total: AtomicU64,
}
impl Metrics {
pub(crate) fn connection_opened(&self) {
self.connections.fetch_add(1, Ordering::Relaxed);
}
pub(crate) fn connection_closed(&self) {
self.connections.fetch_sub(1, Ordering::Relaxed);
}
pub(crate) fn record_command(
&self,
in_bytes: usize,
out_bytes: usize,
duration: Duration,
is_error: bool,
slow_threshold: Duration,
) {
self.commands_total.fetch_add(1, Ordering::Relaxed);
if is_error {
self.commands_error_total.fetch_add(1, Ordering::Relaxed);
}
self.command_duration_microseconds_total
.fetch_add(duration.as_micros() as u64, Ordering::Relaxed);
self.frame_bytes_in_total
.fetch_add(in_bytes as u64, Ordering::Relaxed);
self.frame_bytes_out_total
.fetch_add(out_bytes as u64, Ordering::Relaxed);
if !slow_threshold.is_zero() && duration >= slow_threshold {
self.slow_commands_total.fetch_add(1, Ordering::Relaxed);
}
}
pub(crate) fn record_push(&self, out_bytes: usize) {
self.frame_bytes_out_total
.fetch_add(out_bytes as u64, Ordering::Relaxed);
}
pub(crate) fn record_non_hello_first_frame(&self) {
self.non_hello_first_frames_total
.fetch_add(1, Ordering::Relaxed);
}
pub(crate) fn snapshot(&self) -> MetricsSnapshot {
MetricsSnapshot {
connections: self.connections.load(Ordering::Relaxed),
commands_total: self.commands_total.load(Ordering::Relaxed),
commands_error_total: self.commands_error_total.load(Ordering::Relaxed),
command_duration_microseconds_total: self
.command_duration_microseconds_total
.load(Ordering::Relaxed),
frame_bytes_in_total: self.frame_bytes_in_total.load(Ordering::Relaxed),
frame_bytes_out_total: self.frame_bytes_out_total.load(Ordering::Relaxed),
slow_commands_total: self.slow_commands_total.load(Ordering::Relaxed),
non_hello_first_frames_total: self.non_hello_first_frames_total.load(Ordering::Relaxed),
}
}
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct MetricsSnapshot {
pub connections: u64,
pub commands_total: u64,
pub commands_error_total: u64,
pub command_duration_microseconds_total: u64,
pub frame_bytes_in_total: u64,
pub frame_bytes_out_total: u64,
pub slow_commands_total: u64,
pub non_hello_first_frames_total: u64,
}