thunder/server/
metrics.rs1use std::sync::atomic::{AtomicU64, Ordering};
8use std::time::Duration;
9
10#[derive(Debug, Default)]
13pub(crate) struct Metrics {
14 connections: AtomicU64,
15 commands_total: AtomicU64,
16 commands_error_total: AtomicU64,
17 command_duration_microseconds_total: AtomicU64,
18 frame_bytes_in_total: AtomicU64,
19 frame_bytes_out_total: AtomicU64,
20 slow_commands_total: AtomicU64,
21 non_hello_first_frames_total: AtomicU64,
22}
23
24impl Metrics {
25 pub(crate) fn connection_opened(&self) {
27 self.connections.fetch_add(1, Ordering::Relaxed);
28 }
29
30 pub(crate) fn connection_closed(&self) {
32 self.connections.fetch_sub(1, Ordering::Relaxed);
33 }
34
35 pub(crate) fn record_command(
39 &self,
40 in_bytes: usize,
41 out_bytes: usize,
42 duration: Duration,
43 is_error: bool,
44 slow_threshold: Duration,
45 ) {
46 self.commands_total.fetch_add(1, Ordering::Relaxed);
47 if is_error {
48 self.commands_error_total.fetch_add(1, Ordering::Relaxed);
49 }
50 self.command_duration_microseconds_total
51 .fetch_add(duration.as_micros() as u64, Ordering::Relaxed);
52 self.frame_bytes_in_total
53 .fetch_add(in_bytes as u64, Ordering::Relaxed);
54 self.frame_bytes_out_total
55 .fetch_add(out_bytes as u64, Ordering::Relaxed);
56 if !slow_threshold.is_zero() && duration >= slow_threshold {
57 self.slow_commands_total.fetch_add(1, Ordering::Relaxed);
58 }
59 }
60
61 pub(crate) fn record_push(&self, out_bytes: usize) {
64 self.frame_bytes_out_total
65 .fetch_add(out_bytes as u64, Ordering::Relaxed);
66 }
67
68 pub(crate) fn record_non_hello_first_frame(&self) {
74 self.non_hello_first_frames_total
75 .fetch_add(1, Ordering::Relaxed);
76 }
77
78 pub(crate) fn snapshot(&self) -> MetricsSnapshot {
80 MetricsSnapshot {
81 connections: self.connections.load(Ordering::Relaxed),
82 commands_total: self.commands_total.load(Ordering::Relaxed),
83 commands_error_total: self.commands_error_total.load(Ordering::Relaxed),
84 command_duration_microseconds_total: self
85 .command_duration_microseconds_total
86 .load(Ordering::Relaxed),
87 frame_bytes_in_total: self.frame_bytes_in_total.load(Ordering::Relaxed),
88 frame_bytes_out_total: self.frame_bytes_out_total.load(Ordering::Relaxed),
89 slow_commands_total: self.slow_commands_total.load(Ordering::Relaxed),
90 non_hello_first_frames_total: self.non_hello_first_frames_total.load(Ordering::Relaxed),
91 }
92 }
93}
94
95#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
98pub struct MetricsSnapshot {
99 pub connections: u64,
101 pub commands_total: u64,
103 pub commands_error_total: u64,
105 pub command_duration_microseconds_total: u64,
107 pub frame_bytes_in_total: u64,
109 pub frame_bytes_out_total: u64,
111 pub slow_commands_total: u64,
113 pub non_hello_first_frames_total: u64,
116}