Add request id header to incoming requests
All checks were successful
Backend Actions / check (push) Successful in 1m1s
Backend Actions / build (push) Successful in 1m51s
Frontend Actions / check (push) Successful in 59s
Backend Actions / test (push) Successful in 2m20s
Frontend Actions / build (push) Successful in 59s
Frontend Actions / test (push) Successful in 55s

This commit is contained in:
2025-07-25 23:23:16 +01:00
parent 6bd6dbad38
commit 20f64cd35d
3 changed files with 36 additions and 8 deletions

1
backend/Cargo.lock generated
View File

@ -1896,6 +1896,7 @@ dependencies = [
"tower-layer", "tower-layer",
"tower-service 0.3.3", "tower-service 0.3.3",
"tracing", "tracing",
"uuid",
] ]
[[package]] [[package]]

View File

@ -11,7 +11,7 @@ serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0.141" serde_json = "1.0.141"
tokio = { version = "1.0", features = ["full"] } tokio = { version = "1.0", features = ["full"] }
tower = { version = "0.5.2", features = ["full"] } tower = { version = "0.5.2", features = ["full"] }
tower-http = { version = "0.6.6", features = ["timeout", "trace", "auth"] } tower-http = { version = "0.6.6", features = ["timeout", "trace", "auth", "request-id"] }
tower-http-util = "0.1.0" tower-http-util = "0.1.0"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-subscriber = { version = "0.3", features = ["env-filter"] }

View File

@ -7,12 +7,25 @@ use crate::config;
use axum::extract::Request; use axum::extract::Request;
use axum::routing::get; use axum::routing::get;
use axum::{Router, body::Body}; use axum::{Router, body::Body};
use http::HeaderName;
use tower::ServiceBuilder; use tower::ServiceBuilder;
use tower_http::request_id::{MakeRequestId, RequestId, SetRequestIdLayer};
use tower_http::timeout::TimeoutLayer; use tower_http::timeout::TimeoutLayer;
use tower_http::trace::TraceLayer; use tower_http::trace::TraceLayer;
use tracing::Level; use tracing::Level;
use uuid::Uuid; use uuid::Uuid;
#[derive(Clone)]
struct RequestIdLayer;
impl MakeRequestId for RequestIdLayer {
fn make_request_id<B>(&mut self, _: &http::Request<B>) -> Option<RequestId> {
let id = Uuid::now_v7().to_string();
Some(RequestId::new(id.parse().unwrap()))
}
}
pub fn app(config: &config::Config) -> (Router, mpsc::Receiver<bool>) { pub fn app(config: &config::Config) -> (Router, mpsc::Receiver<bool>) {
let (tx, rx) = mpsc::channel(); let (tx, rx) = mpsc::channel();
( (
@ -22,15 +35,29 @@ pub fn app(config: &config::Config) -> (Router, mpsc::Receiver<bool>) {
.nest("/admin", admin::router(tx, config)) .nest("/admin", admin::router(tx, config))
.layer( .layer(
ServiceBuilder::new() ServiceBuilder::new()
.layer(SetRequestIdLayer::new(
HeaderName::from_static("x-request-id"),
RequestIdLayer,
))
.layer( .layer(
TraceLayer::new_for_http().make_span_with(|req: &Request<Body>| { TraceLayer::new_for_http().make_span_with(|req: &Request<Body>| {
tracing::span!( if let Some(req_id) = req.headers().get("x-request-id") {
Level::DEBUG, tracing::span!(
"request", Level::DEBUG,
trace_id = Uuid::now_v7().to_string(), "request",
method = format!("{}", req.method()), req_id = req_id.to_str().unwrap(),
uri = format!("{}", req.uri()), method = format!("{}", req.method()),
) uri = format!("{}", req.uri()),
)
} else {
tracing::span!(
Level::DEBUG,
"request",
req_id = "<missing>",
method = format!("{}", req.method()),
uri = format!("{}", req.uri()),
)
}
}), }),
) )
.layer(TimeoutLayer::new(Duration::from_secs(10))), .layer(TimeoutLayer::new(Duration::from_secs(10))),