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 connections_refused_total: AtomicU64,
16 commands_total: AtomicU64,
17 commands_error_total: AtomicU64,
18 command_duration_microseconds_total: AtomicU64,
19 frame_bytes_in_total: AtomicU64,
20 frame_bytes_out_total: AtomicU64,
21 slow_commands_total: AtomicU64,
22 non_hello_first_frames_total: AtomicU64,
23}
24
25impl Metrics {
26 pub(crate) fn connection_opened(&self) {
28 self.connections.fetch_add(1, Ordering::Relaxed);
29 }
30
31 pub(crate) fn connection_refused(&self) {
35 self.connections_refused_total
36 .fetch_add(1, Ordering::Relaxed);
37 }
38
39 pub(crate) fn connection_closed(&self) {
41 self.connections.fetch_sub(1, Ordering::Relaxed);
42 }
43
44 pub(crate) fn record_command(
48 &self,
49 in_bytes: usize,
50 out_bytes: usize,
51 duration: Duration,
52 is_error: bool,
53 slow_threshold: Duration,
54 ) {
55 self.commands_total.fetch_add(1, Ordering::Relaxed);
56 if is_error {
57 self.commands_error_total.fetch_add(1, Ordering::Relaxed);
58 }
59 self.command_duration_microseconds_total
60 .fetch_add(duration.as_micros() as u64, Ordering::Relaxed);
61 self.frame_bytes_in_total
62 .fetch_add(in_bytes as u64, Ordering::Relaxed);
63 self.frame_bytes_out_total
64 .fetch_add(out_bytes as u64, Ordering::Relaxed);
65 if !slow_threshold.is_zero() && duration >= slow_threshold {
66 self.slow_commands_total.fetch_add(1, Ordering::Relaxed);
67 }
68 }
69
70 pub(crate) fn record_push(&self, out_bytes: usize) {
73 self.frame_bytes_out_total
74 .fetch_add(out_bytes as u64, Ordering::Relaxed);
75 }
76
77 pub(crate) fn record_non_hello_first_frame(&self) {
83 self.non_hello_first_frames_total
84 .fetch_add(1, Ordering::Relaxed);
85 }
86
87 pub(crate) fn snapshot(&self) -> MetricsSnapshot {
89 MetricsSnapshot {
90 connections: self.connections.load(Ordering::Relaxed),
91 connections_refused_total: self.connections_refused_total.load(Ordering::Relaxed),
92 commands_total: self.commands_total.load(Ordering::Relaxed),
93 commands_error_total: self.commands_error_total.load(Ordering::Relaxed),
94 command_duration_microseconds_total: self
95 .command_duration_microseconds_total
96 .load(Ordering::Relaxed),
97 frame_bytes_in_total: self.frame_bytes_in_total.load(Ordering::Relaxed),
98 frame_bytes_out_total: self.frame_bytes_out_total.load(Ordering::Relaxed),
99 slow_commands_total: self.slow_commands_total.load(Ordering::Relaxed),
100 non_hello_first_frames_total: self.non_hello_first_frames_total.load(Ordering::Relaxed),
101 }
102 }
103}
104
105#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
108pub struct MetricsSnapshot {
109 pub connections: u64,
111 pub connections_refused_total: u64,
113 pub commands_total: u64,
115 pub commands_error_total: u64,
117 pub command_duration_microseconds_total: u64,
119 pub frame_bytes_in_total: u64,
121 pub frame_bytes_out_total: u64,
123 pub slow_commands_total: u64,
125 pub non_hello_first_frames_total: u64,
128}