forked from mirrors/relay
Add timings metrics middleware
This commit is contained in:
parent
4e1a782bea
commit
cecc35ae85
3 changed files with 76 additions and 1 deletions
|
@ -33,7 +33,7 @@ use self::{
|
|||
data::{ActorCache, MediaCache, State},
|
||||
db::Db,
|
||||
jobs::create_workers,
|
||||
middleware::{DebugPayload, RelayResolver},
|
||||
middleware::{DebugPayload, RelayResolver, Timings},
|
||||
routes::{actor, inbox, index, nodeinfo, nodeinfo_meta, statics},
|
||||
};
|
||||
|
||||
|
@ -182,6 +182,7 @@ async fn main() -> Result<(), anyhow::Error> {
|
|||
};
|
||||
|
||||
app.wrap(TracingLogger::default())
|
||||
.wrap(Timings)
|
||||
.service(web::resource("/").route(web::get().to(index)))
|
||||
.service(web::resource("/media/{path}").route(web::get().to(routes::media)))
|
||||
.service(
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
mod payload;
|
||||
mod timings;
|
||||
mod verifier;
|
||||
mod webfinger;
|
||||
|
||||
pub(crate) use payload::DebugPayload;
|
||||
pub(crate) use timings::Timings;
|
||||
pub(crate) use verifier::MyVerify;
|
||||
pub(crate) use webfinger::RelayResolver;
|
||||
|
|
72
src/middleware/timings.rs
Normal file
72
src/middleware/timings.rs
Normal file
|
@ -0,0 +1,72 @@
|
|||
use actix_web::dev::{Service, ServiceRequest, Transform};
|
||||
use futures_util::future::LocalBoxFuture;
|
||||
use std::{
|
||||
future::{ready, Ready},
|
||||
time::Instant,
|
||||
};
|
||||
|
||||
pub(crate) struct Timings;
|
||||
pub(crate) struct TimingsMiddleware<S>(S);
|
||||
|
||||
struct LogOnDrop {
|
||||
begin: Instant,
|
||||
path: String,
|
||||
method: String,
|
||||
}
|
||||
|
||||
impl Drop for LogOnDrop {
|
||||
fn drop(&mut self) {
|
||||
let duration = self.begin.elapsed();
|
||||
metrics::histogram!("relay.request.complete", duration, "path" => self.path.clone(), "method" => self.method.clone());
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Transform<S, ServiceRequest> for Timings
|
||||
where
|
||||
S: Service<ServiceRequest>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type InitError = ();
|
||||
type Transform = TimingsMiddleware<S>;
|
||||
type Future = Ready<Result<Self::Transform, Self::InitError>>;
|
||||
|
||||
fn new_transform(&self, service: S) -> Self::Future {
|
||||
ready(Ok(TimingsMiddleware(service)))
|
||||
}
|
||||
}
|
||||
|
||||
impl<S> Service<ServiceRequest> for TimingsMiddleware<S>
|
||||
where
|
||||
S: Service<ServiceRequest>,
|
||||
S::Future: 'static,
|
||||
{
|
||||
type Response = S::Response;
|
||||
type Error = S::Error;
|
||||
type Future = LocalBoxFuture<'static, Result<S::Response, S::Error>>;
|
||||
|
||||
fn poll_ready(
|
||||
&self,
|
||||
ctx: &mut core::task::Context<'_>,
|
||||
) -> std::task::Poll<Result<(), Self::Error>> {
|
||||
self.0.poll_ready(ctx)
|
||||
}
|
||||
|
||||
fn call(&self, req: ServiceRequest) -> Self::Future {
|
||||
let logger = LogOnDrop {
|
||||
begin: Instant::now(),
|
||||
path: req.path().to_string(),
|
||||
method: req.method().to_string(),
|
||||
};
|
||||
let fut = self.0.call(req);
|
||||
|
||||
Box::pin(async move {
|
||||
let res = fut.await;
|
||||
|
||||
drop(logger);
|
||||
|
||||
res
|
||||
})
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue