diff --git a/Cargo.lock b/Cargo.lock index 6f8215bbf..269f7a3a2 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4668,7 +4668,6 @@ dependencies = [ "torrust-tracker-swarm-coordination-registry", "torrust-tracker-test-helpers", "torrust-udp-tracker-server", - "tracing", ] [[package]] diff --git a/packages/axum-http-tracker-server/tests/server/v1/contract.rs b/packages/axum-http-tracker-server/tests/server/v1/contract.rs index dd80e6b59..85792f922 100644 --- a/packages/axum-http-tracker-server/tests/server/v1/contract.rs +++ b/packages/axum-http-tracker-server/tests/server/v1/contract.rs @@ -704,7 +704,7 @@ mod for_all_config_modes { let stats = env.container.http_tracker_core_container.stats_repository.get_stats().await; - assert_eq!(stats.tcp4_announces_handled, 1); + assert_eq!(stats.tcp4_announces_handled(), 1); drop(stats); @@ -730,7 +730,7 @@ mod for_all_config_modes { let stats = env.container.http_tracker_core_container.stats_repository.get_stats().await; - assert_eq!(stats.tcp6_announces_handled, 1); + assert_eq!(stats.tcp6_announces_handled(), 1); drop(stats); @@ -755,7 +755,7 @@ mod for_all_config_modes { let stats = env.container.http_tracker_core_container.stats_repository.get_stats().await; - assert_eq!(stats.tcp6_announces_handled, 0); + assert_eq!(stats.tcp6_announces_handled(), 0); drop(stats); @@ -1149,7 +1149,7 @@ mod for_all_config_modes { let stats = env.container.http_tracker_core_container.stats_repository.get_stats().await; - assert_eq!(stats.tcp4_scrapes_handled, 1); + assert_eq!(stats.tcp4_scrapes_handled(), 1); drop(stats); @@ -1181,7 +1181,7 @@ mod for_all_config_modes { let stats = env.container.http_tracker_core_container.stats_repository.get_stats().await; - assert_eq!(stats.tcp6_scrapes_handled, 1); + assert_eq!(stats.tcp6_scrapes_handled(), 1); drop(stats); diff --git a/packages/axum-rest-tracker-api-server/src/v1/context/stats/handlers.rs b/packages/axum-rest-tracker-api-server/src/v1/context/stats/handlers.rs index b907b861a..1b1f670a0 100644 --- a/packages/axum-rest-tracker-api-server/src/v1/context/stats/handlers.rs +++ b/packages/axum-rest-tracker-api-server/src/v1/context/stats/handlers.rs @@ -41,21 +41,13 @@ pub struct QueryParams { pub async fn get_stats_handler( State(state): State<( Arc, - Arc>, Arc, Arc, Arc, )>, params: Query, ) -> Response { - let metrics = get_metrics( - state.0.clone(), - state.1.clone(), - state.2.clone(), - state.3.clone(), - state.4.clone(), - ) - .await; + let metrics = get_metrics(state.0.clone(), state.1.clone(), state.2.clone(), state.3.clone()).await; match params.0.format { Some(format) => match format { diff --git a/packages/axum-rest-tracker-api-server/src/v1/context/stats/routes.rs b/packages/axum-rest-tracker-api-server/src/v1/context/stats/routes.rs index c2a1466e0..2bf3776fd 100644 --- a/packages/axum-rest-tracker-api-server/src/v1/context/stats/routes.rs +++ b/packages/axum-rest-tracker-api-server/src/v1/context/stats/routes.rs @@ -18,7 +18,6 @@ pub fn add(prefix: &str, router: Router, http_api_container: &Arc, now: DurationSinceUnixEpoch) { match event { Event::TcpAnnounce { connection, .. } => { - // Global fixed metrics - - match connection.client_ip_addr() { - IpAddr::V4(_) => { - stats_repository.increase_tcp4_announces().await; - } - IpAddr::V6(_) => { - stats_repository.increase_tcp6_announces().await; - } - } - - // Extendable metrics - let mut label_set = LabelSet::from(connection); label_set.upsert(label_name!("request_kind"), LabelValue::new("announce")); @@ -42,19 +28,6 @@ pub async fn handle_event(event: Event, stats_repository: &Arc, now: }; } Event::TcpScrape { connection } => { - // Global fixed metrics - - match connection.client_ip_addr() { - IpAddr::V4(_) => { - stats_repository.increase_tcp4_scrapes().await; - } - IpAddr::V6(_) => { - stats_repository.increase_tcp6_scrapes().await; - } - } - - // Extendable metrics - let mut label_set = LabelSet::from(connection); label_set.upsert(label_name!("request_kind"), LabelValue::new("scrape")); @@ -113,7 +86,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.tcp4_announces_handled, 1); + assert_eq!(stats.tcp4_announces_handled(), 1); } #[tokio::test] @@ -137,7 +110,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.tcp4_scrapes_handled, 1); + assert_eq!(stats.tcp4_scrapes_handled(), 1); } #[tokio::test] @@ -150,7 +123,7 @@ mod tests { Event::TcpAnnounce { connection: ConnectionContext::new( RemoteClientAddr::new(ResolvedIp::FromSocketAddr(remote_client_ip), Some(8080)), - ServiceBinding::new(Protocol::HTTP, SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 7070)).unwrap(), + ServiceBinding::new(Protocol::HTTP, SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 7070)).unwrap(), ), info_hash: sample_info_hash(), announcement: peer, @@ -162,7 +135,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.tcp6_announces_handled, 1); + assert_eq!(stats.tcp6_announces_handled(), 1); } #[tokio::test] @@ -178,7 +151,7 @@ mod tests { ))), Some(8080), ), - ServiceBinding::new(Protocol::HTTP, SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 7070)).unwrap(), + ServiceBinding::new(Protocol::HTTP, SocketAddr::new(IpAddr::V6(Ipv6Addr::LOCALHOST), 7070)).unwrap(), ), }, &stats_repository, @@ -188,6 +161,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.tcp6_scrapes_handled, 1); + assert_eq!(stats.tcp6_scrapes_handled(), 1); } } diff --git a/packages/http-tracker-core/src/statistics/metrics.rs b/packages/http-tracker-core/src/statistics/metrics.rs index 650194d43..05acea937 100644 --- a/packages/http-tracker-core/src/statistics/metrics.rs +++ b/packages/http-tracker-core/src/statistics/metrics.rs @@ -1,24 +1,16 @@ use serde::Serialize; use torrust_tracker_metrics::label::LabelSet; use torrust_tracker_metrics::metric::MetricName; +use torrust_tracker_metrics::metric_collection::aggregate::Sum; use torrust_tracker_metrics::metric_collection::{Error, MetricCollection}; +use torrust_tracker_metrics::metric_name; use torrust_tracker_primitives::DurationSinceUnixEpoch; +use crate::statistics::HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL; + /// Metrics collected by the tracker. #[derive(Debug, Clone, PartialEq, Default, Serialize)] pub struct Metrics { - /// Total number of TCP (HTTP tracker) `announce` requests from IPv4 peers. - pub tcp4_announces_handled: u64, - - /// Total number of TCP (HTTP tracker) `scrape` requests from IPv4 peers. - pub tcp4_scrapes_handled: u64, - - /// Total number of TCP (HTTP tracker) `announce` requests from IPv6 peers. - pub tcp6_announces_handled: u64, - - /// Total number of TCP (HTTP tracker) `scrape` requests from IPv6 peers. - pub tcp6_scrapes_handled: u64, - /// A collection of metrics. pub metric_collection: MetricCollection, } @@ -49,3 +41,61 @@ impl Metrics { self.metric_collection.set_gauge(metric_name, labels, value, now) } } + +impl Metrics { + /// Total number of TCP (HTTP tracker) `announce` requests from IPv4 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn tcp4_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of TCP (HTTP tracker) `scrape` requests from IPv4 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn tcp4_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of TCP (HTTP tracker) `announce` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn tcp6_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of TCP (HTTP tracker) `scrape` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn tcp6_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } +} diff --git a/packages/http-tracker-core/src/statistics/mod.rs b/packages/http-tracker-core/src/statistics/mod.rs index b8ca865fa..3ae355471 100644 --- a/packages/http-tracker-core/src/statistics/mod.rs +++ b/packages/http-tracker-core/src/statistics/mod.rs @@ -1,7 +1,6 @@ pub mod event; pub mod metrics; pub mod repository; -pub mod services; use metrics::Metrics; use torrust_tracker_metrics::metric::description::MetricDescription; diff --git a/packages/http-tracker-core/src/statistics/repository.rs b/packages/http-tracker-core/src/statistics/repository.rs index d5e718821..ea027f5c6 100644 --- a/packages/http-tracker-core/src/statistics/repository.rs +++ b/packages/http-tracker-core/src/statistics/repository.rs @@ -33,30 +33,6 @@ impl Repository { self.stats.read().await } - pub async fn increase_tcp4_announces(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.tcp4_announces_handled += 1; - drop(stats_lock); - } - - pub async fn increase_tcp4_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.tcp4_scrapes_handled += 1; - drop(stats_lock); - } - - pub async fn increase_tcp6_announces(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.tcp6_announces_handled += 1; - drop(stats_lock); - } - - pub async fn increase_tcp6_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.tcp6_scrapes_handled += 1; - drop(stats_lock); - } - /// # Errors /// /// This function will return an error if the metric collection fails to diff --git a/packages/http-tracker-core/src/statistics/services.rs b/packages/http-tracker-core/src/statistics/services.rs deleted file mode 100644 index dbc096030..000000000 --- a/packages/http-tracker-core/src/statistics/services.rs +++ /dev/null @@ -1,117 +0,0 @@ -//! Statistics services. -//! -//! It includes: -//! -//! - A [`factory`](crate::statistics::setup::factory) function to build the structs needed to collect the tracker metrics. -//! - A [`get_metrics`] service to get the tracker [`metrics`](crate::statistics::metrics::Metrics). -//! -//! Tracker metrics are collected using a Publisher-Subscribe pattern. -//! -//! The factory function builds two structs: -//! -//! - An statistics event [`Sender`](torrust_tracker_events::sender::Sender) -//! - An statistics [`Repository`] -//! -//! ```text -//! let (stats_event_sender, stats_repository) = factory(tracker_usage_statistics); -//! ``` -//! -//! The statistics repository is responsible for storing the metrics in memory. -//! The statistics event sender allows sending events related to metrics. -//! There is an event listener that is receiving all the events and processing them with an event handler. -//! Then, the event handler updates the metrics depending on the received event. -use std::sync::Arc; - -use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; -use torrust_tracker_primitives::swarm_metadata::AggregateActiveSwarmMetadata; - -use crate::statistics::metrics::Metrics; -use crate::statistics::repository::Repository; - -/// All the metrics collected by the tracker. -#[derive(Debug, PartialEq)] -pub struct TrackerMetrics { - /// Domain level metrics. - /// - /// General metrics for all torrents (number of seeders, leechers, etcetera) - pub torrents_metrics: AggregateActiveSwarmMetadata, - - /// Application level metrics. Usage statistics/metrics. - /// - /// Metrics about how the tracker is been used (number of number of http scrape requests, etcetera) - pub protocol_metrics: Metrics, -} - -/// It returns all the [`TrackerMetrics`] -pub async fn get_metrics( - in_memory_torrent_repository: Arc, - stats_repository: Arc, -) -> TrackerMetrics { - let torrents_metrics = in_memory_torrent_repository.get_aggregate_swarm_metadata().await; - let stats = stats_repository.get_stats().await; - - TrackerMetrics { - torrents_metrics, - protocol_metrics: Metrics { - // TCPv4 - tcp4_announces_handled: stats.tcp4_announces_handled, - tcp4_scrapes_handled: stats.tcp4_scrapes_handled, - // TCPv6 - tcp6_announces_handled: stats.tcp6_announces_handled, - tcp6_scrapes_handled: stats.tcp6_scrapes_handled, - // Samples - metric_collection: stats.metric_collection.clone(), - }, - } -} - -#[cfg(test)] -mod tests { - use std::sync::Arc; - - use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; - use bittorrent_tracker_core::{self}; - use torrust_tracker_configuration::Configuration; - use torrust_tracker_primitives::swarm_metadata::AggregateActiveSwarmMetadata; - use torrust_tracker_test_helpers::configuration; - - use crate::event::bus::EventBus; - use crate::event::sender::Broadcaster; - use crate::statistics::describe_metrics; - use crate::statistics::event::listener::run_event_listener; - use crate::statistics::repository::Repository; - use crate::statistics::services::{get_metrics, TrackerMetrics}; - - pub fn tracker_configuration() -> Configuration { - configuration::ephemeral() - } - - #[tokio::test] - async fn the_statistics_service_should_return_the_tracker_metrics() { - let config = tracker_configuration(); - - let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default()); - - // HTTP core stats - let http_core_broadcaster = Broadcaster::default(); - let http_stats_repository = Arc::new(Repository::new()); - let http_stats_event_bus = Arc::new(EventBus::new( - config.core.tracker_usage_statistics.into(), - http_core_broadcaster.clone(), - )); - - if config.core.tracker_usage_statistics { - let _unused = run_event_listener(http_stats_event_bus.receiver(), &http_stats_repository); - } - - let tracker_metrics = get_metrics(in_memory_torrent_repository.clone(), http_stats_repository).await; - - assert_eq!( - tracker_metrics, - TrackerMetrics { - torrents_metrics: AggregateActiveSwarmMetadata::default(), - protocol_metrics: describe_metrics(), - } - ); - } -} diff --git a/packages/rest-tracker-api-core/Cargo.toml b/packages/rest-tracker-api-core/Cargo.toml index d9e396960..cc8eda903 100644 --- a/packages/rest-tracker-api-core/Cargo.toml +++ b/packages/rest-tracker-api-core/Cargo.toml @@ -23,7 +23,6 @@ torrust-tracker-metrics = { version = "3.0.0-develop", path = "../metrics" } torrust-tracker-primitives = { version = "3.0.0-develop", path = "../primitives" } torrust-tracker-swarm-coordination-registry = { version = "3.0.0-develop", path = "../swarm-coordination-registry" } torrust-udp-tracker-server = { version = "3.0.0-develop", path = "../udp-tracker-server" } -tracing = "0" [dev-dependencies] torrust-tracker-events = { version = "3.0.0-develop", path = "../events" } diff --git a/packages/rest-tracker-api-core/src/statistics/services.rs b/packages/rest-tracker-api-core/src/statistics/services.rs index 66bacbb06..44c82bfea 100644 --- a/packages/rest-tracker-api-core/src/statistics/services.rs +++ b/packages/rest-tracker-api-core/src/statistics/services.rs @@ -1,20 +1,11 @@ use std::sync::Arc; -use bittorrent_http_tracker_core::statistics::HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL; use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; use bittorrent_udp_tracker_core::services::banning::BanService; use bittorrent_udp_tracker_core::{self}; use tokio::sync::RwLock; -use torrust_tracker_metrics::label::LabelSet; -use torrust_tracker_metrics::metric_collection::aggregate::Sum; use torrust_tracker_metrics::metric_collection::MetricCollection; -use torrust_tracker_metrics::metric_name; -use torrust_udp_tracker_server::statistics::{ - self as udp_server_statistics, UDP_TRACKER_SERVER_ERRORS_TOTAL, UDP_TRACKER_SERVER_IPS_BANNED_TOTAL, - UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS, UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL, - UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL, UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL, - UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL, UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL, -}; +use torrust_udp_tracker_server::statistics::{self as udp_server_statistics}; use super::metrics::TorrentsMetrics; use crate::statistics::metrics::ProtocolMetrics; @@ -36,39 +27,13 @@ pub struct TrackerMetrics { /// It returns all the [`TrackerMetrics`] pub async fn get_metrics( in_memory_torrent_repository: Arc, - ban_service: Arc>, tracker_core_stats_repository: Arc, http_stats_repository: Arc, udp_server_stats_repository: Arc, ) -> TrackerMetrics { - let protocol_metrics_from_global_metrics = get_protocol_metrics( - ban_service.clone(), - http_stats_repository.clone(), - udp_server_stats_repository.clone(), - ) - .await; - - let protocol_metrics_from_labeled_metrics = - get_protocol_metrics_from_labeled_metrics(http_stats_repository.clone(), udp_server_stats_repository.clone()).await; - - // todo: - // We keep both metrics until we deploy to production and we can - // ensure that the protocol metrics from labeled metrics are correct. - // After that we can remove the `get_protocol_metrics` function and - // use only the `get_protocol_metrics_from_labeled_metrics` function. - // And also remove the code in repositories to generate the global metrics. - let protocol_metrics = if protocol_metrics_from_global_metrics == protocol_metrics_from_labeled_metrics { - protocol_metrics_from_labeled_metrics - } else { - tracing::warn!("The protocol metrics from global metrics and labeled metrics are different"); - tracing::warn!("Global metrics: {:?}", protocol_metrics_from_global_metrics); - tracing::warn!("Labeled metrics: {:?}", protocol_metrics_from_labeled_metrics); - protocol_metrics_from_global_metrics - }; - TrackerMetrics { torrents_metrics: get_torrents_metrics(in_memory_torrent_repository, tracker_core_stats_repository).await, - protocol_metrics, + protocol_metrics: get_protocol_metrics(http_stats_repository.clone(), udp_server_stats_repository.clone()).await, } } @@ -85,57 +50,9 @@ async fn get_torrents_metrics( torrents_metrics } -#[allow(deprecated)] -async fn get_protocol_metrics( - ban_service: Arc>, - http_stats_repository: Arc, - udp_server_stats_repository: Arc, -) -> ProtocolMetrics { - let udp_banned_ips_total = ban_service.read().await.get_banned_ips_total(); - let http_stats = http_stats_repository.get_stats().await; - let udp_server_stats = udp_server_stats_repository.get_stats().await; - - // For backward compatibility we keep the `tcp4_connections_handled` and - // `tcp6_connections_handled` metrics. They don't make sense for the HTTP - // tracker, but we keep them for now. In new major versions we should remove - // them. - - ProtocolMetrics { - // TCPv4 - tcp4_connections_handled: http_stats.tcp4_announces_handled + http_stats.tcp4_scrapes_handled, - tcp4_announces_handled: http_stats.tcp4_announces_handled, - tcp4_scrapes_handled: http_stats.tcp4_scrapes_handled, - // TCPv6 - tcp6_connections_handled: http_stats.tcp6_announces_handled + http_stats.tcp6_scrapes_handled, - tcp6_announces_handled: http_stats.tcp6_announces_handled, - tcp6_scrapes_handled: http_stats.tcp6_scrapes_handled, - // UDP - udp_requests_aborted: udp_server_stats.udp_requests_aborted, - udp_requests_banned: udp_server_stats.udp_requests_banned, - udp_banned_ips_total: udp_banned_ips_total as u64, - udp_avg_connect_processing_time_ns: udp_server_stats.udp_avg_connect_processing_time_ns, - udp_avg_announce_processing_time_ns: udp_server_stats.udp_avg_announce_processing_time_ns, - udp_avg_scrape_processing_time_ns: udp_server_stats.udp_avg_scrape_processing_time_ns, - // UDPv4 - udp4_requests: udp_server_stats.udp4_requests, - udp4_connections_handled: udp_server_stats.udp4_connections_handled, - udp4_announces_handled: udp_server_stats.udp4_announces_handled, - udp4_scrapes_handled: udp_server_stats.udp4_scrapes_handled, - udp4_responses: udp_server_stats.udp4_responses, - udp4_errors_handled: udp_server_stats.udp4_errors_handled, - // UDPv6 - udp6_requests: udp_server_stats.udp6_requests, - udp6_connections_handled: udp_server_stats.udp6_connections_handled, - udp6_announces_handled: udp_server_stats.udp6_announces_handled, - udp6_scrapes_handled: udp_server_stats.udp6_scrapes_handled, - udp6_responses: udp_server_stats.udp6_responses, - udp6_errors_handled: udp_server_stats.udp6_errors_handled, - } -} - #[allow(deprecated)] #[allow(clippy::too_many_lines)] -async fn get_protocol_metrics_from_labeled_metrics( +async fn get_protocol_metrics( http_stats_repository: Arc, udp_server_stats_repository: Arc, ) -> ProtocolMetrics { @@ -156,246 +73,40 @@ async fn get_protocol_metrics_from_labeled_metrics( // TCPv4 - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let tcp4_announces_handled = http_stats - .metric_collection - .sum( - &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet"), ("request_kind", "announce")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let tcp4_scrapes_handled = http_stats - .metric_collection - .sum( - &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet"), ("request_kind", "scrape")].into(), - ) - .unwrap_or_default() - .value() as u64; + let tcp4_announces_handled = http_stats.tcp4_announces_handled(); + let tcp4_scrapes_handled = http_stats.tcp4_scrapes_handled(); // TCPv6 - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let tcp6_announces_handled = http_stats - .metric_collection - .sum( - &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet6"), ("request_kind", "announce")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let tcp6_scrapes_handled = http_stats - .metric_collection - .sum( - &metric_name!(HTTP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet6"), ("request_kind", "scrape")].into(), - ) - .unwrap_or_default() - .value() as u64; + let tcp6_announces_handled = http_stats.tcp6_announces_handled(); + let tcp6_scrapes_handled = http_stats.tcp6_scrapes_handled(); // UDP - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_requests_aborted = udp_server_stats - .metric_collection - .sum(&metric_name!(UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL), &LabelSet::empty()) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_requests_banned = udp_server_stats - .metric_collection - .sum(&metric_name!(UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL), &LabelSet::empty()) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_banned_ips_total = udp_server_stats - .metric_collection - .sum(&metric_name!(UDP_TRACKER_SERVER_IPS_BANNED_TOTAL), &LabelSet::empty()) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_avg_connect_processing_time_ns = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), - &[("request_kind", "connect")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_avg_announce_processing_time_ns = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), - &[("request_kind", "announce")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp_avg_scrape_processing_time_ns = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), - &[("request_kind", "scrape")].into(), - ) - .unwrap_or_default() - .value() as u64; + let udp_requests_aborted = udp_server_stats.udp_requests_aborted(); + let udp_requests_banned = udp_server_stats.udp_requests_banned(); + let udp_banned_ips_total = udp_server_stats.udp_banned_ips_total(); + let udp_avg_connect_processing_time_ns = udp_server_stats.udp_avg_connect_processing_time_ns(); + let udp_avg_announce_processing_time_ns = udp_server_stats.udp_avg_announce_processing_time_ns(); + let udp_avg_scrape_processing_time_ns = udp_server_stats.udp_avg_scrape_processing_time_ns(); // UDPv4 - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_requests = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_connections_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet"), ("request_kind", "connect")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_announces_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet"), ("request_kind", "announce")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_scrapes_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet"), ("request_kind", "scrape")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_responses = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL), - &[("server_binding_address_ip_family", "inet")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp4_errors_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_ERRORS_TOTAL), - &[("server_binding_address_ip_family", "inet")].into(), - ) - .unwrap_or_default() - .value() as u64; + let udp4_requests = udp_server_stats.udp4_requests(); + let udp4_connections_handled = udp_server_stats.udp4_connections_handled(); + let udp4_announces_handled = udp_server_stats.udp4_announces_handled(); + let udp4_scrapes_handled = udp_server_stats.udp4_scrapes_handled(); + let udp4_responses = udp_server_stats.udp4_responses(); + let udp4_errors_handled = udp_server_stats.udp4_errors_handled(); // UDPv6 - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_requests = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL), - &[("server_binding_address_ip_family", "inet6")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_connections_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet6"), ("request_kind", "connect")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_announces_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet6"), ("request_kind", "announce")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_scrapes_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), - &[("server_binding_address_ip_family", "inet6"), ("request_kind", "scrape")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_responses = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL), - &[("server_binding_address_ip_family", "inet6")].into(), - ) - .unwrap_or_default() - .value() as u64; - - #[allow(clippy::cast_sign_loss)] - #[allow(clippy::cast_possible_truncation)] - let udp6_errors_handled = udp_server_stats - .metric_collection - .sum( - &metric_name!(UDP_TRACKER_SERVER_ERRORS_TOTAL), - &[("server_binding_address_ip_family", "inet6")].into(), - ) - .unwrap_or_default() - .value() as u64; + let udp6_requests = udp_server_stats.udp6_requests(); + let udp6_connections_handled = udp_server_stats.udp6_connections_handled(); + let udp6_announces_handled = udp_server_stats.udp6_announces_handled(); + let udp6_scrapes_handled = udp_server_stats.udp6_scrapes_handled(); + let udp6_responses = udp_server_stats.udp6_responses(); + let udp6_errors_handled = udp_server_stats.udp6_errors_handled(); // For backward compatibility we keep the `tcp4_connections_handled` and // `tcp6_connections_handled` metrics. They don't make sense for the HTTP @@ -522,7 +233,7 @@ mod tests { let tracker_core_container = TrackerCoreContainer::initialize_from(&core_config, &swarm_coordination_registry_container.clone()); - let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); + let _ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); // HTTP core stats let http_core_broadcaster = Broadcaster::default(); @@ -541,7 +252,6 @@ mod tests { let tracker_metrics = get_metrics( tracker_core_container.in_memory_torrent_repository.clone(), - ban_service.clone(), tracker_core_container.stats_repository.clone(), http_stats_repository.clone(), udp_server_stats_repository.clone(), diff --git a/packages/udp-tracker-core/src/statistics/event/handler.rs b/packages/udp-tracker-core/src/statistics/event/handler.rs index 039b6b0d5..e5d2b87a7 100644 --- a/packages/udp-tracker-core/src/statistics/event/handler.rs +++ b/packages/udp-tracker-core/src/statistics/event/handler.rs @@ -12,19 +12,6 @@ use crate::statistics::UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL; pub async fn handle_event(event: Event, stats_repository: &Repository, now: DurationSinceUnixEpoch) { match event { Event::UdpConnect { connection: context } => { - // Global fixed metrics - - match context.client_socket_addr.ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_connections().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_connections().await; - } - } - - // Extendable metrics - let mut label_set = LabelSet::from(context); label_set.upsert(label_name!("request_kind"), LabelValue::new("connect")); @@ -37,19 +24,6 @@ pub async fn handle_event(event: Event, stats_repository: &Repository, now: Dura }; } Event::UdpAnnounce { connection: context, .. } => { - // Global fixed metrics - - match context.client_socket_addr.ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_announces().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_announces().await; - } - } - - // Extendable metrics - let mut label_set = LabelSet::from(context); label_set.upsert(label_name!("request_kind"), LabelValue::new("announce")); @@ -62,19 +36,6 @@ pub async fn handle_event(event: Event, stats_repository: &Repository, now: Dura }; } Event::UdpScrape { connection: context } => { - // Global fixed metrics - - match context.client_socket_addr.ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_scrapes().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_scrapes().await; - } - } - - // Extendable metrics - let mut label_set = LabelSet::from(context); label_set.upsert(label_name!("request_kind"), LabelValue::new("scrape")); @@ -127,7 +88,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_connections_handled, 1); + assert_eq!(stats.udp4_connections_handled(), 1); } #[tokio::test] @@ -154,7 +115,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_announces_handled, 1); + assert_eq!(stats.udp4_announces_handled(), 1); } #[tokio::test] @@ -179,7 +140,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_scrapes_handled, 1); + assert_eq!(stats.udp4_scrapes_handled(), 1); } #[tokio::test] @@ -204,7 +165,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_connections_handled, 1); + assert_eq!(stats.udp6_connections_handled(), 1); } #[tokio::test] @@ -231,7 +192,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_announces_handled, 1); + assert_eq!(stats.udp6_announces_handled(), 1); } #[tokio::test] @@ -256,6 +217,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_scrapes_handled, 1); + assert_eq!(stats.udp6_scrapes_handled(), 1); } } diff --git a/packages/udp-tracker-core/src/statistics/metrics.rs b/packages/udp-tracker-core/src/statistics/metrics.rs index e6ff8d5f6..57838c66f 100644 --- a/packages/udp-tracker-core/src/statistics/metrics.rs +++ b/packages/udp-tracker-core/src/statistics/metrics.rs @@ -1,37 +1,15 @@ use serde::Serialize; use torrust_tracker_metrics::label::LabelSet; use torrust_tracker_metrics::metric::MetricName; +use torrust_tracker_metrics::metric_collection::aggregate::Sum; use torrust_tracker_metrics::metric_collection::{Error, MetricCollection}; +use torrust_tracker_metrics::metric_name; use torrust_tracker_primitives::DurationSinceUnixEpoch; -/// Metrics collected by the tracker. -/// -/// - Number of connections handled -/// - Number of `announce` requests handled -/// - Number of `scrape` request handled -/// -/// These metrics are collected for each connection type: UDP and HTTP -/// and also for each IP version used by the peers: IPv4 and IPv6. +use crate::statistics::UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL; + #[derive(Debug, PartialEq, Default, Serialize)] pub struct Metrics { - /// Total number of UDP (UDP tracker) connections from IPv4 peers. - pub udp4_connections_handled: u64, - - /// Total number of UDP (UDP tracker) `announce` requests from IPv4 peers. - pub udp4_announces_handled: u64, - - /// Total number of UDP (UDP tracker) `scrape` requests from IPv4 peers. - pub udp4_scrapes_handled: u64, - - /// Total number of UDP (UDP tracker) `connection` requests from IPv6 peers. - pub udp6_connections_handled: u64, - - /// Total number of UDP (UDP tracker) `announce` requests from IPv6 peers. - pub udp6_announces_handled: u64, - - /// Total number of UDP (UDP tracker) `scrape` requests from IPv6 peers. - pub udp6_scrapes_handled: u64, - /// A collection of metrics. pub metric_collection: MetricCollection, } @@ -64,3 +42,89 @@ impl Metrics { self.metric_collection.set_gauge(metric_name, labels, value, now) } } + +impl Metrics { + /// Total number of UDP (UDP tracker) connections from IPv4 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_connections_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "connect")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of UDP (UDP tracker) `announce` requests from IPv4 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of UDP (UDP tracker) `scrape` requests from IPv4 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of UDP (UDP tracker) `connection` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_connections_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "connect")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of UDP (UDP tracker) `announce` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } + + /// Total number of UDP (UDP tracker) `scrape` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_CORE_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } +} diff --git a/packages/udp-tracker-core/src/statistics/repository.rs b/packages/udp-tracker-core/src/statistics/repository.rs index c68fa14f7..ceee0e369 100644 --- a/packages/udp-tracker-core/src/statistics/repository.rs +++ b/packages/udp-tracker-core/src/statistics/repository.rs @@ -33,42 +33,6 @@ impl Repository { self.stats.read().await } - pub async fn increase_udp4_connections(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_connections_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp4_announces(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_announces_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp4_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_scrapes_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_connections(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_connections_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_announces(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_announces_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_scrapes_handled += 1; - drop(stats_lock); - } - /// # Errors /// /// This function will return an error if the metric collection fails to diff --git a/packages/udp-tracker-core/src/statistics/services.rs b/packages/udp-tracker-core/src/statistics/services.rs index 24d25a25c..18a80bad1 100644 --- a/packages/udp-tracker-core/src/statistics/services.rs +++ b/packages/udp-tracker-core/src/statistics/services.rs @@ -69,15 +69,6 @@ pub async fn get_metrics( TrackerMetrics { torrents_metrics, protocol_metrics: Metrics { - // UDPv4 - udp4_connections_handled: stats.udp4_connections_handled, - udp4_announces_handled: stats.udp4_announces_handled, - udp4_scrapes_handled: stats.udp4_scrapes_handled, - // UDPv6 - udp6_connections_handled: stats.udp6_connections_handled, - udp6_announces_handled: stats.udp6_announces_handled, - udp6_scrapes_handled: stats.udp6_scrapes_handled, - // Extendable metrics metric_collection: stats.metric_collection.clone(), }, } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/error.rs b/packages/udp-tracker-server/src/statistics/event/handler/error.rs index 7bde032fe..d83a0584d 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/error.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/error.rs @@ -14,21 +14,9 @@ pub async fn handle_event( repository: &Repository, now: DurationSinceUnixEpoch, ) { - update_global_fixed_metrics(&connection_context, repository).await; update_extendable_metrics(&connection_context, opt_udp_request_kind, error_kind, repository, now).await; } -async fn update_global_fixed_metrics(connection_context: &ConnectionContext, repository: &Repository) { - match connection_context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - repository.increase_udp4_errors().await; - } - std::net::IpAddr::V6(_) => { - repository.increase_udp6_errors().await; - } - } -} - async fn update_extendable_metrics( connection_context: &ConnectionContext, opt_udp_request_kind: Option, @@ -149,6 +137,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_errors_handled, 1); + assert_eq!(stats.udp4_errors_handled(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/request_aborted.rs b/packages/udp-tracker-server/src/statistics/event/handler/request_aborted.rs index fc701df75..19e410d5e 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/request_aborted.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/request_aborted.rs @@ -7,10 +7,6 @@ use crate::statistics::repository::Repository; use crate::statistics::UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL; pub async fn handle_event(context: ConnectionContext, stats_repository: &Repository, now: DurationSinceUnixEpoch) { - // Global fixed metrics - stats_repository.increase_udp_requests_aborted().await; - - // Extendable metrics match stats_repository .increase_counter( &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL), @@ -58,7 +54,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp_requests_aborted, 1); + assert_eq!(stats.udp_requests_aborted(), 1); } #[tokio::test] @@ -81,6 +77,6 @@ mod tests { ) .await; let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp_requests_aborted, 1); + assert_eq!(stats.udp_requests_aborted(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/request_accepted.rs b/packages/udp-tracker-server/src/statistics/event/handler/request_accepted.rs index 37b668227..af92636df 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/request_accepted.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/request_accepted.rs @@ -12,35 +12,6 @@ pub async fn handle_event( stats_repository: &Repository, now: DurationSinceUnixEpoch, ) { - // Global fixed metrics - match kind { - UdpRequestKind::Connect => match context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_connections().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_connections().await; - } - }, - UdpRequestKind::Announce { .. } => match context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_announces().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_announces().await; - } - }, - UdpRequestKind::Scrape => match context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_scrapes().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_scrapes().await; - } - }, - } - - // Extendable metrics let mut label_set = LabelSet::from(context); label_set.upsert(label_name!("request_kind"), LabelValue::new(&kind.to_string())); match stats_repository @@ -90,7 +61,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_connections_handled, 1); + assert_eq!(stats.udp4_connections_handled(), 1); } #[tokio::test] @@ -118,7 +89,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_announces_handled, 1); + assert_eq!(stats.udp4_announces_handled(), 1); } #[tokio::test] @@ -144,7 +115,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_scrapes_handled, 1); + assert_eq!(stats.udp4_scrapes_handled(), 1); } #[tokio::test] @@ -170,7 +141,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_connections_handled, 1); + assert_eq!(stats.udp6_connections_handled(), 1); } #[tokio::test] @@ -198,7 +169,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_announces_handled, 1); + assert_eq!(stats.udp6_announces_handled(), 1); } #[tokio::test] @@ -224,6 +195,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_scrapes_handled, 1); + assert_eq!(stats.udp6_scrapes_handled(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/request_banned.rs b/packages/udp-tracker-server/src/statistics/event/handler/request_banned.rs index ce6e179a3..8badfa137 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/request_banned.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/request_banned.rs @@ -7,10 +7,6 @@ use crate::statistics::repository::Repository; use crate::statistics::UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL; pub async fn handle_event(context: ConnectionContext, stats_repository: &Repository, now: DurationSinceUnixEpoch) { - // Global fixed metrics - stats_repository.increase_udp_requests_banned().await; - - // Extendable metrics match stats_repository .increase_counter( &metric_name!(UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL), @@ -58,7 +54,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp_requests_banned, 1); + assert_eq!(stats.udp_requests_banned(), 1); } #[tokio::test] @@ -81,6 +77,6 @@ mod tests { ) .await; let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp_requests_banned, 1); + assert_eq!(stats.udp_requests_banned(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/request_received.rs b/packages/udp-tracker-server/src/statistics/event/handler/request_received.rs index 89f306f6a..eced5a215 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/request_received.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/request_received.rs @@ -7,17 +7,6 @@ use crate::statistics::repository::Repository; use crate::statistics::UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL; pub async fn handle_event(context: ConnectionContext, stats_repository: &Repository, now: DurationSinceUnixEpoch) { - // Global fixed metrics - match context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_requests().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_requests().await; - } - } - - // Extendable metrics match stats_repository .increase_counter( &metric_name!(UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL), @@ -65,6 +54,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_requests, 1); + assert_eq!(stats.udp4_requests(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/event/handler/response_sent.rs b/packages/udp-tracker-server/src/statistics/event/handler/response_sent.rs index 4e167a10e..7e05e483b 100644 --- a/packages/udp-tracker-server/src/statistics/event/handler/response_sent.rs +++ b/packages/udp-tracker-server/src/statistics/event/handler/response_sent.rs @@ -13,16 +13,6 @@ pub async fn handle_event( stats_repository: &Repository, now: DurationSinceUnixEpoch, ) { - // Global fixed metrics - match context.client_socket_addr().ip() { - std::net::IpAddr::V4(_) => { - stats_repository.increase_udp4_responses().await; - } - std::net::IpAddr::V6(_) => { - stats_repository.increase_udp6_responses().await; - } - } - let (result_label_value, kind_label_value) = match kind { UdpResponseKind::Ok { req_kind } => match req_kind { UdpRequestKind::Connect => { @@ -145,7 +135,7 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp4_responses, 1); + assert_eq!(stats.udp4_responses(), 1); } #[tokio::test] @@ -176,6 +166,6 @@ mod tests { let stats = stats_repository.get_stats().await; - assert_eq!(stats.udp6_responses, 1); + assert_eq!(stats.udp6_responses(), 1); } } diff --git a/packages/udp-tracker-server/src/statistics/metrics.rs b/packages/udp-tracker-server/src/statistics/metrics.rs index ac6250872..8eba248d2 100644 --- a/packages/udp-tracker-server/src/statistics/metrics.rs +++ b/packages/udp-tracker-server/src/statistics/metrics.rs @@ -1,96 +1,296 @@ use serde::Serialize; use torrust_tracker_metrics::label::LabelSet; use torrust_tracker_metrics::metric::MetricName; +use torrust_tracker_metrics::metric_collection::aggregate::Sum; use torrust_tracker_metrics::metric_collection::{Error, MetricCollection}; +use torrust_tracker_metrics::metric_name; use torrust_tracker_primitives::DurationSinceUnixEpoch; +use crate::statistics::{ + UDP_TRACKER_SERVER_ERRORS_TOTAL, UDP_TRACKER_SERVER_IPS_BANNED_TOTAL, UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS, + UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL, UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL, + UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL, UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL, + UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL, +}; + /// Metrics collected by the UDP tracker server. #[derive(Debug, PartialEq, Default, Serialize)] pub struct Metrics { + /// A collection of metrics. + pub metric_collection: MetricCollection, +} + +impl Metrics { + /// # Errors + /// + /// Returns an error if the metric does not exist and it cannot be created. + pub fn increase_counter( + &mut self, + metric_name: &MetricName, + labels: &LabelSet, + now: DurationSinceUnixEpoch, + ) -> Result<(), Error> { + self.metric_collection.increment_counter(metric_name, labels, now) + } + + /// # Errors + /// + /// Returns an error if the metric does not exist and it cannot be created. + pub fn set_gauge( + &mut self, + metric_name: &MetricName, + labels: &LabelSet, + value: f64, + now: DurationSinceUnixEpoch, + ) -> Result<(), Error> { + self.metric_collection.set_gauge(metric_name, labels, value, now) + } +} + +impl Metrics { // UDP /// Total number of UDP (UDP tracker) requests aborted. - pub udp_requests_aborted: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_requests_aborted(&self) -> u64 { + self.metric_collection + .sum(&metric_name!(UDP_TRACKER_SERVER_REQUESTS_ABORTED_TOTAL), &LabelSet::empty()) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) requests banned. - pub udp_requests_banned: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_requests_banned(&self) -> u64 { + self.metric_collection + .sum(&metric_name!(UDP_TRACKER_SERVER_REQUESTS_BANNED_TOTAL), &LabelSet::empty()) + .unwrap_or_default() + .value() as u64 + } /// Total number of banned IPs. - pub udp_banned_ips_total: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_banned_ips_total(&self) -> u64 { + self.metric_collection + .sum(&metric_name!(UDP_TRACKER_SERVER_IPS_BANNED_TOTAL), &LabelSet::empty()) + .unwrap_or_default() + .value() as u64 + } /// Average rounded time spent processing UDP connect requests. - pub udp_avg_connect_processing_time_ns: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_avg_connect_processing_time_ns(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), + &[("request_kind", "connect")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Average rounded time spent processing UDP announce requests. - pub udp_avg_announce_processing_time_ns: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_avg_announce_processing_time_ns(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), + &[("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Average rounded time spent processing UDP scrape requests. - pub udp_avg_scrape_processing_time_ns: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp_avg_scrape_processing_time_ns(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_PERFORMANCE_AVG_PROCESSING_TIME_NS), + &[("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } // UDPv4 /// Total number of UDP (UDP tracker) requests from IPv4 peers. - pub udp4_requests: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_requests(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) connections from IPv4 peers. - pub udp4_connections_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_connections_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "connect")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `announce` requests from IPv4 peers. - pub udp4_announces_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `scrape` requests from IPv4 peers. - pub udp4_scrapes_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) responses from IPv4 peers. - pub udp4_responses: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_responses(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL), + &[("server_binding_address_ip_family", "inet")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `error` requests from IPv4 peers. - pub udp4_errors_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp4_errors_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_ERRORS_TOTAL), + &[("server_binding_address_ip_family", "inet")].into(), + ) + .unwrap_or_default() + .value() as u64 + } // UDPv6 /// Total number of UDP (UDP tracker) requests from IPv6 peers. - pub udp6_requests: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_requests(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_RECEIVED_TOTAL), + &[("server_binding_address_ip_family", "inet6")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `connection` requests from IPv6 peers. - pub udp6_connections_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_connections_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "connect")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `announce` requests from IPv6 peers. - pub udp6_announces_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_announces_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "announce")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) `scrape` requests from IPv6 peers. - pub udp6_scrapes_handled: u64, + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_scrapes_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_REQUESTS_ACCEPTED_TOTAL), + &[("server_binding_address_ip_family", "inet6"), ("request_kind", "scrape")].into(), + ) + .unwrap_or_default() + .value() as u64 + } /// Total number of UDP (UDP tracker) responses from IPv6 peers. - pub udp6_responses: u64, - - /// Total number of UDP (UDP tracker) `error` requests from IPv6 peers. - pub udp6_errors_handled: u64, - - /// A collection of metrics. - pub metric_collection: MetricCollection, -} - -impl Metrics { - /// # Errors - /// - /// Returns an error if the metric does not exist and it cannot be created. - pub fn increase_counter( - &mut self, - metric_name: &MetricName, - labels: &LabelSet, - now: DurationSinceUnixEpoch, - ) -> Result<(), Error> { - self.metric_collection.increment_counter(metric_name, labels, now) + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_responses(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_RESPONSES_SENT_TOTAL), + &[("server_binding_address_ip_family", "inet6")].into(), + ) + .unwrap_or_default() + .value() as u64 } - /// # Errors - /// - /// Returns an error if the metric does not exist and it cannot be created. - pub fn set_gauge( - &mut self, - metric_name: &MetricName, - labels: &LabelSet, - value: f64, - now: DurationSinceUnixEpoch, - ) -> Result<(), Error> { - self.metric_collection.set_gauge(metric_name, labels, value, now) + /// Total number of UDP (UDP tracker) `error` requests from IPv6 peers. + #[must_use] + #[allow(clippy::cast_sign_loss)] + #[allow(clippy::cast_possible_truncation)] + pub fn udp6_errors_handled(&self) -> u64 { + self.metric_collection + .sum( + &metric_name!(UDP_TRACKER_SERVER_ERRORS_TOTAL), + &[("server_binding_address_ip_family", "inet6")].into(), + ) + .unwrap_or_default() + .value() as u64 } } diff --git a/packages/udp-tracker-server/src/statistics/repository.rs b/packages/udp-tracker-server/src/statistics/repository.rs index 1a1db89c7..1851b78a8 100644 --- a/packages/udp-tracker-server/src/statistics/repository.rs +++ b/packages/udp-tracker-server/src/statistics/repository.rs @@ -34,70 +34,59 @@ impl Repository { self.stats.read().await } - pub async fn increase_udp_requests_aborted(&self) { + /// # Errors + /// + /// This function will return an error if the metric collection fails to + /// increase the counter. + pub async fn increase_counter( + &self, + metric_name: &MetricName, + labels: &LabelSet, + now: DurationSinceUnixEpoch, + ) -> Result<(), Error> { let mut stats_lock = self.stats.write().await; - stats_lock.udp_requests_aborted += 1; - drop(stats_lock); - } - pub async fn increase_udp_requests_banned(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp_requests_banned += 1; - drop(stats_lock); - } + let result = stats_lock.increase_counter(metric_name, labels, now); - pub async fn increase_udp4_requests(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_requests += 1; drop(stats_lock); - } - pub async fn increase_udp4_connections(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_connections_handled += 1; - drop(stats_lock); + result } - pub async fn increase_udp4_announces(&self) { + /// # Errors + /// + /// This function will return an error if the metric collection fails to + /// increase the counter. + pub async fn set_gauge( + &self, + metric_name: &MetricName, + labels: &LabelSet, + value: f64, + now: DurationSinceUnixEpoch, + ) -> Result<(), Error> { let mut stats_lock = self.stats.write().await; - stats_lock.udp4_announces_handled += 1; - drop(stats_lock); - } - pub async fn increase_udp4_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_scrapes_handled += 1; - drop(stats_lock); - } + let result = stats_lock.set_gauge(metric_name, labels, value, now); - pub async fn increase_udp4_responses(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_responses += 1; drop(stats_lock); - } - pub async fn increase_udp4_errors(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp4_errors_handled += 1; - drop(stats_lock); + result } #[allow(clippy::cast_precision_loss)] #[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss)] pub async fn recalculate_udp_avg_connect_processing_time_ns(&self, req_processing_time: Duration) -> f64 { - let mut stats_lock = self.stats.write().await; + let stats_lock = self.stats.write().await; let req_processing_time = req_processing_time.as_nanos() as f64; - let udp_connections_handled = (stats_lock.udp4_connections_handled + stats_lock.udp6_connections_handled) as f64; + let udp_connections_handled = (stats_lock.udp4_connections_handled() + stats_lock.udp6_connections_handled()) as f64; - let previous_avg = stats_lock.udp_avg_connect_processing_time_ns; + let previous_avg = stats_lock.udp_avg_connect_processing_time_ns(); // Moving average: https://en.wikipedia.org/wiki/Moving_average let new_avg = previous_avg as f64 + (req_processing_time - previous_avg as f64) / udp_connections_handled; - stats_lock.udp_avg_connect_processing_time_ns = new_avg.ceil() as u64; - drop(stats_lock); new_avg @@ -107,19 +96,17 @@ impl Repository { #[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss)] pub async fn recalculate_udp_avg_announce_processing_time_ns(&self, req_processing_time: Duration) -> f64 { - let mut stats_lock = self.stats.write().await; + let stats_lock = self.stats.write().await; let req_processing_time = req_processing_time.as_nanos() as f64; - let udp_announces_handled = (stats_lock.udp4_announces_handled + stats_lock.udp6_announces_handled) as f64; + let udp_announces_handled = (stats_lock.udp4_announces_handled() + stats_lock.udp6_announces_handled()) as f64; - let previous_avg = stats_lock.udp_avg_announce_processing_time_ns; + let previous_avg = stats_lock.udp_avg_announce_processing_time_ns(); // Moving average: https://en.wikipedia.org/wiki/Moving_average let new_avg = previous_avg as f64 + (req_processing_time - previous_avg as f64) / udp_announces_handled; - stats_lock.udp_avg_announce_processing_time_ns = new_avg.ceil() as u64; - drop(stats_lock); new_avg @@ -129,95 +116,18 @@ impl Repository { #[allow(clippy::cast_possible_truncation)] #[allow(clippy::cast_sign_loss)] pub async fn recalculate_udp_avg_scrape_processing_time_ns(&self, req_processing_time: Duration) -> f64 { - let mut stats_lock = self.stats.write().await; + let stats_lock = self.stats.write().await; let req_processing_time = req_processing_time.as_nanos() as f64; - let udp_scrapes_handled = (stats_lock.udp4_scrapes_handled + stats_lock.udp6_scrapes_handled) as f64; + let udp_scrapes_handled = (stats_lock.udp4_scrapes_handled() + stats_lock.udp6_scrapes_handled()) as f64; - let previous_avg = stats_lock.udp_avg_scrape_processing_time_ns; + let previous_avg = stats_lock.udp_avg_scrape_processing_time_ns(); // Moving average: https://en.wikipedia.org/wiki/Moving_average let new_avg = previous_avg as f64 + (req_processing_time - previous_avg as f64) / udp_scrapes_handled; - stats_lock.udp_avg_scrape_processing_time_ns = new_avg.ceil() as u64; - drop(stats_lock); new_avg } - - pub async fn increase_udp6_requests(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_requests += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_connections(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_connections_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_announces(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_announces_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_scrapes(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_scrapes_handled += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_responses(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_responses += 1; - drop(stats_lock); - } - - pub async fn increase_udp6_errors(&self) { - let mut stats_lock = self.stats.write().await; - stats_lock.udp6_errors_handled += 1; - drop(stats_lock); - } - - /// # Errors - /// - /// This function will return an error if the metric collection fails to - /// increase the counter. - pub async fn increase_counter( - &self, - metric_name: &MetricName, - labels: &LabelSet, - now: DurationSinceUnixEpoch, - ) -> Result<(), Error> { - let mut stats_lock = self.stats.write().await; - - let result = stats_lock.increase_counter(metric_name, labels, now); - - drop(stats_lock); - - result - } - - /// # Errors - /// - /// This function will return an error if the metric collection fails to - /// increase the counter. - pub async fn set_gauge( - &self, - metric_name: &MetricName, - labels: &LabelSet, - value: f64, - now: DurationSinceUnixEpoch, - ) -> Result<(), Error> { - let mut stats_lock = self.stats.write().await; - - let result = stats_lock.set_gauge(metric_name, labels, value, now); - - drop(stats_lock); - - result - } } diff --git a/packages/udp-tracker-server/src/statistics/services.rs b/packages/udp-tracker-server/src/statistics/services.rs index e6e5a28f3..0eac01270 100644 --- a/packages/udp-tracker-server/src/statistics/services.rs +++ b/packages/udp-tracker-server/src/statistics/services.rs @@ -39,8 +39,6 @@ use std::sync::Arc; use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; -use bittorrent_udp_tracker_core::services::banning::BanService; -use tokio::sync::RwLock; use torrust_tracker_primitives::swarm_metadata::AggregateActiveSwarmMetadata; use crate::statistics::metrics::Metrics; @@ -63,38 +61,14 @@ pub struct TrackerMetrics { /// It returns all the [`TrackerMetrics`] pub async fn get_metrics( in_memory_torrent_repository: Arc, - ban_service: Arc>, stats_repository: Arc, ) -> TrackerMetrics { let torrents_metrics = in_memory_torrent_repository.get_aggregate_swarm_metadata().await; let stats = stats_repository.get_stats().await; - let udp_banned_ips_total = ban_service.read().await.get_banned_ips_total(); TrackerMetrics { torrents_metrics, protocol_metrics: Metrics { - // UDP - udp_requests_aborted: stats.udp_requests_aborted, - udp_requests_banned: stats.udp_requests_banned, - udp_banned_ips_total: udp_banned_ips_total as u64, - udp_avg_connect_processing_time_ns: stats.udp_avg_connect_processing_time_ns, - udp_avg_announce_processing_time_ns: stats.udp_avg_announce_processing_time_ns, - udp_avg_scrape_processing_time_ns: stats.udp_avg_scrape_processing_time_ns, - // UDPv4 - udp4_requests: stats.udp4_requests, - udp4_connections_handled: stats.udp4_connections_handled, - udp4_announces_handled: stats.udp4_announces_handled, - udp4_scrapes_handled: stats.udp4_scrapes_handled, - udp4_responses: stats.udp4_responses, - udp4_errors_handled: stats.udp4_errors_handled, - // UDPv6 - udp6_requests: stats.udp6_requests, - udp6_connections_handled: stats.udp6_connections_handled, - udp6_announces_handled: stats.udp6_announces_handled, - udp6_scrapes_handled: stats.udp6_scrapes_handled, - udp6_responses: stats.udp6_responses, - udp6_errors_handled: stats.udp6_errors_handled, - // Extendable metrics metric_collection: stats.metric_collection.clone(), }, } @@ -106,9 +80,6 @@ mod tests { use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; use bittorrent_tracker_core::{self}; - use bittorrent_udp_tracker_core::services::banning::BanService; - use bittorrent_udp_tracker_core::MAX_CONNECTION_ID_ERRORS_PER_IP; - use tokio::sync::RwLock; use torrust_tracker_primitives::swarm_metadata::AggregateActiveSwarmMetadata; use crate::statistics::describe_metrics; @@ -118,16 +89,10 @@ mod tests { #[tokio::test] async fn the_statistics_service_should_return_the_tracker_metrics() { let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default()); - let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); let stats_repository = Arc::new(Repository::new()); - let tracker_metrics = get_metrics( - in_memory_torrent_repository.clone(), - ban_service.clone(), - stats_repository.clone(), - ) - .await; + let tracker_metrics = get_metrics(in_memory_torrent_repository.clone(), stats_repository.clone()).await; assert_eq!( tracker_metrics, diff --git a/packages/udp-tracker-server/tests/server/contract.rs b/packages/udp-tracker-server/tests/server/contract.rs index 0d9540289..2745f3407 100644 --- a/packages/udp-tracker-server/tests/server/contract.rs +++ b/packages/udp-tracker-server/tests/server/contract.rs @@ -273,7 +273,7 @@ mod receiving_an_announce_request { .stats_repository .get_stats() .await - .udp_requests_banned; + .udp_requests_banned(); // This should return a timeout error match client.send(announce_request.into()).await { @@ -289,7 +289,7 @@ mod receiving_an_announce_request { .stats_repository .get_stats() .await - .udp_requests_banned; + .udp_requests_banned(); let udp_banned_ips_total_after = ban_service.read().await.get_banned_ips_total(); // UDP counter for banned requests should be increased by 1