Commit Diff


commit - 3e51ca5cea08d8f20e579cdac7aa296f96967439
commit + 901713323c305809dbcf20c2d33505e2c65ea5eb
blob - 0c41cb9f7eff65760953f32f5bb282e8150efa89
blob + c43f0bf66015a2a1b7313fd4bb9e8584761a7fe0
--- web/template/Cargo.toml
+++ web/template/Cargo.toml
@@ -12,6 +12,6 @@ axum = "=0.8.6"
 minijinja = "=2.12.0"
 serde = { version = "=1.0.228", features = ["derive"] }
 tokio = { version = "=1.48.0", features = ["macros", "rt-multi-thread", "signal"] }
-tower-http = { version = "=0.6.6", features = ["timeout", "trace", "fs"] }
+tower-http = { version = "=0.6.6", features = ["timeout", "trace", "fs", "request-id"] }
 tracing = "=0.1.41"
 tracing-subscriber = { version = "=0.3.20", features = ["env-filter"] }
blob - 64ec71848edcc1a463f86928aa7e5c9da25d60fa
blob + d3bc57c7a8ad936ba925a369a467edd353acadea
--- web/template/src/router.rs
+++ web/template/src/router.rs
@@ -18,30 +18,58 @@ use std::{sync::Arc, time::Duration};
 use axum::{
     Router,
     extract::State,
-    http::StatusCode,
+    http::{HeaderName, Request, StatusCode},
     response::{Html, IntoResponse},
     routing::get,
 };
 use minijinja::context;
 use tower_http::{
-    services::ServeDir, timeout::TimeoutLayer, trace::TraceLayer,
+    request_id::{
+        MakeRequestUuid, PropagateRequestIdLayer, SetRequestIdLayer,
+    },
+    services::ServeDir,
+    timeout::TimeoutLayer,
+    trace::TraceLayer,
 };
+use tracing::{error, info_span};
 
 use crate::state::AppState;
 
+const REQUEST_ID_HEADER: &str = "x-request-id";
+
 pub(crate) fn route(app_state: Arc<AppState>) -> Router {
+    let x_request_id = HeaderName::from_static(REQUEST_ID_HEADER);
+
     Router::new()
-        .route("/healthz", get(healthz))
         .route("/", get(handler_home))
         .route("/content", get(handler_content))
         .route("/about", get(handler_about))
         // TODO(msi): from config folder asssets
         .nest_service("/assets", ServeDir::new("assets"))
         .layer((
-            TraceLayer::new_for_http(),
+            SetRequestIdLayer::new(x_request_id.clone(), MakeRequestUuid),
+            TraceLayer::new_for_http().make_span_with(
+            |request: &Request<_>| {
+                // Log the request id as generated.
+                let request_id = request.headers().get(REQUEST_ID_HEADER);
+
+                match request_id {
+                    Some(request_id) => info_span!(
+                        "http_request",
+                        request_id = ?request_id,
+                    ),
+                    None => {
+                        error!("could not extract request_id");
+                        info_span!("http_request")
+                    }
+                }
+            },
+            ),
             // TODO(msi): from config
             TimeoutLayer::new(Duration::from_secs(10)),
+            PropagateRequestIdLayer::new(x_request_id)
         ))
+        .route("/healthz", get(healthz))
         .with_state(app_state)
 }