viz_middleware/
logger.rs

1use std::{future::Future, pin::Pin, time::Instant};
2
3use viz_core::{http, Context, Middleware, Response, Result};
4use viz_utils::tracing;
5
6/// Logger Middleware
7#[derive(Debug, Default)]
8pub struct Logger {}
9
10impl Logger {
11    async fn run(&self, cx: &mut Context) -> Result<Response> {
12        let start = Instant::now();
13        let method = cx.method().to_string();
14        let path = cx.uri().path().to_owned();
15
16        tracing::trace!("> {:>7} {}", method, path);
17
18        match cx.next().await {
19            Ok(res) => {
20                let status = res.status();
21
22                if status == http::StatusCode::INTERNAL_SERVER_ERROR {
23                    tracing::error!(
24                        "< {:>7} {} {} {:?}",
25                        method,
26                        path,
27                        status.as_u16(),
28                        start.elapsed(),
29                    );
30                } else {
31                    tracing::trace!(
32                        "< {:>7} {} {} {:?}",
33                        method,
34                        path,
35                        status.as_u16(),
36                        start.elapsed(),
37                    );
38                }
39
40                Ok(res)
41            }
42            Err(err) => {
43                tracing::error!("< {:>7} {} {} {:?}", method, path, err, start.elapsed(),);
44                Err(err)
45            }
46        }
47    }
48}
49
50impl<'a> Middleware<'a, Context> for Logger {
51    type Output = Result<Response>;
52
53    #[must_use]
54    fn call(
55        &'a self,
56        cx: &'a mut Context,
57    ) -> Pin<Box<dyn Future<Output = Self::Output> + Send + 'a>> {
58        Box::pin(self.run(cx))
59    }
60}