diff --git a/Cargo.lock b/Cargo.lock index e48156c..279f355 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1049,6 +1049,8 @@ dependencies = [ "serde_json", "sqlx", "tokio", + "tower", + "tower-http", "tracing", "tracing-bunyan-formatter", "tracing-log 0.2.0", @@ -2487,6 +2489,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0da193277a4e2c33e59e09b5861580c33dd0a637c3883d0fa74ba40c0374af2e" +dependencies = [ + "bitflags 2.4.1", + "bytes", + "http 1.0.0", + "http-body 1.0.0", + "http-body-util", + "pin-project-lite", + "tower", + "tower-layer", + "tower-service", + "tracing", + "uuid", +] + [[package]] name = "tower-layer" version = "0.3.2" diff --git a/Cargo.toml b/Cargo.toml index 4c5773e..37eb1e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,8 @@ serde_json = "1" # serde_with = "3" # Axum axum = { version = "0.7" } -# tower-http = { version = "0.5", features = ["fs"] } +tower = { version = "0.4" } +tower-http = { version = "0.5", features = ["trace", "request-id", "util"] } # tower-cookies = "0.10" # Others config = "0.14" diff --git a/src/startup.rs b/src/startup.rs index 1a0c9ce..90bec1a 100644 --- a/src/startup.rs +++ b/src/startup.rs @@ -1,8 +1,29 @@ +use axum::http::Request; use axum::routing::IntoMakeService; use axum::serve::Serve; use axum::Router; use sqlx::PgPool; use tokio::net::TcpListener; +use tower::ServiceBuilder; +use tower_http::{ + request_id::{MakeRequestId, RequestId}, + trace::{DefaultMakeSpan, DefaultOnResponse, TraceLayer}, + ServiceBuilderExt, +}; +use tracing::Level; +use uuid::Uuid; + +// from https://docs.rs/tower-http/0.2.5/tower_http/request_id/index.html#using-uuids +#[derive(Clone)] +struct MakeRequestUuid; + +impl MakeRequestId for MakeRequestUuid { + fn make_request_id(&mut self, _: &Request) -> Option { + let request_id = Uuid::new_v4().to_string(); + + Some(RequestId::new(request_id.parse().unwrap())) + } +} /// API routing /// @@ -11,6 +32,21 @@ pub fn app(connection: PgPool) -> Router { Router::new() .merge(crate::routes::routes_health_check()) .merge(crate::routes::routes_subscriptions(connection.clone())) + .layer( + // from https://docs.rs/tower-http/0.2.5/tower_http/request_id/index.html#using-trace + ServiceBuilder::new() + .set_x_request_id(MakeRequestUuid) + .layer( + TraceLayer::new_for_http() + .make_span_with( + DefaultMakeSpan::new() + .include_headers(true) + .level(Level::INFO), + ) + .on_response(DefaultOnResponse::new().include_headers(true)), + ) + .propagate_x_request_id(), + ) } /// Start the server