Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore:[#674] Tracker Checker: Ouput in JSON #810

Merged
merged 3 commits into from
Apr 24, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ ringbuf = "0"
serde = { version = "1", features = ["derive"] }
serde_bencode = "0"
serde_bytes = "0"
serde_json = "1"
serde_json = { version = "1", features = ["preserve_order"] }
serde_repr = "0"
thiserror = "1"
tokio = { version = "1", features = ["macros", "net", "rt-multi-thread", "signal", "sync"] }
Expand Down
53 changes: 26 additions & 27 deletions src/console/clients/checker/checks/health.rs
Original file line number Diff line number Diff line change
@@ -1,51 +1,50 @@
use std::time::Duration;

use colored::Colorize;
use reqwest::{Client as HttpClient, Url, Url as ServiceUrl};

use crate::console::clients::checker::console::Console;
use crate::console::clients::checker::printer::Printer;
use crate::console::clients::checker::service::{CheckError, CheckResult};

pub async fn run(health_checks: &Vec<ServiceUrl>, console: &Console, check_results: &mut Vec<CheckResult>) {
console.println("Health checks ...");
use super::structs::{CheckerOutput, Status};

#[allow(clippy::missing_panics_doc)]
pub async fn run(health_checks: &Vec<ServiceUrl>, check_results: &mut Vec<CheckResult>) -> Vec<CheckerOutput> {

Check warning on line 10 in src/console/clients/checker/checks/health.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/health.rs#L10

Added line #L10 was not covered by tests
let mut health_checkers: Vec<CheckerOutput> = Vec::new();

for health_check_url in health_checks {
match run_health_check(health_check_url.clone(), console).await {
Ok(()) => check_results.push(Ok(())),
Err(err) => check_results.push(Err(err)),
let mut health_checker = CheckerOutput {
url: health_check_url.to_string(),
status: Status {
code: String::new(),
message: String::new(),
},
};
match run_health_check(health_check_url.clone()).await {
Ok(()) => {
check_results.push(Ok(()));
health_checker.status.code = "ok".to_string();
}
Err(err) => {
check_results.push(Err(err));
health_checker.status.code = "error".to_string();
health_checker.status.message = "Health API is failing.".to_string();
}
}
health_checkers.push(health_checker);
}
health_checkers
}

async fn run_health_check(url: Url, console: &Console) -> Result<(), CheckError> {
async fn run_health_check(url: Url) -> Result<(), CheckError> {

Check warning on line 37 in src/console/clients/checker/checks/health.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/health.rs#L37

Added line #L37 was not covered by tests
let client = HttpClient::builder().timeout(Duration::from_secs(5)).build().unwrap();

let colored_url = url.to_string().yellow();

match client.get(url.clone()).send().await {
Ok(response) => {
if response.status().is_success() {
console.println(&format!("{} - Health API at {} is OK", "✓".green(), colored_url));
Ok(())
} else {
console.eprintln(&format!(
"{} - Health API at {} is failing: {:?}",
"✗".red(),
colored_url,
response
));
Err(CheckError::HealthCheckError { url })
}
}
Err(err) => {
console.eprintln(&format!(
"{} - Health API at {} is failing: {:?}",
"✗".red(),
colored_url,
err
));
Err(CheckError::HealthCheckError { url })
}
Err(_) => Err(CheckError::HealthCheckError { url }),
}
}
30 changes: 20 additions & 10 deletions src/console/clients/checker/checks/http.rs
Original file line number Diff line number Diff line change
@@ -1,47 +1,57 @@
use std::str::FromStr;

use colored::Colorize;
use log::debug;
use reqwest::Url as ServiceUrl;
use torrust_tracker_primitives::info_hash::InfoHash;
use url::Url;

use crate::console::clients::checker::console::Console;
use crate::console::clients::checker::printer::Printer;
use crate::console::clients::checker::service::{CheckError, CheckResult};
use crate::shared::bit_torrent::tracker::http::client::requests::announce::QueryBuilder;
use crate::shared::bit_torrent::tracker::http::client::responses::announce::Announce;
use crate::shared::bit_torrent::tracker::http::client::responses::scrape;
use crate::shared::bit_torrent::tracker::http::client::{requests, Client};

pub async fn run(http_trackers: &Vec<ServiceUrl>, console: &Console, check_results: &mut Vec<CheckResult>) {
console.println("HTTP trackers ...");
use super::structs::{CheckerOutput, Status};

#[allow(clippy::missing_panics_doc)]
pub async fn run(http_trackers: &Vec<ServiceUrl>, check_results: &mut Vec<CheckResult>) -> Vec<CheckerOutput> {

Check warning on line 17 in src/console/clients/checker/checks/http.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/http.rs#L17

Added line #L17 was not covered by tests
let mut http_checkers: Vec<CheckerOutput> = Vec::new();

for http_tracker in http_trackers {
let colored_tracker_url = http_tracker.to_string().yellow();
let mut http_checker = CheckerOutput {
url: http_tracker.to_string(),
status: Status {
code: String::new(),
message: String::new(),
},
};

match check_http_announce(http_tracker).await {
Ok(()) => {
check_results.push(Ok(()));
console.println(&format!("{} - Announce at {} is OK", "✓".green(), colored_tracker_url));
http_checker.status.code = "ok".to_string();
}
Err(err) => {
check_results.push(Err(err));
console.println(&format!("{} - Announce at {} is failing", "✗".red(), colored_tracker_url));
http_checker.status.code = "error".to_string();
http_checker.status.message = "Announce is failing.".to_string();
}
}

match check_http_scrape(http_tracker).await {
Ok(()) => {
check_results.push(Ok(()));
console.println(&format!("{} - Scrape at {} is OK", "✓".green(), colored_tracker_url));
http_checker.status.code = "ok".to_string();
}
Err(err) => {
check_results.push(Err(err));
console.println(&format!("{} - Scrape at {} is failing", "✗".red(), colored_tracker_url));
http_checker.status.code = "error".to_string();
http_checker.status.message = "Scrape is failing.".to_string();
}
}
http_checkers.push(http_checker);
}
http_checkers
}

async fn check_http_announce(tracker_url: &Url) -> Result<(), CheckError> {
Expand Down
1 change: 1 addition & 0 deletions src/console/clients/checker/checks/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod health;
pub mod http;
pub mod structs;
pub mod udp;
12 changes: 12 additions & 0 deletions src/console/clients/checker/checks/structs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize)]

Check warning on line 3 in src/console/clients/checker/checks/structs.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/structs.rs#L3

Added line #L3 was not covered by tests
pub struct Status {
pub code: String,
pub message: String,
}
#[derive(Serialize, Deserialize)]

Check warning on line 8 in src/console/clients/checker/checks/structs.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/structs.rs#L8

Added line #L8 was not covered by tests
pub struct CheckerOutput {
pub url: String,
pub status: Status,
}
42 changes: 25 additions & 17 deletions src/console/clients/checker/checks/udp.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,32 @@
use std::net::SocketAddr;

use aquatic_udp_protocol::{Port, TransactionId};
use colored::Colorize;
use hex_literal::hex;
use log::debug;
use torrust_tracker_primitives::info_hash::InfoHash;

use crate::console::clients::checker::console::Console;
use crate::console::clients::checker::printer::Printer;
use crate::console::clients::checker::service::{CheckError, CheckResult};
use crate::console::clients::udp::checker;

use crate::console::clients::checker::checks::structs::{CheckerOutput, Status};

const ASSIGNED_BY_OS: u16 = 0;
const RANDOM_TRANSACTION_ID: i32 = -888_840_697;

pub async fn run(udp_trackers: &Vec<SocketAddr>, console: &Console, check_results: &mut Vec<CheckResult>) {
console.println("UDP trackers ...");
#[allow(clippy::missing_panics_doc)]
pub async fn run(udp_trackers: &Vec<SocketAddr>, check_results: &mut Vec<CheckResult>) -> Vec<CheckerOutput> {

Check warning on line 17 in src/console/clients/checker/checks/udp.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/checks/udp.rs#L17

Added line #L17 was not covered by tests
let mut udp_checkers: Vec<CheckerOutput> = Vec::new();

for udp_tracker in udp_trackers {
debug!("UDP tracker: {:?}", udp_tracker);
let mut checker_output = CheckerOutput {
url: udp_tracker.to_string(),
status: Status {
code: String::new(),
message: String::new(),
},
};

let colored_tracker_url = udp_tracker.to_string().yellow();
debug!("UDP tracker: {:?}", udp_tracker);

let transaction_id = TransactionId(RANDOM_TRANSACTION_ID);

Expand All @@ -32,7 +38,8 @@
check_results.push(Err(CheckError::UdpError {
socket_addr: *udp_tracker,
}));
console.println(&format!("{} - Can't connect to socket {}", "✗".red(), colored_tracker_url));
checker_output.status.code = "error".to_string();
checker_output.status.message = "Can't connect to socket.".to_string();
break;
};

Expand All @@ -42,11 +49,8 @@
check_results.push(Err(CheckError::UdpError {
socket_addr: *udp_tracker,
}));
console.println(&format!(
"{} - Can't make tracker connection request to {}",
"✗".red(),
colored_tracker_url
));
checker_output.status.code = "error".to_string();
checker_output.status.message = "Can't make tracker connection request.".to_string();
break;
};

Expand All @@ -60,13 +64,14 @@
.is_ok()
{
check_results.push(Ok(()));
console.println(&format!("{} - Announce at {} is OK", "✓".green(), colored_tracker_url));
checker_output.status.code = "ok".to_string();
} else {
let err = CheckError::UdpError {
socket_addr: *udp_tracker,
};
check_results.push(Err(err));
console.println(&format!("{} - Announce at {} is failing", "✗".red(), colored_tracker_url));
checker_output.status.code = "error".to_string();
checker_output.status.message = "Announce is failing.".to_string();
}

debug!("Send scrape request");
Expand All @@ -75,13 +80,16 @@

if (client.send_scrape_request(connection_id, transaction_id, info_hashes).await).is_ok() {
check_results.push(Ok(()));
console.println(&format!("{} - Announce at {} is OK", "✓".green(), colored_tracker_url));
checker_output.status.code = "ok".to_string();
} else {
let err = CheckError::UdpError {
socket_addr: *udp_tracker,
};
check_results.push(Err(err));
console.println(&format!("{} - Announce at {} is failing", "✗".red(), colored_tracker_url));
checker_output.status.code = "error".to_string();
checker_output.status.message = "Scrape is failing.".to_string();
}
udp_checkers.push(checker_output);
}
udp_checkers
}
13 changes: 9 additions & 4 deletions src/console/clients/checker/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::sync::Arc;

use reqwest::Url;

use super::checks;
use super::checks::{self};
use super::config::Configuration;
use super::console::Console;
use crate::console::clients::checker::printer::Printer;
Expand All @@ -26,16 +26,21 @@ impl Service {
/// # Errors
///
/// Will return OK is all checks pass or an array with the check errors.
#[allow(clippy::missing_panics_doc)]
pub async fn run_checks(&self) -> Vec<CheckResult> {
self.console.println("Running checks for trackers ...");

let mut check_results = vec![];

checks::udp::run(&self.config.udp_trackers, &self.console, &mut check_results).await;
let udp_checkers = checks::udp::run(&self.config.udp_trackers, &mut check_results).await;

checks::http::run(&self.config.http_trackers, &self.console, &mut check_results).await;
let http_checkers = checks::http::run(&self.config.http_trackers, &mut check_results).await;

checks::health::run(&self.config.health_checks, &self.console, &mut check_results).await;
let health_checkers = checks::health::run(&self.config.health_checks, &mut check_results).await;

let json_output =
serde_json::json!({ "udp_trackers": udp_checkers, "http_trackers": http_checkers, "health_checks": health_checkers });
self.console.println(&serde_json::to_string_pretty(&json_output).unwrap());

check_results
}
Expand Down
Loading