diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/main.rs | 31 | ||||
-rw-r--r-- | src/proxy.rs | 3 | ||||
-rw-r--r-- | src/reporting.rs | 39 |
3 files changed, 62 insertions, 11 deletions
diff --git a/src/main.rs b/src/main.rs index 4d14bec..a1b04d4 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,8 @@ pub mod error; pub mod files; pub mod helper; pub mod proxy; +#[cfg(feature = "mond")] +pub mod reporting; use crate::{ config::{Config, HostConfig}, @@ -26,6 +28,8 @@ use hyper::{ Request, Response, StatusCode, }; use log::{debug, error, info, warn}; +#[cfg(feature = "mond")] +use reporting::Reporting; use std::{fs::File, io::BufReader, net::SocketAddr, path::Path, process::exit, sync::Arc}; use tokio::{net::TcpListener, signal::ctrl_c, sync::Semaphore}; use tokio_rustls::TlsAcceptor; @@ -34,6 +38,8 @@ pub struct State { pub config: Config, pub l_incoming: Semaphore, pub l_outgoing: Semaphore, + #[cfg(feature = "mond")] + pub reporting: Reporting, } #[tokio::main] @@ -54,6 +60,8 @@ async fn main() -> anyhow::Result<()> { let state = Arc::new(State { l_incoming: Semaphore::new(config.limits.max_incoming_connections), l_outgoing: Semaphore::new(config.limits.max_outgoing_connections), + #[cfg(feature = "mond")] + reporting: Reporting::new(&config), config, }); @@ -204,18 +212,19 @@ async fn service( addr: SocketAddr, ) -> Result<hyper::Response<BoxBody<bytes::Bytes, ServiceError>>, ServiceError> { debug!("{addr} ~> {:?} {}", req.headers().get(HOST), req.uri()); + #[cfg(feature = "mond")] + state.reporting.request_in.inc(); - let route = state - .config - .hosts - .get(remove_port( - &req.headers() - .get(HOST) - .and_then(|e| e.to_str().ok()) - .map(String::from) - .unwrap_or(String::from("")), - )) - .ok_or(ServiceError::NoHost)?; + let host = req + .headers() + .get(HOST) + .and_then(|e| e.to_str().ok()) + .map(String::from) + .unwrap_or(String::from("")); + let host = remove_port(&host); + let route = state.config.hosts.get(host).ok_or(ServiceError::NoHost)?; + #[cfg(feature = "mond")] + state.reporting.hosts.get(host).unwrap().requests_in.inc(); let mut resp = match route { HostConfig::Backend { backend } => proxy_request(&state, req, addr, backend).await, diff --git a/src/proxy.rs b/src/proxy.rs index d38de4d..e8d2467 100644 --- a/src/proxy.rs +++ b/src/proxy.rs @@ -20,6 +20,9 @@ pub async fn proxy_request( addr: SocketAddr, backend: &SocketAddr, ) -> Result<hyper::Response<BoxBody<bytes::Bytes, ServiceError>>, ServiceError> { + #[cfg(feature = "mond")] + state.reporting.request_out.inc(); + let scheme_secure = req.uri().scheme() == Some(&Scheme::HTTPS); *req.uri_mut() = Uri::builder() .path_and_query( diff --git a/src/reporting.rs b/src/reporting.rs new file mode 100644 index 0000000..ee30ac5 --- /dev/null +++ b/src/reporting.rs @@ -0,0 +1,39 @@ +use crate::config::Config; +use mond_client::{make_ident, Aspect, Push, Rate, Reporter}; +use std::{collections::HashMap, marker::PhantomData}; + +pub struct Reporting { + pub request_in: Aspect<Rate<i64>>, + pub request_out: Aspect<Rate<i64>>, + pub hosts: HashMap<String, HostReporting>, + // pub connections: Aspect<State<i64>>, +} +pub struct HostReporting { + pub requests_in: Aspect<Rate<i64>>, +} + +impl Reporting { + pub fn new(config: &Config) -> Self { + let mut rep = Reporter::new(); + Self { + request_in: rep.create(make_ident!("requests-in"), Push(Rate(PhantomData::<i64>))), + request_out: rep.create(make_ident!("requests-out"), Push(Rate(PhantomData::<i64>))), + // connections: rep.create(make_ident!("connections"), Push()), + hosts: config + .hosts + .iter() + .map(|(k, _v)| { + ( + k.to_owned(), + HostReporting { + requests_in: rep.create( + make_ident!("host", k, "request-in"), + Push(Rate(PhantomData::<i64>)), + ), + }, + ) + }) + .collect(), + } + } +} |