|
| 1 | +use std::sync::Arc; |
| 2 | + |
| 3 | +use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; |
| 4 | +use packages::tracker_api_core::statistics::metrics::Metrics; |
| 5 | +use tokio::sync::RwLock; |
| 6 | +use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics; |
| 7 | + |
| 8 | +use crate::packages::{self, http_tracker_core, udp_tracker_core}; |
| 9 | +use crate::servers::udp::server::banning::BanService; |
| 10 | + |
| 11 | +/// All the metrics collected by the tracker. |
| 12 | +#[derive(Debug, PartialEq)] |
| 13 | +pub struct TrackerMetrics { |
| 14 | + /// Domain level metrics. |
| 15 | + /// |
| 16 | + /// General metrics for all torrents (number of seeders, leechers, etcetera) |
| 17 | + pub torrents_metrics: TorrentsMetrics, |
| 18 | + |
| 19 | + /// Application level metrics. Usage statistics/metrics. |
| 20 | + /// |
| 21 | + /// Metrics about how the tracker is been used (number of udp announce requests, number of http scrape requests, etcetera) |
| 22 | + pub protocol_metrics: Metrics, |
| 23 | +} |
| 24 | + |
| 25 | +/// It returns all the [`TrackerMetrics`] |
| 26 | +pub async fn get_metrics( |
| 27 | + in_memory_torrent_repository: Arc<InMemoryTorrentRepository>, |
| 28 | + ban_service: Arc<RwLock<BanService>>, |
| 29 | + http_stats_repository: Arc<http_tracker_core::statistics::repository::Repository>, |
| 30 | + udp_stats_repository: Arc<udp_tracker_core::statistics::repository::Repository>, |
| 31 | +) -> TrackerMetrics { |
| 32 | + let torrents_metrics = in_memory_torrent_repository.get_torrents_metrics(); |
| 33 | + let udp_banned_ips_total = ban_service.read().await.get_banned_ips_total(); |
| 34 | + let http_stats = http_stats_repository.get_stats().await; |
| 35 | + let udp_stats = udp_stats_repository.get_stats().await; |
| 36 | + |
| 37 | + TrackerMetrics { |
| 38 | + torrents_metrics, |
| 39 | + protocol_metrics: Metrics { |
| 40 | + // TCPv4 |
| 41 | + tcp4_connections_handled: http_stats.tcp4_connections_handled, |
| 42 | + tcp4_announces_handled: http_stats.tcp4_announces_handled, |
| 43 | + tcp4_scrapes_handled: http_stats.tcp4_scrapes_handled, |
| 44 | + // TCPv6 |
| 45 | + tcp6_connections_handled: http_stats.tcp6_connections_handled, |
| 46 | + tcp6_announces_handled: http_stats.tcp6_announces_handled, |
| 47 | + tcp6_scrapes_handled: http_stats.tcp6_scrapes_handled, |
| 48 | + // UDP |
| 49 | + udp_requests_aborted: udp_stats.udp_requests_aborted, |
| 50 | + udp_requests_banned: udp_stats.udp_requests_banned, |
| 51 | + udp_banned_ips_total: udp_banned_ips_total as u64, |
| 52 | + udp_avg_connect_processing_time_ns: udp_stats.udp_avg_connect_processing_time_ns, |
| 53 | + udp_avg_announce_processing_time_ns: udp_stats.udp_avg_announce_processing_time_ns, |
| 54 | + udp_avg_scrape_processing_time_ns: udp_stats.udp_avg_scrape_processing_time_ns, |
| 55 | + // UDPv4 |
| 56 | + udp4_requests: udp_stats.udp4_requests, |
| 57 | + udp4_connections_handled: udp_stats.udp4_connections_handled, |
| 58 | + udp4_announces_handled: udp_stats.udp4_announces_handled, |
| 59 | + udp4_scrapes_handled: udp_stats.udp4_scrapes_handled, |
| 60 | + udp4_responses: udp_stats.udp4_responses, |
| 61 | + udp4_errors_handled: udp_stats.udp4_errors_handled, |
| 62 | + // UDPv6 |
| 63 | + udp6_requests: udp_stats.udp6_requests, |
| 64 | + udp6_connections_handled: udp_stats.udp6_connections_handled, |
| 65 | + udp6_announces_handled: udp_stats.udp6_announces_handled, |
| 66 | + udp6_scrapes_handled: udp_stats.udp6_scrapes_handled, |
| 67 | + udp6_responses: udp_stats.udp6_responses, |
| 68 | + udp6_errors_handled: udp_stats.udp6_errors_handled, |
| 69 | + }, |
| 70 | + } |
| 71 | +} |
| 72 | + |
| 73 | +#[cfg(test)] |
| 74 | +mod tests { |
| 75 | + use std::sync::Arc; |
| 76 | + |
| 77 | + use bittorrent_tracker_core::torrent::repository::in_memory::InMemoryTorrentRepository; |
| 78 | + use bittorrent_tracker_core::{self}; |
| 79 | + use tokio::sync::RwLock; |
| 80 | + use torrust_tracker_configuration::Configuration; |
| 81 | + use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics; |
| 82 | + use torrust_tracker_test_helpers::configuration; |
| 83 | + |
| 84 | + use crate::packages::tracker_api_core::statistics::metrics::Metrics; |
| 85 | + use crate::packages::tracker_api_core::statistics::services::{get_metrics, TrackerMetrics}; |
| 86 | + use crate::packages::{http_tracker_core, udp_tracker_core}; |
| 87 | + use crate::servers::udp::server::banning::BanService; |
| 88 | + use crate::servers::udp::server::launcher::MAX_CONNECTION_ID_ERRORS_PER_IP; |
| 89 | + |
| 90 | + pub fn tracker_configuration() -> Configuration { |
| 91 | + configuration::ephemeral() |
| 92 | + } |
| 93 | + |
| 94 | + #[tokio::test] |
| 95 | + async fn the_statistics_service_should_return_the_tracker_metrics() { |
| 96 | + let config = tracker_configuration(); |
| 97 | + |
| 98 | + let in_memory_torrent_repository = Arc::new(InMemoryTorrentRepository::default()); |
| 99 | + let ban_service = Arc::new(RwLock::new(BanService::new(MAX_CONNECTION_ID_ERRORS_PER_IP))); |
| 100 | + |
| 101 | + // HTTP stats |
| 102 | + let (_http_stats_event_sender, http_stats_repository) = |
| 103 | + http_tracker_core::statistics::setup::factory(config.core.tracker_usage_statistics); |
| 104 | + let http_stats_repository = Arc::new(http_stats_repository); |
| 105 | + |
| 106 | + // UDP stats |
| 107 | + let (_udp_stats_event_sender, udp_stats_repository) = |
| 108 | + udp_tracker_core::statistics::setup::factory(config.core.tracker_usage_statistics); |
| 109 | + let udp_stats_repository = Arc::new(udp_stats_repository); |
| 110 | + |
| 111 | + let tracker_metrics = get_metrics( |
| 112 | + in_memory_torrent_repository.clone(), |
| 113 | + ban_service.clone(), |
| 114 | + http_stats_repository.clone(), |
| 115 | + udp_stats_repository.clone(), |
| 116 | + ) |
| 117 | + .await; |
| 118 | + |
| 119 | + assert_eq!( |
| 120 | + tracker_metrics, |
| 121 | + TrackerMetrics { |
| 122 | + torrents_metrics: TorrentsMetrics::default(), |
| 123 | + protocol_metrics: Metrics::default(), |
| 124 | + } |
| 125 | + ); |
| 126 | + } |
| 127 | +} |
0 commit comments