Skip to content

Commit 30ae6df

Browse files
committed
feat: [torrust#697] add logs to HTTP tracker
Sample logs: ``` 2024-02-19T13:29:02.301023716+00:00 [HTTP TRACKER][INFO] request; server_socket_addr=0.0.0.0:7070 method=GET uri=/scrape?info_hash=%44%3C%76%02%B4%FD%E8%3D%11%54%D6%D9%DA%48%80%84%18%B1%81%B6 request_id=2c4aa57d-dd12-4cb8-95d1-e8193627c106 2024-02-19T13:29:02.301095545+00:00 [HTTP TRACKER][INFO] response; server_socket_addr=0.0.0.0:7070 latency=0 status=200 OK request_id=2c4aa57d-dd12-4cb8-95d1-e8193627c106 ```
1 parent d3344da commit 30ae6df

File tree

3 files changed

+62
-8
lines changed

3 files changed

+62
-8
lines changed

src/console/ci/e2e/logs_parser.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
use serde::{Deserialize, Serialize};
33

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

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

src/servers/http/server.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ pub struct Launcher {
4040

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

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

58-
info!(target: "HTTP Tracker", "Starting on: {protocol}://{}", address);
57+
info!(target: "HTTP TRACKER", "Starting on: {protocol}://{}", address);
58+
59+
let app = router(tracker, address);
5960

6061
let running = Box::pin(async {
6162
match tls {
@@ -72,7 +73,7 @@ impl Launcher {
7273
}
7374
});
7475

75-
info!(target: "HTTP Tracker", "Started on: {protocol}://{}", address);
76+
info!(target: "HTTP TRACKER", "Started on: {protocol}://{}", address);
7677

7778
tx_start
7879
.send(Started { address })

src/servers/http/v1/routes.rs

+54-1
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,20 @@
11
//! HTTP server routes for version `v1`.
2+
use std::net::SocketAddr;
23
use std::sync::Arc;
4+
use std::time::Duration;
35

6+
use axum::http::{HeaderName, HeaderValue};
7+
use axum::response::Response;
48
use axum::routing::get;
59
use axum::Router;
610
use axum_client_ip::SecureClientIpSource;
11+
use hyper::Request;
712
use tower_http::compression::CompressionLayer;
13+
use tower_http::propagate_header::PropagateHeaderLayer;
14+
use tower_http::request_id::{MakeRequestId, RequestId, SetRequestIdLayer};
15+
use tower_http::trace::{DefaultMakeSpan, TraceLayer};
16+
use tracing::{Level, Span};
17+
use uuid::Uuid;
818

919
use super::handlers::{announce, health_check, scrape};
1020
use crate::core::Tracker;
@@ -14,7 +24,7 @@ use crate::core::Tracker;
1424
/// > **NOTICE**: it's added a layer to get the client IP from the connection
1525
/// info. The tracker could use the connection info to get the client IP.
1626
#[allow(clippy::needless_pass_by_value)]
17-
pub fn router(tracker: Arc<Tracker>) -> Router {
27+
pub fn router(tracker: Arc<Tracker>, server_socket_addr: SocketAddr) -> Router {
1828
Router::new()
1929
// Health check
2030
.route("/health_check", get(health_check::handler))
@@ -27,4 +37,47 @@ pub fn router(tracker: Arc<Tracker>) -> Router {
2737
// Add extension to get the client IP from the connection info
2838
.layer(SecureClientIpSource::ConnectInfo.into_extension())
2939
.layer(CompressionLayer::new())
40+
.layer(SetRequestIdLayer::x_request_id(RequestIdGenerator))
41+
.layer(PropagateHeaderLayer::new(HeaderName::from_static("x-request-id")))
42+
.layer(
43+
TraceLayer::new_for_http()
44+
.make_span_with(DefaultMakeSpan::new().level(Level::INFO))
45+
.on_request(move |request: &Request<axum::body::Body>, _span: &Span| {
46+
let method = request.method().to_string();
47+
let uri = request.uri().to_string();
48+
let request_id = request
49+
.headers()
50+
.get("x-request-id")
51+
.map(|v| v.to_str().unwrap_or_default())
52+
.unwrap_or_default();
53+
54+
tracing::span!(
55+
target:"HTTP TRACKER",
56+
tracing::Level::INFO, "request", server_socket_addr= %server_socket_addr, method = %method, uri = %uri, request_id = %request_id);
57+
})
58+
.on_response(move |response: &Response, latency: Duration, _span: &Span| {
59+
let status_code = response.status();
60+
let request_id = response
61+
.headers()
62+
.get("x-request-id")
63+
.map(|v| v.to_str().unwrap_or_default())
64+
.unwrap_or_default();
65+
let latency_ms = latency.as_millis();
66+
67+
tracing::span!(
68+
target: "HTTP TRACKER",
69+
tracing::Level::INFO, "response", server_socket_addr= %server_socket_addr, latency = %latency_ms, status = %status_code, request_id = %request_id);
70+
}),
71+
)
72+
.layer(SetRequestIdLayer::x_request_id(RequestIdGenerator))
73+
}
74+
75+
#[derive(Clone, Default)]
76+
struct RequestIdGenerator;
77+
78+
impl MakeRequestId for RequestIdGenerator {
79+
fn make_request_id<B>(&mut self, _request: &Request<B>) -> Option<RequestId> {
80+
let id = HeaderValue::from_str(&Uuid::new_v4().to_string()).expect("UUID is a valid HTTP header value");
81+
Some(RequestId::new(id))
82+
}
3083
}

0 commit comments

Comments
 (0)