Skip to content

Enable colour in console output #896

New issue

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

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

Already on GitHub? # to your account

Merged
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
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.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ r2d2 = "0"
r2d2_mysql = "24"
r2d2_sqlite = { version = "0", features = ["bundled"] }
rand = "0"
regex = "1.10.5"
reqwest = { version = "0", features = ["json"] }
ringbuf = "0"
serde = { version = "1", features = ["derive"] }
Expand Down
2 changes: 1 addition & 1 deletion src/bootstrap/logging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
}

fn tracing_stdout_init(filter: LevelFilter, style: &TraceStyle) {
let builder = tracing_subscriber::fmt().with_max_level(filter).with_ansi(false);
let builder = tracing_subscriber::fmt().with_max_level(filter).with_ansi(true);

Check warning on line 49 in src/bootstrap/logging.rs

View check run for this annotation

Codecov / codecov/patch

src/bootstrap/logging.rs#L49

Added line #L49 was not covered by tests

let () = match style {
TraceStyle::Default => builder.init(),
Expand Down
58 changes: 44 additions & 14 deletions src/console/ci/e2e/logs_parser.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
//! Utilities to parse Torrust Tracker logs.
use regex::Regex;
use serde::{Deserialize, Serialize};

const UDP_TRACKER_PATTERN: &str = "UDP TRACKER: Started on: udp://";
const HTTP_TRACKER_PATTERN: &str = "HTTP TRACKER: Started on: ";
const HEALTH_CHECK_PATTERN: &str = "HEALTH CHECK API: Started on: ";
const INFO_LOG_LEVEL: &str = "INFO";
const UDP_TRACKER_LOG_TARGET: &str = "UDP TRACKER";
const HTTP_TRACKER_LOG_TARGET: &str = "HTTP TRACKER";
const HEALTH_CHECK_API_LOG_TARGET: &str = "HEALTH CHECK API";

#[derive(Serialize, Deserialize, Debug, Default)]
pub struct RunningServices {
Expand Down Expand Up @@ -52,19 +54,43 @@ impl RunningServices {
///
/// NOTICE: Using colors in the console output could affect this method
/// due to the hidden control chars.
///
/// # Panics
///
/// Will panic is the regular expression to parse the services can't be compiled.
#[must_use]
pub fn parse_from_logs(logs: &str) -> Self {
let mut udp_trackers: Vec<String> = Vec::new();
let mut http_trackers: Vec<String> = Vec::new();
let mut health_checks: Vec<String> = Vec::new();

let udp_re = Regex::new(r"Started on: udp://([0-9.]+:[0-9]+)").unwrap();
let http_re = Regex::new(r"Started on: (https?://[0-9.]+:[0-9]+)").unwrap(); // DevSkim: ignore DS137138
let health_re = Regex::new(r"Started on: (https?://[0-9.]+:[0-9]+)").unwrap(); // DevSkim: ignore DS137138
let ansi_escape_re = Regex::new(r"\x1b\[[0-9;]*m").unwrap();

for line in logs.lines() {
if let Some(address) = Self::extract_address_if_matches(line, UDP_TRACKER_PATTERN) {
udp_trackers.push(address);
} else if let Some(address) = Self::extract_address_if_matches(line, HTTP_TRACKER_PATTERN) {
http_trackers.push(address);
} else if let Some(address) = Self::extract_address_if_matches(line, HEALTH_CHECK_PATTERN) {
health_checks.push(format!("{address}/health_check"));
let clean_line = ansi_escape_re.replace_all(line, "");

if !line.contains(INFO_LOG_LEVEL) {
continue;
};

if line.contains(UDP_TRACKER_LOG_TARGET) {
if let Some(captures) = udp_re.captures(&clean_line) {
let address = Self::replace_wildcard_ip_with_localhost(&captures[1]);
udp_trackers.push(address);
}
} else if line.contains(HTTP_TRACKER_LOG_TARGET) {
if let Some(captures) = http_re.captures(&clean_line) {
let address = Self::replace_wildcard_ip_with_localhost(&captures[1]);
http_trackers.push(address);
}
} else if line.contains(HEALTH_CHECK_API_LOG_TARGET) {
if let Some(captures) = health_re.captures(&clean_line) {
let address = format!("{}/health_check", Self::replace_wildcard_ip_with_localhost(&captures[1]));
health_checks.push(address);
}
}
}

Expand All @@ -75,11 +101,6 @@ impl RunningServices {
}
}

fn extract_address_if_matches(line: &str, pattern: &str) -> Option<String> {
line.find(pattern)
.map(|start| Self::replace_wildcard_ip_with_localhost(line[start + pattern.len()..].trim()))
}

fn replace_wildcard_ip_with_localhost(address: &str) -> String {
address.replace("0.0.0.0", "127.0.0.1")
}
Expand Down Expand Up @@ -127,6 +148,15 @@ mod tests {
assert_eq!(running_services.health_checks, vec!["http://127.0.0.1:1313/health_check"]);
}

#[test]
fn it_should_support_colored_output() {
let logs = "\x1b[2m2024-06-14T14:40:13.028824Z\x1b[0m \x1b[33mINFO\x1b[0m \x1b[2mUDP TRACKER\x1b[0m: \x1b[37mStarted on: udp://0.0.0.0:6969\x1b[0m";

let running_services = RunningServices::parse_from_logs(logs);

assert_eq!(running_services.udp_trackers, vec!["127.0.0.1:6969"]);
}

#[test]
fn it_should_ignore_logs_with_no_matching_lines() {
let logs = "[Other Service][INFO] Started on: 0.0.0.0:7070";
Expand Down
2 changes: 1 addition & 1 deletion src/console/ci/e2e/runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@
}

fn tracing_stdout_init(filter: LevelFilter) {
tracing_subscriber::fmt().with_max_level(filter).with_ansi(false).init();
tracing_subscriber::fmt().with_max_level(filter).init();

Check warning on line 119 in src/console/ci/e2e/runner.rs

View check run for this annotation

Codecov / codecov/patch

src/console/ci/e2e/runner.rs#L119

Added line #L119 was not covered by tests
info!("Logging initialized.");
}

Expand Down
2 changes: 1 addition & 1 deletion src/console/clients/checker/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
}

fn tracing_stdout_init(filter: LevelFilter) {
tracing_subscriber::fmt().with_max_level(filter).with_ansi(false).init();
tracing_subscriber::fmt().with_max_level(filter).init();

Check warning on line 61 in src/console/clients/checker/app.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/checker/app.rs#L61

Added line #L61 was not covered by tests
info!("logging initialized.");
}

Expand Down
2 changes: 1 addition & 1 deletion src/console/clients/udp/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@
}

fn tracing_stdout_init(filter: LevelFilter) {
tracing_subscriber::fmt().with_max_level(filter).with_ansi(false).init();
tracing_subscriber::fmt().with_max_level(filter).init();

Check warning on line 130 in src/console/clients/udp/app.rs

View check run for this annotation

Codecov / codecov/patch

src/console/clients/udp/app.rs#L130

Added line #L130 was not covered by tests
info!("logging initialized.");
}

Expand Down
Loading