feat: add request ids

This commit is contained in:
dusk 2023-05-05 13:32:00 +03:00
parent 632426672c
commit cc31eab4ff
Signed by: dusk
GPG Key ID: 1D8F8FAF2294D6EA
3 changed files with 35 additions and 6 deletions

10
Cargo.lock generated
View File

@ -1130,6 +1130,7 @@ dependencies = [
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing", "tracing",
"uuid",
] ]
[[package]] [[package]]
@ -1301,6 +1302,15 @@ version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9" checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dad5567ad0cf5b760e5665964bec1b47dfd077ba8a2544b513f3556d3d239a2"
dependencies = [
"getrandom",
]
[[package]] [[package]]
name = "valuable" name = "valuable"
version = "0.1.0" version = "0.1.0"

View File

@ -10,7 +10,7 @@ tokio = {version = "1", features = ["rt-multi-thread"]}
dotenvy = "0.15" dotenvy = "0.15"
tracing = "0.1" tracing = "0.1"
tracing-subscriber = {version = "0.3", features = ["env-filter"]} tracing-subscriber = {version = "0.3", features = ["env-filter"]}
tower-http = {version = "0.4", features = ["trace", "cors", "sensitive-headers"]} tower-http = {version = "0.4", features = ["trace", "cors", "sensitive-headers", "request-id"]}
hyper = {version = "0.14", features = ["client"]} hyper = {version = "0.14", features = ["client"]}
http = "0.2" http = "0.2"
async-tungstenite = {version = "0.21", features = ["tokio-runtime"]} async-tungstenite = {version = "0.21", features = ["tokio-runtime"]}

View File

@ -20,20 +20,24 @@ use base64::Engine;
use futures::{SinkExt, StreamExt}; use futures::{SinkExt, StreamExt};
use http::{ use http::{
header::{AUTHORIZATION, CACHE_CONTROL, CONTENT_TYPE}, header::{AUTHORIZATION, CACHE_CONTROL, CONTENT_TYPE},
HeaderValue, Method, Request, Response, StatusCode, HeaderName, HeaderValue, Method, Request, Response, StatusCode,
}; };
use hyper::Body; use hyper::Body;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use serde_json::Value; use serde_json::Value;
use tokio::net::TcpStream; use tokio::net::TcpStream;
use tower_http::{ use tower_http::{
cors::CorsLayer, sensitive_headers::SetSensitiveRequestHeadersLayer, trace::TraceLayer, cors::CorsLayer,
request_id::{MakeRequestUuid, SetRequestIdLayer},
sensitive_headers::SetSensitiveRequestHeadersLayer,
trace::TraceLayer,
}; };
use tracing::{Instrument, Span}; use tracing::{Instrument, Span};
use crate::{AppState, B64}; use crate::{AppState, B64};
const AUDIO_CACHE_HEADER: HeaderValue = HeaderValue::from_static("private, max-age=604800"); const AUDIO_CACHE_HEADER: HeaderValue = HeaderValue::from_static("private, max-age=604800");
const REQUEST_ID: HeaderName = HeaderName::from_static("x-request-id");
#[derive(Deserialize)] #[derive(Deserialize)]
struct Auth { struct Auth {
@ -73,18 +77,32 @@ fn make_span_trace<B>(req: &Request<B>) -> Span {
query_map.insert("token", "<redacted>"); query_map.insert("token", "<redacted>");
} }
let query_display = QueryDisplay { map: query_map }; let query_display = QueryDisplay { map: query_map };
let request_id = req
.headers()
.get(REQUEST_ID)
.and_then(|v| v.to_str().ok())
.unwrap_or("no id set");
tracing::debug_span!( tracing::debug_span!(
"request", "request",
method = %req.method(), method = %req.method(),
path = %req.uri().path(), path = %req.uri().path(),
query = %query_display, query = %query_display,
version = ?req.version(), version = ?req.version(),
headers = ?req.headers(), id = %request_id,
) )
} }
pub(super) async fn handler(state: AppState) -> Result<(Router, Router), AppError> { pub(super) async fn handler(state: AppState) -> Result<(Router, Router), AppError> {
let trace_layer = TraceLayer::new_for_http().make_span_with(make_span_trace); let trace_layer = TraceLayer::new_for_http()
.make_span_with(make_span_trace)
.on_request(|req: &Request<Body>, _span: &Span| {
tracing::debug!(
"started processing request with headers: {:#?}",
req.headers()
)
});
let internal_router = Router::new() let internal_router = Router::new()
.route("/token/generate", get(generate_token)) .route("/token/generate", get(generate_token))
@ -97,12 +115,13 @@ pub(super) async fn handler(state: AppState) -> Result<(Router, Router), AppErro
.route("/audio/external_id/:id", get(get_music)) .route("/audio/external_id/:id", get(get_music))
.route("/audio/scoped/:id", get(get_scoped_music)) .route("/audio/scoped/:id", get(get_scoped_music))
.route("/", get(metadata_ws)) .route("/", get(metadata_ws))
.layer(SetRequestIdLayer::new(REQUEST_ID.clone(), MakeRequestUuid))
.layer(SetSensitiveRequestHeadersLayer::new([AUTHORIZATION])) .layer(SetSensitiveRequestHeadersLayer::new([AUTHORIZATION]))
.layer(trace_layer) .layer(trace_layer)
.layer( .layer(
CorsLayer::new() CorsLayer::new()
.allow_origin(tower_http::cors::Any) .allow_origin(tower_http::cors::Any)
.allow_headers([CONTENT_TYPE]) .allow_headers([CONTENT_TYPE, CACHE_CONTROL, REQUEST_ID])
.allow_methods([Method::GET]), .allow_methods([Method::GET]),
) )
.with_state(state); .with_state(state);