Skip to content

Commit 0f40030

Browse files
committed
Merge #1151: Override tower-http tracing errors
9ac676c feat: [#1146] override tower-http tracing error (Jose Celano) Pull request description: This overrides the default log errors when a 500 response is sent to the client. From: ``` 2024-12-23T15:54:25.842837Z ERROR tower_http::trace::on_failure: response failed classification=Status code: 500 Internal Server Error latency=0 ms ``` To: ``` 2024-12-23T16:06:53.553023Z ERROR API: response failed classification=Status code: 500 Internal Server Error latency=0 ms ``` The target has been changed: ``` 2024-12-23T15:54:25.842837Z ERROR tower_http::trace::on_failure: response failed classification=Status code: 500 Internal Server Error latency=0 ms 2024-12-23T16:06:53.553023Z ERROR API: response failed classification=Status code: 500 Internal Server Error latency=0 ms ``` It was changed to: - Easily identify the origin of the error in our code. - Allow for the inserting of more fields in the future, for example, to write assertions about logs. ACKs for top commit: josecelano: ACK 9ac676c Tree-SHA512: 4e2eb9057ea15bf28f2a5ab6a8d8becc072520d428fe6718ea2275a7ccd028e21d9907fb7d9626b8beba80ccfd72a60c040bdae902c1ec4b41fa31a8e8014974
2 parents 90f6a01 + 9ac676c commit 0f40030

File tree

4 files changed

+62
-3
lines changed

4 files changed

+62
-3
lines changed

src/servers/apis/routes.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,20 @@ use hyper::{Request, StatusCode};
1717
use torrust_tracker_configuration::{AccessTokens, DEFAULT_TIMEOUT};
1818
use tower::timeout::TimeoutLayer;
1919
use tower::ServiceBuilder;
20+
use tower_http::classify::ServerErrorsFailureClass;
2021
use tower_http::compression::CompressionLayer;
2122
use tower_http::propagate_header::PropagateHeaderLayer;
2223
use tower_http::request_id::{MakeRequestUuid, SetRequestIdLayer};
2324
use tower_http::trace::{DefaultMakeSpan, TraceLayer};
25+
use tower_http::LatencyUnit;
2426
use tracing::{instrument, Level, Span};
2527

2628
use super::v1;
2729
use super::v1::context::health_check::handlers::health_check_handler;
2830
use super::v1::middlewares::auth::State;
2931
use crate::core::Tracker;
3032
use crate::servers::apis::API_LOG_TARGET;
33+
use crate::servers::logging::Latency;
3134

3235
/// Add all API routes to the router.
3336
#[allow(clippy::needless_pass_by_value)]
@@ -75,7 +78,14 @@ pub fn router(tracker: Arc<Tracker>, access_tokens: Arc<AccessTokens>) -> Router
7578
tracing::span!(
7679
target: API_LOG_TARGET,
7780
tracing::Level::INFO, "response", latency = %latency_ms, status = %status_code, request_id = %request_id);
78-
}),
81+
})
82+
.on_failure(|failure_classification: ServerErrorsFailureClass, latency: Duration, _span: &Span| {
83+
let latency = Latency::new(
84+
LatencyUnit::Millis,
85+
latency,
86+
);
87+
tracing::error!(target: API_LOG_TARGET, "response failed classification={failure_classification} latency={latency}");
88+
})
7989
)
8090
.layer(SetRequestIdLayer::x_request_id(MakeRequestUuid))
8191
.layer(

src/servers/health_check_api/server.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -14,15 +14,18 @@ use futures::Future;
1414
use hyper::Request;
1515
use serde_json::json;
1616
use tokio::sync::oneshot::{Receiver, Sender};
17+
use tower_http::classify::ServerErrorsFailureClass;
1718
use tower_http::compression::CompressionLayer;
1819
use tower_http::propagate_header::PropagateHeaderLayer;
1920
use tower_http::request_id::{MakeRequestUuid, SetRequestIdLayer};
2021
use tower_http::trace::{DefaultMakeSpan, TraceLayer};
22+
use tower_http::LatencyUnit;
2123
use tracing::{instrument, Level, Span};
2224

2325
use crate::bootstrap::jobs::Started;
2426
use crate::servers::health_check_api::handlers::health_check_handler;
2527
use crate::servers::health_check_api::HEALTH_CHECK_API_LOG_TARGET;
28+
use crate::servers::logging::Latency;
2629
use crate::servers::registar::ServiceRegistry;
2730
use crate::servers::signals::{graceful_shutdown, Halted};
2831

@@ -73,7 +76,14 @@ pub fn start(
7376
tracing::span!(
7477
target: HEALTH_CHECK_API_LOG_TARGET,
7578
tracing::Level::INFO, "response", latency = %latency_ms, status = %status_code, request_id = %request_id);
76-
}),
79+
})
80+
.on_failure(|failure_classification: ServerErrorsFailureClass, latency: Duration, _span: &Span| {
81+
let latency = Latency::new(
82+
LatencyUnit::Millis,
83+
latency,
84+
);
85+
tracing::error!(target: HEALTH_CHECK_API_LOG_TARGET, "response failed classification={failure_classification} latency={latency}");
86+
})
7787
)
7888
.layer(SetRequestIdLayer::x_request_id(MakeRequestUuid));
7989

