nym_statistics_common/clients/
mod.rs1use crate::report::client::{ClientStatsReport, OsInformation};
5
6use nym_task::ShutdownToken;
7use time::{OffsetDateTime, Time};
8use tokio::sync::mpsc::UnboundedSender;
9
10pub mod gateway_conn_statistics;
12
13pub mod nym_api_statistics;
15
16pub mod packet_statistics;
18
19pub mod connection;
20
21pub type ClientStatsReceiver = tokio::sync::mpsc::UnboundedReceiver<ClientStatsEvents>;
23
24#[derive(Clone)]
26pub struct ClientStatsSender {
27 stats_tx: Option<UnboundedSender<ClientStatsEvents>>,
28 shutdown_token: ShutdownToken,
29}
30
31impl ClientStatsSender {
32 pub fn new(
34 stats_tx: Option<UnboundedSender<ClientStatsEvents>>,
35 shutdown_token: ShutdownToken,
36 ) -> Self {
37 ClientStatsSender {
38 stats_tx,
39 shutdown_token,
40 }
41 }
42
43 pub fn report(&self, event: ClientStatsEvents) {
45 if let Some(tx) = &self.stats_tx
46 && let Err(err) = tx.send(event)
47 && !self.shutdown_token.is_cancelled()
48 {
49 log::error!("Failed to send stats event: {err}");
50 }
51 }
52}
53
54pub enum ClientStatsEvents {
56 PacketStatistics(packet_statistics::PacketStatisticsEvent),
58 GatewayConn(gateway_conn_statistics::GatewayStatsEvent),
60 NymApi(nym_api_statistics::NymApiStatsEvent),
62 Connection(connection::ConnectionStatsEvent),
64}
65
66pub struct ClientStatsController {
68 last_update_time: OffsetDateTime,
70 client_id: String,
71 client_type: String,
72 os_information: OsInformation,
73
74 packet_stats: packet_statistics::PacketStatisticsControl,
76 gateway_conn_stats: gateway_conn_statistics::GatewayStatsControl,
77 nym_api_stats: nym_api_statistics::NymApiStatsControl,
78 connection_stats: connection::ConnectionStatsControl,
79}
80
81impl ClientStatsController {
82 pub fn new(client_id: String, client_type: String) -> Self {
84 ClientStatsController {
85 last_update_time: ClientStatsController::get_update_time(),
86 client_id,
87 client_type,
88 os_information: OsInformation::new(),
89 packet_stats: Default::default(),
90 gateway_conn_stats: Default::default(),
91 nym_api_stats: Default::default(),
92 connection_stats: Default::default(),
93 }
94 }
95 pub fn build_report(&self) -> ClientStatsReport {
97 ClientStatsReport {
98 last_update_time: self.last_update_time,
99 client_id: self.client_id.clone(),
100 client_type: self.client_type.clone(),
101 os_information: self.os_information.clone(),
102 packet_stats: self.packet_stats.report(),
103 gateway_conn_stats: self.gateway_conn_stats.report(),
104 nym_api_stats: self.nym_api_stats.report(),
105 connection_stats: self.connection_stats.report(),
106 ..Default::default()
107 }
108 }
109
110 pub fn handle_event(&mut self, stats_event: ClientStatsEvents) {
112 match stats_event {
113 ClientStatsEvents::PacketStatistics(event) => self.packet_stats.handle_event(event),
114 ClientStatsEvents::GatewayConn(event) => self.gateway_conn_stats.handle_event(event),
115 ClientStatsEvents::NymApi(event) => self.nym_api_stats.handle_event(event),
116 ClientStatsEvents::Connection(event) => self.connection_stats.handle_event(event),
117 }
118 }
119
120 pub fn reset(&mut self) {
124 self.nym_api_stats = Default::default();
125 self.gateway_conn_stats = Default::default();
126 self.connection_stats = Default::default();
127 self.last_update_time = ClientStatsController::get_update_time();
130 }
131
132 pub fn snapshot(&mut self) {
134 self.packet_stats.snapshot();
137 }
138
139 pub fn local_report(&mut self) {
140 self.packet_stats.local_report();
141 self.gateway_conn_stats.local_report();
142 self.nym_api_stats.local_report();
143 }
144
145 fn get_update_time() -> OffsetDateTime {
146 let now = OffsetDateTime::now_utc();
147 #[allow(clippy::unwrap_used)]
148 let new_time = Time::from_hms(now.hour(), now.minute(), 0).unwrap();
150 now.replace_time(new_time)
152 }
153}