diff --git a/nmsr-aas/src/utils/http_client.rs b/nmsr-aas/src/utils/http_client.rs index 2f9cb1d..2cc74ed 100644 --- a/nmsr-aas/src/utils/http_client.rs +++ b/nmsr-aas/src/utils/http_client.rs @@ -17,7 +17,7 @@ use tower::{ buffer::Buffer, discover::ServiceList, limit::RateLimit, - load::{CompleteOnResponse, PendingRequestsDiscover}, + load::{CompleteOnResponse, PeakEwmaDiscover}, retry::{Policy, Retry}, timeout::{Timeout, TimeoutLayer}, Service, ServiceBuilder, ServiceExt, @@ -29,7 +29,7 @@ use tower_http::{ DefaultMakeSpan, DefaultOnFailure, DefaultOnRequest, DefaultOnResponse, Trace, TraceLayer, }, }; -use tracing::{instrument, Span}; +use tracing::{info, instrument, Span}; use crate::error::{MojangRequestError, MojangRequestResult}; @@ -45,7 +45,7 @@ pub(crate) type SyncBody = pub(crate) type SyncBodyClient = Client, SyncBody>; pub(crate) type NmsrTraceLayer = Trace< - SetRequestHeader, + SetRequestHeader, HeaderValue>, SharedClassifier, DefaultMakeSpan, DefaultOnRequest, @@ -225,7 +225,8 @@ fn create_http_client_internal( .build(https); let tracing = TraceLayer::new_for_http().on_body_chunk(()).on_eos(()); - + let ip_layer = LogRequestIpLayer::new(client_ip); + let service = ServiceBuilder::new() .buffer(rate_limit_per_second.saturating_mul(2) as usize) .rate_limit(rate_limit_per_second, Duration::from_secs(1)) @@ -240,6 +241,7 @@ fn create_http_client_internal( HeaderName::from_static("user-agent"), HeaderValue::from_str(USER_AGENT).expect("Expected user-agent to be valid"), )) + .layer(ip_layer) .check_clone() .service(client); @@ -320,3 +322,52 @@ where Retry::new(policy, service) } } + + +#[derive(Clone, Debug, Copy)] +pub struct LogRequestIpLayer { + ip: Option, +} + +impl LogRequestIpLayer { + pub fn new(ip: Option) -> Self { + Self { ip } + } +} + +impl tower::Layer for LogRequestIpLayer { + type Service = LogRequestIpService; + + fn layer(&self, service: S) -> Self::Service { + LogRequestIpService { + ip: self.ip, + inner: service, + } + } +} + +#[derive(Clone, Debug)] +pub struct LogRequestIpService { + ip: Option, + inner: S, +} + +impl Service> for LogRequestIpService +where + S: Service, Response = http::Response>, +{ + type Response = S::Response; + type Error = S::Error; + type Future = S::Future; + + fn poll_ready(&mut self, cx: &mut std::task::Context<'_>) -> std::task::Poll> { + self.inner.poll_ready(cx) + } + + fn call(&mut self, req: Request) -> Self::Future { + if let Some(ip) = self.ip { + info!("Outgoing request from IP: {}", ip); + } + self.inner.call(req) + } +} \ No newline at end of file