Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
206 changes: 191 additions & 15 deletions packages/torrent-repository/src/statistics/event/handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ use torrust_tracker_primitives::DurationSinceUnixEpoch;
use crate::event::Event;
use crate::statistics::repository::Repository;
use crate::statistics::{
TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL, TORRENT_REPOSITORY_TORRENTS_DOWNLOADS_TOTAL, TORRENT_REPOSITORY_TORRENTS_TOTAL,
TORRENT_REPOSITORY_PEERS_ADDED_TOTAL, TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL, TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL,
TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL, TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL,
TORRENT_REPOSITORY_TORRENTS_DOWNLOADS_TOTAL, TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL, TORRENT_REPOSITORY_TORRENTS_TOTAL,
};

pub async fn handle_event(event: Event, stats_repository: &Arc<Repository>, now: DurationSinceUnixEpoch) {
Expand All @@ -20,36 +22,56 @@ pub async fn handle_event(event: Event, stats_repository: &Arc<Repository>, now:
let _unused = stats_repository
.increment_gauge(&metric_name!(TORRENT_REPOSITORY_TORRENTS_TOTAL), &LabelSet::default(), now)
.await;

let _unused = stats_repository
.increment_counter(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL),
&LabelSet::default(),
now,
)
.await;
}
Event::TorrentRemoved { info_hash } => {
tracing::debug!(info_hash = ?info_hash, "Torrent removed",);

let _unused = stats_repository
.decrement_gauge(&metric_name!(TORRENT_REPOSITORY_TORRENTS_TOTAL), &LabelSet::default(), now)
.await;

let _unused = stats_repository
.increment_counter(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL),
&LabelSet::default(),
now,
)
.await;
}

// Peer events
Event::PeerAdded { info_hash, peer } => {
tracing::debug!(info_hash = ?info_hash, peer = ?peer, "Peer added", );

let label_set = label_set_for_peer(&peer);

let _unused = stats_repository
.increment_gauge(
&metric_name!(TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL),
&label_set_for_peer(&peer),
now,
)
.increment_gauge(&metric_name!(TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL), &label_set, now)
.await;

let _unused = stats_repository
.increment_counter(&metric_name!(TORRENT_REPOSITORY_PEERS_ADDED_TOTAL), &label_set, now)
.await;
}
Event::PeerRemoved { info_hash, peer } => {
tracing::debug!(info_hash = ?info_hash, peer = ?peer, "Peer removed", );

let label_set = label_set_for_peer(&peer);

let _unused = stats_repository
.decrement_gauge(
&metric_name!(TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL),
&label_set_for_peer(&peer),
now,
)
.decrement_gauge(&metric_name!(TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL), &label_set, now)
.await;

let _unused = stats_repository
.increment_counter(&metric_name!(TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL), &label_set, now)
.await;
}
Event::PeerUpdated {
Expand All @@ -76,6 +98,12 @@ pub async fn handle_event(event: Event, stats_repository: &Arc<Repository>, now:
)
.await;
}

let label_set = label_set_for_peer(&new_peer);

let _unused = stats_repository
.increment_counter(&metric_name!(TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL), &label_set, now)
.await;
}
Event::PeerDownloadCompleted { info_hash, peer } => {
tracing::debug!(info_hash = ?info_hash, peer = ?peer, "Peer download completed", );
Expand All @@ -92,7 +120,7 @@ pub async fn handle_event(event: Event, stats_repository: &Arc<Repository>, now:
}

/// Returns the label set to be included in the metrics for the given peer.
fn label_set_for_peer(peer: &Peer) -> LabelSet {
pub(crate) fn label_set_for_peer(peer: &Peer) -> LabelSet {
if peer.is_seeder() {
(label_name!("peer_role"), LabelValue::new("seeder")).into()
} else {
Expand Down Expand Up @@ -135,7 +163,7 @@ mod tests {
opposite_role_peer
}

async fn expect_counter_metric_to_be(
pub async fn expect_counter_metric_to_be(
stats_repository: &Arc<Repository>,
metric_name: &MetricName,
label_set: &LabelSet,
Expand Down Expand Up @@ -186,9 +214,11 @@ mod tests {

use crate::event::Event;
use crate::statistics::event::handler::handle_event;
use crate::statistics::event::handler::tests::expect_gauge_metric_to_be;
use crate::statistics::event::handler::tests::{expect_counter_metric_to_be, expect_gauge_metric_to_be};
use crate::statistics::repository::Repository;
use crate::statistics::TORRENT_REPOSITORY_TORRENTS_TOTAL;
use crate::statistics::{
TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL, TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL, TORRENT_REPOSITORY_TORRENTS_TOTAL,
};
use crate::tests::{sample_info_hash, sample_peer};
use crate::CurrentClock;

Expand Down Expand Up @@ -242,9 +272,73 @@ mod tests {

expect_gauge_metric_to_be(&stats_repository, &metric_name, &label_set, 0.0).await;
}

#[tokio::test]
async fn it_should_increment_the_number_of_torrents_added_when_a_torrent_added_event_is_received() {
clock::Stopped::local_set_to_unix_epoch();

let stats_repository = Arc::new(Repository::new());

handle_event(
Event::TorrentAdded {
info_hash: sample_info_hash(),
announcement: sample_peer(),
},
&stats_repository,
CurrentClock::now(),
)
.await;

expect_counter_metric_to_be(
&stats_repository,
&metric_name!(TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL),
&LabelSet::default(),
1,
)
.await;
}

#[tokio::test]
async fn it_should_increment_the_number_of_torrents_removed_when_a_torrent_removed_event_is_received() {
clock::Stopped::local_set_to_unix_epoch();

let stats_repository = Arc::new(Repository::new());

handle_event(
Event::TorrentRemoved {
info_hash: sample_info_hash(),
},
&stats_repository,
CurrentClock::now(),
)
.await;

expect_counter_metric_to_be(
&stats_repository,
&metric_name!(TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL),
&LabelSet::default(),
1,
)
.await;
}
}

mod for_peer_metrics {
use std::sync::Arc;

use torrust_tracker_clock::clock::stopped::Stopped;
use torrust_tracker_clock::clock::{self, Time};
use torrust_tracker_metrics::metric_name;

use crate::event::Event;
use crate::statistics::event::handler::tests::expect_counter_metric_to_be;
use crate::statistics::event::handler::{handle_event, label_set_for_peer};
use crate::statistics::repository::Repository;
use crate::statistics::{
TORRENT_REPOSITORY_PEERS_ADDED_TOTAL, TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL, TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL,
};
use crate::tests::{sample_info_hash, sample_peer};
use crate::CurrentClock;

mod peer_connections_total {

Expand Down Expand Up @@ -383,6 +477,88 @@ mod tests {
}
}

#[tokio::test]
async fn it_should_increment_the_number_of_peers_added_when_a_peer_added_event_is_received() {
clock::Stopped::local_set_to_unix_epoch();

let stats_repository = Arc::new(Repository::new());

let peer = sample_peer();

handle_event(
Event::PeerAdded {
info_hash: sample_info_hash(),
peer,
},
&stats_repository,
CurrentClock::now(),
)
.await;

expect_counter_metric_to_be(
&stats_repository,
&metric_name!(TORRENT_REPOSITORY_PEERS_ADDED_TOTAL),
&label_set_for_peer(&peer),
1,
)
.await;
}

#[tokio::test]
async fn it_should_increment_the_number_of_peers_removed_when_a_peer_removed_event_is_received() {
clock::Stopped::local_set_to_unix_epoch();

let stats_repository = Arc::new(Repository::new());

let peer = sample_peer();

handle_event(
Event::PeerRemoved {
info_hash: sample_info_hash(),
peer,
},
&stats_repository,
CurrentClock::now(),
)
.await;

expect_counter_metric_to_be(
&stats_repository,
&metric_name!(TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL),
&label_set_for_peer(&peer),
1,
)
.await;
}

#[tokio::test]
async fn it_should_increment_the_number_of_peers_updated_when_a_peer_updated_event_is_received() {
clock::Stopped::local_set_to_unix_epoch();

let stats_repository = Arc::new(Repository::new());

let new_peer = sample_peer();

handle_event(
Event::PeerUpdated {
info_hash: sample_info_hash(),
old_peer: sample_peer(),
new_peer,
},
&stats_repository,
CurrentClock::now(),
)
.await;

expect_counter_metric_to_be(
&stats_repository,
&metric_name!(TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL),
&label_set_for_peer(&new_peer),
1,
)
.await;
}

mod torrent_downloads_total {

use std::sync::Arc;
Expand Down
41 changes: 38 additions & 3 deletions packages/torrent-repository/src/statistics/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,18 @@ use torrust_tracker_metrics::unit::Unit;

// Torrent metrics

const TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL: &str = "torrent_repository_torrents_added_total";
const TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL: &str = "torrent_repository_torrents_removed_total";

const TORRENT_REPOSITORY_TORRENTS_TOTAL: &str = "torrent_repository_torrents_total";
const TORRENT_REPOSITORY_TORRENTS_DOWNLOADS_TOTAL: &str = "torrent_repository_torrents_downloads_total";

// Peers metrics

const TORRENT_REPOSITORY_PEERS_ADDED_TOTAL: &str = "torrent_repository_peers_added_total";
const TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL: &str = "torrent_repository_peers_removed_total";
const TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL: &str = "torrent_repository_peers_updated_total";

const TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL: &str = "torrent_repository_peer_connections_total";
const TORRENT_REPOSITORY_UNIQUE_PEERS_TOTAL: &str = "torrent_repository_unique_peers_total"; // todo: not implemented yet

Expand All @@ -23,6 +30,18 @@ pub fn describe_metrics() -> Metrics {

// Torrent metrics

metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_ADDED_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new("The total number of torrents added.")),
);

metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_REMOVED_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new("The total number of torrents removed.")),
);

metrics.metric_collection.describe_gauge(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_TOTAL),
Some(Unit::Count),
Expand All @@ -32,13 +51,29 @@ pub fn describe_metrics() -> Metrics {
metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_TORRENTS_DOWNLOADS_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new(
"The total number of torrent downloads (since the tracker process started).",
)),
Some(&MetricDescription::new("The total number of torrent downloads.")),
);

// Peers metrics

metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_PEERS_ADDED_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new("The total number of peers added.")),
);

metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_PEERS_REMOVED_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new("The total number of peers removed.")),
);

metrics.metric_collection.describe_counter(
&metric_name!(TORRENT_REPOSITORY_PEERS_UPDATED_TOTAL),
Some(Unit::Count),
Some(&MetricDescription::new("The total number of peers updated.")),
);

metrics.metric_collection.describe_gauge(
&metric_name!(TORRENT_REPOSITORY_PEER_CONNECTIONS_TOTAL),
Some(Unit::Count),
Expand Down
Loading