aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorrtkay123 <dev@kanjala.com>2025-08-12 05:13:32 +0200
committerrtkay123 <dev@kanjala.com>2025-08-12 05:13:32 +0200
commitc5ea875f544824b0c042bf7c0a58b3134f9c0373 (patch)
tree4913d4ff2b408c7157e33894e40deec570ecce9e /lib
parent9c850d6c4d0ed468709c2eb5340d7b64bbb9aa68 (diff)
downloadwarden-c5ea875f544824b0c042bf7c0a58b3134f9c0373.tar.bz2
warden-c5ea875f544824b0c042bf7c0a58b3134f9c0373.zip
feat(config): get active routing
Diffstat (limited to 'lib')
-rw-r--r--lib/warden-core/build.rs16
-rw-r--r--lib/warden-middleware/Cargo.toml18
-rw-r--r--lib/warden-middleware/src/lib.rs20
-rw-r--r--lib/warden-middleware/src/metrics.rs33
-rw-r--r--lib/warden-middleware/src/trace_layer.rs24
5 files changed, 104 insertions, 7 deletions
diff --git a/lib/warden-core/build.rs b/lib/warden-core/build.rs
index 9088fd7..5f1e898 100644
--- a/lib/warden-core/build.rs
+++ b/lib/warden-core/build.rs
@@ -18,12 +18,9 @@ impl Entity {
vec!["proto/warden_message.proto"]
}
-
#[cfg(feature = "configuration")]
fn configuration_protos() -> Vec<&'static str> {
- vec![
- "proto/configuration/routing.proto",
- ]
+ vec!["proto/configuration/routing.proto"]
}
#[cfg(feature = "pseudonyms")]
@@ -72,7 +69,6 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
#[cfg(any(feature = "message", feature = "pseudonyms", feature = "configuration"))]
build_proto(&protos)?;
-
Ok(())
}
@@ -100,7 +96,10 @@ fn build_proto(protos: &[&str]) -> Result<(), Box<dyn std::error::Error>> {
Ok(())
}
-#[cfg(all(feature = "serde", any(feature = "pseudonyms", feature = "message", feature = "configuration")))]
+#[cfg(all(
+ feature = "serde",
+ any(feature = "pseudonyms", feature = "message", feature = "configuration")
+))]
fn add_serde(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder {
let config = config.type_attribute(
".",
@@ -116,7 +115,10 @@ fn add_serde(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder {
config
}
-#[cfg(all(feature = "openapi", any(feature = "message", feature = "pseudonyms", feature = "configuration")))]
+#[cfg(all(
+ feature = "openapi",
+ any(feature = "message", feature = "pseudonyms", feature = "configuration")
+))]
fn add_openapi(config: tonic_prost_build::Builder) -> tonic_prost_build::Builder {
config.type_attribute(".", "#[derive(utoipa::ToSchema)]")
}
diff --git a/lib/warden-middleware/Cargo.toml b/lib/warden-middleware/Cargo.toml
new file mode 100644
index 0000000..b23e61e
--- /dev/null
+++ b/lib/warden-middleware/Cargo.toml
@@ -0,0 +1,18 @@
+[package]
+name = "warden-middleware"
+version = "0.1.0"
+edition = "2024"
+license.workspace = true
+homepage.workspace = true
+documentation.workspace = true
+description.workspace = true
+publish = false
+
+[dependencies]
+axum.workspace = true
+metrics.workspace = true
+metrics-exporter-prometheus.workspace = true
+tower-http = { workspace = true, features = [
+ "request-id",
+] }
+tracing.workspace = true
diff --git a/lib/warden-middleware/src/lib.rs b/lib/warden-middleware/src/lib.rs
new file mode 100644
index 0000000..6e3a0f4
--- /dev/null
+++ b/lib/warden-middleware/src/lib.rs
@@ -0,0 +1,20 @@
+mod metrics;
+mod trace_layer;
+
+use metrics::*;
+use trace_layer::*;
+
+use axum::{Router, http::HeaderName, middleware};
+use tower_http::request_id::{MakeRequestUuid, PropagateRequestIdLayer, SetRequestIdLayer};
+
+const REQUEST_ID_HEADER: &str = "x-request-id";
+
+pub fn apply<T: Clone + Send + Sync + 'static>(router: Router<T>) -> Router<T> {
+ let x_request_id = HeaderName::from_static(REQUEST_ID_HEADER);
+
+ let router = router.layer(PropagateRequestIdLayer::new(x_request_id.clone()));
+
+ apply_trace_context_middleware(router)
+ .layer(SetRequestIdLayer::new(x_request_id, MakeRequestUuid))
+ .route_layer(middleware::from_fn(apply_metrics_middleware))
+}
diff --git a/lib/warden-middleware/src/metrics.rs b/lib/warden-middleware/src/metrics.rs
new file mode 100644
index 0000000..8644160
--- /dev/null
+++ b/lib/warden-middleware/src/metrics.rs
@@ -0,0 +1,33 @@
+use std::time::Instant;
+
+use axum::{
+ extract::{MatchedPath, Request},
+ middleware::Next,
+ response::IntoResponse,
+};
+
+pub async fn apply_metrics_middleware(req: Request, next: Next) -> impl IntoResponse {
+ let start = Instant::now();
+ let path = if let Some(matched_path) = req.extensions().get::<MatchedPath>() {
+ matched_path.as_str().to_owned()
+ } else {
+ req.uri().path().to_owned()
+ };
+ let method = req.method().clone();
+
+ let response = next.run(req).await;
+
+ let latency = start.elapsed().as_secs_f64();
+ let status = response.status().as_u16().to_string();
+
+ let labels = [
+ ("method", method.to_string()),
+ ("path", path),
+ ("status", status),
+ ];
+
+ metrics::counter!("http_requests_total", &labels).increment(1);
+ metrics::histogram!("http_requests_duration_seconds", &labels).record(latency);
+
+ response
+}
diff --git a/lib/warden-middleware/src/trace_layer.rs b/lib/warden-middleware/src/trace_layer.rs
new file mode 100644
index 0000000..5173e8d
--- /dev/null
+++ b/lib/warden-middleware/src/trace_layer.rs
@@ -0,0 +1,24 @@
+use axum::{Router, http::Request};
+use tower_http::trace::TraceLayer;
+use tracing::info_span;
+
+use super::REQUEST_ID_HEADER;
+
+pub fn apply_trace_context_middleware<T: Clone + Send + Sync + 'static>(
+ router: Router<T>,
+) -> Router<T> {
+ router.layer(
+ TraceLayer::new_for_http().make_span_with(|request: &Request<_>| {
+ let request_id = request
+ .headers()
+ .get(REQUEST_ID_HEADER)
+ .expect("should have been applied already");
+
+ info_span!(
+ "http_request",
+ request_id = ?request_id,
+ headers = ?request.headers()
+ )
+ }),
+ )
+}