torrust_tracker/servers/apis/v1/context/stats/
resources.rs

1//! API resources for the [`stats`](crate::servers::apis::v1::context::stats)
2//! API context.
3use serde::{Deserialize, Serialize};
4
5use crate::core::services::statistics::TrackerMetrics;
6
7/// It contains all the statistics generated by the tracker.
8#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
9pub struct Stats {
10    // Torrent metrics
11    /// Total number of torrents.
12    pub torrents: u64,
13    /// Total number of seeders for all torrents.
14    pub seeders: u64,
15    /// Total number of peers that have ever completed downloading for all torrents.
16    pub completed: u64,
17    /// Total number of leechers for all torrents.
18    pub leechers: u64,
19
20    // Protocol metrics
21    /// Total number of TCP (HTTP tracker) connections from IPv4 peers.
22    /// Since the HTTP tracker spec does not require a handshake, this metric
23    /// increases for every HTTP request.
24    pub tcp4_connections_handled: u64,
25    /// Total number of TCP (HTTP tracker) `announce` requests from IPv4 peers.
26    pub tcp4_announces_handled: u64,
27    /// Total number of TCP (HTTP tracker) `scrape` requests from IPv4 peers.
28    pub tcp4_scrapes_handled: u64,
29    /// Total number of TCP (HTTP tracker) connections from IPv6 peers.
30    pub tcp6_connections_handled: u64,
31    /// Total number of TCP (HTTP tracker) `announce` requests from IPv6 peers.
32    pub tcp6_announces_handled: u64,
33    /// Total number of TCP (HTTP tracker) `scrape` requests from IPv6 peers.
34    pub tcp6_scrapes_handled: u64,
35    /// Total number of UDP (UDP tracker) connections from IPv4 peers.
36    pub udp4_connections_handled: u64,
37    /// Total number of UDP (UDP tracker) `announce` requests from IPv4 peers.
38    pub udp4_announces_handled: u64,
39    /// Total number of UDP (UDP tracker) `scrape` requests from IPv4 peers.
40    pub udp4_scrapes_handled: u64,
41    /// Total number of UDP (UDP tracker) `connection` requests from IPv6 peers.
42    pub udp6_connections_handled: u64,
43    /// Total number of UDP (UDP tracker) `announce` requests from IPv6 peers.
44    pub udp6_announces_handled: u64,
45    /// Total number of UDP (UDP tracker) `scrape` requests from IPv6 peers.
46    pub udp6_scrapes_handled: u64,
47}
48
49impl From<TrackerMetrics> for Stats {
50    fn from(metrics: TrackerMetrics) -> Self {
51        Self {
52            torrents: metrics.torrents_metrics.torrents,
53            seeders: metrics.torrents_metrics.complete,
54            completed: metrics.torrents_metrics.downloaded,
55            leechers: metrics.torrents_metrics.incomplete,
56            tcp4_connections_handled: metrics.protocol_metrics.tcp4_connections_handled,
57            tcp4_announces_handled: metrics.protocol_metrics.tcp4_announces_handled,
58            tcp4_scrapes_handled: metrics.protocol_metrics.tcp4_scrapes_handled,
59            tcp6_connections_handled: metrics.protocol_metrics.tcp6_connections_handled,
60            tcp6_announces_handled: metrics.protocol_metrics.tcp6_announces_handled,
61            tcp6_scrapes_handled: metrics.protocol_metrics.tcp6_scrapes_handled,
62            udp4_connections_handled: metrics.protocol_metrics.udp4_connections_handled,
63            udp4_announces_handled: metrics.protocol_metrics.udp4_announces_handled,
64            udp4_scrapes_handled: metrics.protocol_metrics.udp4_scrapes_handled,
65            udp6_connections_handled: metrics.protocol_metrics.udp6_connections_handled,
66            udp6_announces_handled: metrics.protocol_metrics.udp6_announces_handled,
67            udp6_scrapes_handled: metrics.protocol_metrics.udp6_scrapes_handled,
68        }
69    }
70}
71
72#[cfg(test)]
73mod tests {
74    use torrust_tracker_primitives::torrent_metrics::TorrentsMetrics;
75
76    use super::Stats;
77    use crate::core::services::statistics::TrackerMetrics;
78    use crate::core::statistics::Metrics;
79
80    #[test]
81    fn stats_resource_should_be_converted_from_tracker_metrics() {
82        assert_eq!(
83            Stats::from(TrackerMetrics {
84                torrents_metrics: TorrentsMetrics {
85                    complete: 1,
86                    downloaded: 2,
87                    incomplete: 3,
88                    torrents: 4
89                },
90                protocol_metrics: Metrics {
91                    tcp4_connections_handled: 5,
92                    tcp4_announces_handled: 6,
93                    tcp4_scrapes_handled: 7,
94                    tcp6_connections_handled: 8,
95                    tcp6_announces_handled: 9,
96                    tcp6_scrapes_handled: 10,
97                    udp4_connections_handled: 11,
98                    udp4_announces_handled: 12,
99                    udp4_scrapes_handled: 13,
100                    udp6_connections_handled: 14,
101                    udp6_announces_handled: 15,
102                    udp6_scrapes_handled: 16
103                }
104            }),
105            Stats {
106                torrents: 4,
107                seeders: 1,
108                completed: 2,
109                leechers: 3,
110                tcp4_connections_handled: 5,
111                tcp4_announces_handled: 6,
112                tcp4_scrapes_handled: 7,
113                tcp6_connections_handled: 8,
114                tcp6_announces_handled: 9,
115                tcp6_scrapes_handled: 10,
116                udp4_connections_handled: 11,
117                udp4_announces_handled: 12,
118                udp4_scrapes_handled: 13,
119                udp6_connections_handled: 14,
120                udp6_announces_handled: 15,
121                udp6_scrapes_handled: 16
122            }
123        );
124    }
125}