2022-03-07 23:05:40 -08:00
|
|
|
/// Statistics and reporting.
|
2023-03-28 17:19:37 +02:00
|
|
|
use arc_swap::ArcSwap;
|
|
|
|
|
|
|
|
|
|
use log::{info, warn};
|
2022-02-26 11:01:52 -08:00
|
|
|
use once_cell::sync::Lazy;
|
2023-03-28 17:19:37 +02:00
|
|
|
use parking_lot::RwLock;
|
2022-02-14 10:00:55 -08:00
|
|
|
use std::collections::HashMap;
|
2023-03-28 17:19:37 +02:00
|
|
|
|
2022-09-14 10:20:41 -05:00
|
|
|
use std::sync::Arc;
|
|
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
// Structs that hold stats for different resources
|
|
|
|
|
pub mod address;
|
|
|
|
|
pub mod client;
|
|
|
|
|
pub mod pool;
|
|
|
|
|
pub mod server;
|
|
|
|
|
pub use address::AddressStats;
|
|
|
|
|
pub use client::{ClientState, ClientStats};
|
|
|
|
|
pub use server::{ServerState, ServerStats};
|
2022-09-14 10:20:41 -05:00
|
|
|
|
|
|
|
|
/// Convenience types for various stats
|
2023-03-28 17:19:37 +02:00
|
|
|
type ClientStatesLookup = HashMap<i32, Arc<ClientStats>>;
|
|
|
|
|
type ServerStatesLookup = HashMap<i32, Arc<ServerStats>>;
|
2022-09-14 10:20:41 -05:00
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
/// Stats for individual client connections
|
2022-09-14 10:20:41 -05:00
|
|
|
/// Used in SHOW CLIENTS.
|
2023-03-28 17:19:37 +02:00
|
|
|
static CLIENT_STATS: Lazy<Arc<RwLock<ClientStatesLookup>>> =
|
|
|
|
|
Lazy::new(|| Arc::new(RwLock::new(ClientStatesLookup::default())));
|
2022-09-14 10:20:41 -05:00
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
/// Stats for individual server connections
|
2022-09-14 10:20:41 -05:00
|
|
|
/// Used in SHOW SERVERS.
|
2023-03-28 17:19:37 +02:00
|
|
|
static SERVER_STATS: Lazy<Arc<RwLock<ServerStatesLookup>>> =
|
|
|
|
|
Lazy::new(|| Arc::new(RwLock::new(ServerStatesLookup::default())));
|
2022-09-14 10:20:41 -05:00
|
|
|
|
|
|
|
|
/// The statistics reporter. An instance is given to each possible source of statistics,
|
2023-03-28 17:19:37 +02:00
|
|
|
/// e.g. client stats, server stats, connection pool stats.
|
2022-06-24 14:52:38 -07:00
|
|
|
pub static REPORTER: Lazy<ArcSwap<Reporter>> =
|
|
|
|
|
Lazy::new(|| ArcSwap::from_pointee(Reporter::default()));
|
2022-02-14 10:00:55 -08:00
|
|
|
|
2022-03-10 01:33:29 -08:00
|
|
|
/// Statistics period used for average calculations.
|
|
|
|
|
/// 15 seconds.
|
2022-03-07 23:05:40 -08:00
|
|
|
static STAT_PERIOD: u64 = 15000;
|
|
|
|
|
|
|
|
|
|
/// The statistics reporter. An instance is given
|
|
|
|
|
/// to each possible source of statistics,
|
|
|
|
|
/// e.g. clients, servers, connection pool.
|
2023-03-28 17:19:37 +02:00
|
|
|
#[derive(Clone, Debug, Default)]
|
|
|
|
|
pub struct Reporter {}
|
2022-06-24 14:52:38 -07:00
|
|
|
|
2022-02-14 10:00:55 -08:00
|
|
|
impl Reporter {
|
2022-09-14 10:20:41 -05:00
|
|
|
/// Register a client with the stats system. The stats system uses client_id
|
|
|
|
|
/// to track and aggregate statistics from all source that relate to that client
|
2023-03-28 17:19:37 +02:00
|
|
|
fn client_register(&self, client_id: i32, stats: Arc<ClientStats>) {
|
|
|
|
|
if CLIENT_STATS.read().get(&client_id).is_some() {
|
|
|
|
|
warn!("Client {:?} was double registered!", client_id);
|
|
|
|
|
return;
|
|
|
|
|
}
|
2022-02-15 08:18:01 -08:00
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
CLIENT_STATS.write().insert(client_id, stats);
|
2022-02-15 08:18:01 -08:00
|
|
|
}
|
2022-02-20 22:47:08 -08:00
|
|
|
|
2023-04-11 09:37:16 +08:00
|
|
|
/// Reports a client is disconnecting from the pooler.
|
2023-03-28 17:19:37 +02:00
|
|
|
fn client_disconnecting(&self, client_id: i32) {
|
|
|
|
|
CLIENT_STATS.write().remove(&client_id);
|
2022-02-20 22:47:08 -08:00
|
|
|
}
|
|
|
|
|
|
2022-09-14 10:20:41 -05:00
|
|
|
/// Register a server connection with the stats system. The stats system uses server_id
|
|
|
|
|
/// to track and aggregate statistics from all source that relate to that server
|
2023-03-28 17:19:37 +02:00
|
|
|
fn server_register(&self, server_id: i32, stats: Arc<ServerStats>) {
|
|
|
|
|
SERVER_STATS.write().insert(server_id, stats);
|
2022-02-20 22:47:08 -08:00
|
|
|
}
|
2023-04-11 09:37:16 +08:00
|
|
|
/// Reports a server connection is disconnecting from the pooler.
|
2023-03-28 17:19:37 +02:00
|
|
|
fn server_disconnecting(&self, server_id: i32) {
|
|
|
|
|
SERVER_STATS.write().remove(&server_id);
|
2022-02-20 22:47:08 -08:00
|
|
|
}
|
2022-02-14 10:00:55 -08:00
|
|
|
}
|
|
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
/// The statistics collector which used for calculating averages
|
|
|
|
|
/// There is only one collector (kind of like a singleton)
|
|
|
|
|
/// it updates averages every 15 seconds.
|
|
|
|
|
#[derive(Default)]
|
|
|
|
|
pub struct Collector {}
|
2022-02-14 10:00:55 -08:00
|
|
|
|
|
|
|
|
impl Collector {
|
2022-03-07 23:05:40 -08:00
|
|
|
/// The statistics collection handler. It will collect statistics
|
|
|
|
|
/// for `address_id`s starting at 0 up to `addresses`.
|
2022-06-25 12:22:46 -07:00
|
|
|
pub async fn collect(&mut self) {
|
2022-02-21 17:28:50 -08:00
|
|
|
info!("Events reporter started");
|
2022-02-20 22:47:08 -08:00
|
|
|
|
2022-02-22 18:10:30 -08:00
|
|
|
tokio::task::spawn(async move {
|
2022-02-26 10:03:11 -08:00
|
|
|
let mut interval =
|
|
|
|
|
tokio::time::interval(tokio::time::Duration::from_millis(STAT_PERIOD));
|
2022-02-22 18:10:30 -08:00
|
|
|
loop {
|
|
|
|
|
interval.tick().await;
|
2023-03-28 17:19:37 +02:00
|
|
|
|
2023-05-11 20:37:58 -04:00
|
|
|
// Hold read lock for duration of update to retain all server stats
|
|
|
|
|
let server_stats = SERVER_STATS.read();
|
|
|
|
|
|
|
|
|
|
for stats in server_stats.values() {
|
|
|
|
|
if !stats.check_address_stat_average_is_updated_status() {
|
|
|
|
|
stats.address_stats().update_averages();
|
2023-05-18 00:38:10 -04:00
|
|
|
stats.address_stats().reset_current_counts();
|
2023-05-11 20:37:58 -04:00
|
|
|
stats.set_address_stat_average_is_updated_status(true);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Reset to false for next update
|
|
|
|
|
for stats in server_stats.values() {
|
|
|
|
|
stats.set_address_stat_average_is_updated_status(false);
|
2022-03-04 17:04:27 -08:00
|
|
|
}
|
2022-02-22 18:10:30 -08:00
|
|
|
}
|
|
|
|
|
});
|
2022-02-14 10:00:55 -08:00
|
|
|
}
|
|
|
|
|
}
|
2022-02-25 18:20:15 -08:00
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
/// Get a snapshot of client statistics.
|
2022-09-14 10:20:41 -05:00
|
|
|
/// by the `Collector`.
|
|
|
|
|
pub fn get_client_stats() -> ClientStatesLookup {
|
2023-03-28 17:19:37 +02:00
|
|
|
CLIENT_STATS.read().clone()
|
2022-09-14 10:20:41 -05:00
|
|
|
}
|
|
|
|
|
|
2023-03-28 17:19:37 +02:00
|
|
|
/// Get a snapshot of server statistics.
|
2022-09-14 10:20:41 -05:00
|
|
|
/// by the `Collector`.
|
|
|
|
|
pub fn get_server_stats() -> ServerStatesLookup {
|
2023-03-28 17:19:37 +02:00
|
|
|
SERVER_STATS.read().clone()
|
2022-09-14 10:20:41 -05:00
|
|
|
}
|
|
|
|
|
|
2022-06-24 14:52:38 -07:00
|
|
|
/// Get the statistics reporter used to update stats across the pools/clients.
|
|
|
|
|
pub fn get_reporter() -> Reporter {
|
|
|
|
|
(*(*REPORTER.load())).clone()
|
|
|
|
|
}
|