src/servers/http/v1/routes.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,18 @@ use hyper::{Request, StatusCode};
1313
use torrust_tracker_configuration::DEFAULT_TIMEOUT;
1414
use tower::timeout::TimeoutLayer;
1515
use tower::ServiceBuilder;
16+
use tower_http::classify::ServerErrorsFailureClass;
1617
use tower_http::compression::CompressionLayer;
1718
use tower_http::propagate_header::PropagateHeaderLayer;
1819
use tower_http::request_id::{MakeRequestUuid, SetRequestIdLayer};
1920
use tower_http::trace::{DefaultMakeSpan, TraceLayer};
21+
use tower_http::LatencyUnit;
2022
use tracing::{instrument, Level, Span};
2123

2224
use super::handlers::{announce, health_check, scrape};
2325
use crate::core::Tracker;
2426
use crate::servers::http::HTTP_TRACKER_LOG_TARGET;
27+
use crate::servers::logging::Latency;
2528

2629
/// It adds the routes to the router.
2730
///
@@ -72,7 +75,14 @@ pub fn router(tracker: Arc<Tracker>, server_socket_addr: SocketAddr) -> Router {
7275
tracing::span!(
7376
target: HTTP_TRACKER_LOG_TARGET,
7477
tracing::Level::INFO, "response", server_socket_addr= %server_socket_addr, latency = %latency_ms, status = %status_code, request_id = %request_id);
75-
}),
78+
})
79+
.on_failure(|failure_classification: ServerErrorsFailureClass, latency: Duration, _span: &Span| {
80+
let latency = Latency::new(
81+
LatencyUnit::Millis,
82+
latency,
83+
);
84+
tracing::error!(target: HTTP_TRACKER_LOG_TARGET, "response failed classification={failure_classification} latency={latency}");
85+
})
7686
)
7787
.layer(SetRequestIdLayer::x_request_id(MakeRequestUuid))
7888
.layer(

src/servers/logging.rs

+29
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
use std::fmt;
2+
use std::time::Duration;
3+
4+
use tower_http::LatencyUnit;
5+
16
/// This is the prefix used in logs to identify a started service.
27
///
38
/// For example:
@@ -27,3 +32,27 @@ We should use something like:
2732
```
2833
2934
*/
35+
36+
pub struct Latency {
37+
unit: LatencyUnit,
38+
duration: Duration,
39+
}
40+
41+
impl Latency {
42+
#[must_use]
43+
pub fn new(unit: LatencyUnit, duration: Duration) -> Self {
44+
Self { unit, duration }
45+
}
46+
}
47+
48+
impl fmt::Display for Latency {
49+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50+
match self.unit {
51+
LatencyUnit::Seconds => write!(f, "{} s", self.duration.as_secs_f64()),
52+
LatencyUnit::Millis => write!(f, "{} ms", self.duration.as_millis()),
53+
LatencyUnit::Micros => write!(f, "{} μs", self.duration.as_micros()),
54+
LatencyUnit::Nanos => write!(f, "{} ns", self.duration.as_nanos()),
55+
_ => panic!("Invalid latency unit"),
56+
}
57+
}
58+
}

0 commit comments

Comments
 (0)