Skip to content

Commit dc6f424

Browse files
committed
Move request logging near the top of the middleware stack
By converting to a regular `Middleware` (instead of `AroundMiddleware`), the logging can now sit near the top of the middleware stack. Previously logging occurred at the top of the around stack, which sits under the layers added via `add()`. This change ensures that middleware sitting below the request logger in the stack are able to add logging metadata in a call to `after()`.
1 parent 8c1a7e2 commit dc6f424

File tree

2 files changed

+12
-16
lines changed

2 files changed

+12
-16
lines changed

src/middleware.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ pub fn build_middleware(app: Arc<App>, endpoints: R404) -> MiddlewareBuilder {
4646

4747
if env != Env::Test {
4848
m.add(ensure_well_formed_500::EnsureWellFormed500);
49+
m.add(log_request::LogRequests::default());
4950
}
5051

5152
if env == Env::Development {
@@ -94,9 +95,5 @@ pub fn build_middleware(app: Arc<App>, endpoints: R404) -> MiddlewareBuilder {
9495

9596
m.around(require_user_agent::RequireUserAgent::default());
9697

97-
if env != Env::Test {
98-
m.around(log_request::LogRequests::default());
99-
}
100-
10198
m
10299
}

src/middleware/log_request.rs

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,22 +9,21 @@ use std::time::Instant;
99

1010
const SLOW_REQUEST_THRESHOLD_MS: u64 = 1000;
1111

12-
#[allow(missing_debug_implementations)] // We can't
1312
#[derive(Default)]
14-
pub struct LogRequests {
15-
handler: Option<Box<dyn Handler>>,
16-
}
13+
pub(super) struct LogRequests();
14+
15+
struct RequestStart(Instant);
1716

18-
impl AroundMiddleware for LogRequests {
19-
fn with_handler(&mut self, handler: Box<dyn Handler>) {
20-
self.handler = Some(handler);
17+
impl Middleware for LogRequests {
18+
fn before(&self, req: &mut dyn Request) -> Result<()> {
19+
req.mut_extensions().insert(RequestStart(Instant::now()));
20+
Ok(())
2121
}
22-
}
2322

24-
impl Handler for LogRequests {
25-
fn call(&self, req: &mut dyn Request) -> Result<Response> {
26-
let request_start = Instant::now();
27-
let res = self.handler.as_ref().unwrap().call(req);
23+
fn after(&self, req: &mut dyn Request, res: Result<Response>) -> Result<Response> {
24+
// Unwrap shouldn't panic as no other code has access to the private struct to remove it
25+
let request_start = req.extensions().find::<RequestStart>().unwrap().0;
26+
2827
let response_time = request_start.elapsed();
2928
let response_time =
3029
response_time.as_secs() * 1000 + u64::from(response_time.subsec_nanos()) / 1_000_000;

0 commit comments

Comments
 (0)