Configurable, improved, middleware struct instead of function
This commit is contained in:
parent
ea1ed6fd70
commit
8a7353dc97
|
@ -1364,8 +1364,10 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tide_tracing"
|
name = "tide_tracing"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"chrono",
|
||||||
"nrid",
|
"nrid",
|
||||||
"tide",
|
"tide",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
[package]
|
[package]
|
||||||
name = "tide_tracing"
|
name = "tide_tracing"
|
||||||
version = "0.1.0"
|
version = "0.2.0"
|
||||||
authors = ["Michael Pfaff <michael@pfaff.dev>"]
|
authors = ["Michael Pfaff <michael@pfaff.dev>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
|
|
||||||
|
@ -8,5 +8,7 @@ edition = "2018"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
nrid = { git = "https://git.pfaff.dev/michael/nrid.rs.git" }
|
nrid = { git = "https://git.pfaff.dev/michael/nrid.rs.git" }
|
||||||
tide = "0.15.0"
|
tide = { version = "0.15.0" }
|
||||||
tracing = "0.1.15"
|
tracing = { version = "0.1.15" }
|
||||||
|
async-trait = { version = "0.1.36" }
|
||||||
|
chrono = { version = "0.4.19" }
|
||||||
|
|
66
src/lib.rs
66
src/lib.rs
|
@ -1,33 +1,71 @@
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate tracing;
|
extern crate tracing;
|
||||||
|
|
||||||
use core::future::Future;
|
use chrono::Utc;
|
||||||
use core::pin::Pin;
|
|
||||||
use nrid::Nrid;
|
use nrid::Nrid;
|
||||||
use std::time::Instant;
|
use tide::Middleware;
|
||||||
use tide::Next;
|
use tide::Next;
|
||||||
use tide::Request;
|
use tide::Request;
|
||||||
use tracing::Instrument;
|
use tracing::Instrument;
|
||||||
use tracing::Level;
|
use tracing::Level;
|
||||||
|
|
||||||
pub fn log_middleware<'a, State: 'static + Clone + Send + Sync>(
|
#[derive(Debug, Clone)]
|
||||||
req: Request<State>,
|
pub struct LogMiddleware {
|
||||||
next: Next<'a, State>,
|
include_ip: bool,
|
||||||
) -> Pin<Box<dyn Future<Output = tide::Result> + Send + 'a>> {
|
include_query: bool,
|
||||||
Box::pin(async move {
|
}
|
||||||
let now = Instant::now();
|
|
||||||
|
impl Default for LogMiddleware {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
include_ip: false,
|
||||||
|
include_query: false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl LogMiddleware {
|
||||||
|
async fn log<'a, State: Clone + Send + Sync + 'static>(
|
||||||
|
&'a self,
|
||||||
|
req: Request<State>,
|
||||||
|
next: Next<'a, State>,
|
||||||
|
) -> tide::Result {
|
||||||
|
let start = Utc::now();
|
||||||
let id = Nrid::now();
|
let id = Nrid::now();
|
||||||
let uri = req.url().clone();
|
let uri = req.url().clone();
|
||||||
// doesn't take forwarding into account and includes useless socket port information
|
|
||||||
// let ip = req.peer_addr().unwrap_or("unknown").to_string();
|
|
||||||
let ip = req.remote().unwrap_or("unknown").to_string();
|
let ip = req.remote().unwrap_or("unknown").to_string();
|
||||||
let span = span!(Level::ERROR, "Request", id = %id);
|
let span = span!(Level::ERROR, "Request", id = %id);
|
||||||
let res = async {
|
let res = async {
|
||||||
debug!(req.method = %req.method(), req.uri.path = uri.path(), req.uri.query = uri.query().unwrap_or(""), client_ip = %ip, received = ?now);
|
debug!(path = uri.path());
|
||||||
|
|
||||||
|
debug!(method = %req.method());
|
||||||
|
|
||||||
|
if self.include_query {
|
||||||
|
debug!(query = uri.query().unwrap_or(""));
|
||||||
|
}
|
||||||
|
|
||||||
|
if self.include_ip {
|
||||||
|
debug!(client_ip = %ip);
|
||||||
|
}
|
||||||
|
|
||||||
|
debug!(received = %start);
|
||||||
|
// debug!(method = %req.method(), query = uri.query().unwrap_or(""), client_ip = %ip, received = %start, "Request recieved");
|
||||||
let res = next.run(req).await;
|
let res = next.run(req).await;
|
||||||
debug!(status = %res.status(), elapsed = ?now.elapsed(), "Response");
|
let end = Utc::now();
|
||||||
|
let span = span!(Level::ERROR, "Response");
|
||||||
|
async {
|
||||||
|
debug!(status = %res.status());
|
||||||
|
debug!(duration = %end.signed_duration_since(start));
|
||||||
|
}.instrument(span).await;
|
||||||
res
|
res
|
||||||
}.instrument(span).await;
|
}.instrument(span).await;
|
||||||
Ok(res)
|
Ok(res)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_trait::async_trait]
|
||||||
|
impl<State: Clone + Send + Sync + 'static> Middleware<State> for LogMiddleware {
|
||||||
|
async fn handle(&self, req: Request<State>, next: Next<'_, State>) -> tide::Result {
|
||||||
|
self.log(req, next).await
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue