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

Add logs to HTTP tracker #702

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
8 changes: 4 additions & 4 deletions src/console/ci/e2e/logs_parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
use serde::{Deserialize, Serialize};

const UDP_TRACKER_PATTERN: &str = "[UDP Tracker][INFO] Starting on: udp://";
const HTTP_TRACKER_PATTERN: &str = "[HTTP Tracker][INFO] Starting on: ";
const HTTP_TRACKER_PATTERN: &str = "[HTTP TRACKER][INFO] Starting on: ";
const HEALTH_CHECK_PATTERN: &str = "[HEALTH CHECK API][INFO] Starting on: ";

#[derive(Serialize, Deserialize, Debug, Default)]
Expand All @@ -22,8 +22,8 @@ impl RunningServices {
/// 2024-01-24T16:36:14.614898789+00:00 [torrust_tracker::bootstrap::logging][INFO] logging initialized.
/// 2024-01-24T16:36:14.615586025+00:00 [UDP Tracker][INFO] Starting on: udp://0.0.0.0:6969
/// 2024-01-24T16:36:14.615623705+00:00 [torrust_tracker::bootstrap::jobs][INFO] TLS not enabled
/// 2024-01-24T16:36:14.615694484+00:00 [HTTP Tracker][INFO] Starting on: http://0.0.0.0:7070
/// 2024-01-24T16:36:14.615710534+00:00 [HTTP Tracker][INFO] Started on: http://0.0.0.0:7070
/// 2024-01-24T16:36:14.615694484+00:00 [HTTP TRACKER][INFO] Starting on: http://0.0.0.0:7070
/// 2024-01-24T16:36:14.615710534+00:00 [HTTP TRACKER][INFO] Started on: http://0.0.0.0:7070
/// 2024-01-24T16:36:14.615716574+00:00 [torrust_tracker::bootstrap::jobs][INFO] TLS not enabled
/// 2024-01-24T16:36:14.615764904+00:00 [API][INFO] Starting on http://127.0.0.1:1212
/// 2024-01-24T16:36:14.615767264+00:00 [API][INFO] Started on http://127.0.0.1:1212
Expand Down Expand Up @@ -87,7 +87,7 @@ mod tests {
fn it_should_parse_from_logs_with_valid_logs() {
let logs = "\
[UDP Tracker][INFO] Starting on: udp://0.0.0.0:8080\n\
[HTTP Tracker][INFO] Starting on: 0.0.0.0:9090\n\
[HTTP TRACKER][INFO] Starting on: 0.0.0.0:9090\n\
[HEALTH CHECK API][INFO] Starting on: 0.0.0.0:10010";
let running_services = RunningServices::parse_from_logs(logs);

Expand Down
7 changes: 4 additions & 3 deletions src/servers/http/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub struct Launcher {

impl Launcher {
fn start(&self, tracker: Arc<Tracker>, tx_start: Sender<Started>, rx_halt: Receiver<Halted>) -> BoxFuture<'static, ()> {
let app = router(tracker);
let socket = std::net::TcpListener::bind(self.bind_to).expect("Could not bind tcp_listener to address.");
let address = socket.local_addr().expect("Could not get local_addr from tcp_listener.");

Expand All @@ -55,7 +54,9 @@ impl Launcher {
let tls = self.tls.clone();
let protocol = if tls.is_some() { "https" } else { "http" };

info!(target: "HTTP Tracker", "Starting on: {protocol}://{}", address);
info!(target: "HTTP TRACKER", "Starting on: {protocol}://{}", address);

let app = router(tracker, address);

let running = Box::pin(async {
match tls {
Expand All @@ -72,7 +73,7 @@ impl Launcher {
}
});

info!(target: "HTTP Tracker", "Started on: {protocol}://{}", address);
info!(target: "HTTP TRACKER", "Started on: {protocol}://{}", address);

tx_start
.send(Started { address })
Expand Down
55 changes: 54 additions & 1 deletion src/servers/http/v1/routes.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
//! HTTP server routes for version `v1`.
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;

use axum::http::{HeaderName, HeaderValue};
use axum::response::Response;
use axum::routing::get;
use axum::Router;
use axum_client_ip::SecureClientIpSource;
use hyper::Request;
use tower_http::compression::CompressionLayer;
use tower_http::propagate_header::PropagateHeaderLayer;
use tower_http::request_id::{MakeRequestId, RequestId, SetRequestIdLayer};
use tower_http::trace::{DefaultMakeSpan, TraceLayer};
use tracing::{Level, Span};
use uuid::Uuid;

use super::handlers::{announce, health_check, scrape};
use crate::core::Tracker;
Expand All @@ -14,7 +24,7 @@ use crate::core::Tracker;
/// > **NOTICE**: it's added a layer to get the client IP from the connection
/// info. The tracker could use the connection info to get the client IP.
#[allow(clippy::needless_pass_by_value)]
pub fn router(tracker: Arc<Tracker>) -> Router {
pub fn router(tracker: Arc<Tracker>, server_socket_addr: SocketAddr) -> Router {
Router::new()
// Health check
.route("/health_check", get(health_check::handler))
Expand All @@ -27,4 +37,47 @@ pub fn router(tracker: Arc<Tracker>) -> Router {
// Add extension to get the client IP from the connection info
.layer(SecureClientIpSource::ConnectInfo.into_extension())
.layer(CompressionLayer::new())
.layer(SetRequestIdLayer::x_request_id(RequestIdGenerator))
.layer(PropagateHeaderLayer::new(HeaderName::from_static("x-request-id")))
.layer(
TraceLayer::new_for_http()
.make_span_with(DefaultMakeSpan::new().level(Level::INFO))
.on_request(move |request: &Request<axum::body::Body>, _span: &Span| {
let method = request.method().to_string();
let uri = request.uri().to_string();
let request_id = request
.headers()
.get("x-request-id")
.map(|v| v.to_str().unwrap_or_default())
.unwrap_or_default();

tracing::span!(
target:"HTTP TRACKER",
tracing::Level::INFO, "request", server_socket_addr= %server_socket_addr, method = %method, uri = %uri, request_id = %request_id);
})
.on_response(move |response: &Response, latency: Duration, _span: &Span| {
let status_code = response.status();
let request_id = response
.headers()
.get("x-request-id")
.map(|v| v.to_str().unwrap_or_default())
.unwrap_or_default();
let latency_ms = latency.as_millis();

tracing::span!(
target: "HTTP TRACKER",
tracing::Level::INFO, "response", server_socket_addr= %server_socket_addr, latency = %latency_ms, status = %status_code, request_id = %request_id);
}),
)
.layer(SetRequestIdLayer::x_request_id(RequestIdGenerator))
}

#[derive(Clone, Default)]
struct RequestIdGenerator;

impl MakeRequestId for RequestIdGenerator {
fn make_request_id<B>(&mut self, _request: &Request<B>) -> Option<RequestId> {
let id = HeaderValue::from_str(&Uuid::new_v4().to_string()).expect("UUID is a valid HTTP header value");
Some(RequestId::new(id))
}
}
Loading