From 6e4095bd811a53cb75092516ef303b746e9aafba Mon Sep 17 00:00:00 2001 From: metamuffin Date: Fri, 6 Oct 2023 10:22:31 +0200 Subject: some basic reporting for mond --- Cargo.lock | 42 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 6 ++++++ src/main.rs | 33 +++++++++++++++++++++------------ src/proxy.rs | 3 +++ src/reporting.rs | 39 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 111 insertions(+), 12 deletions(-) create mode 100644 src/reporting.rs diff --git a/Cargo.lock b/Cargo.lock index ee63174..c3a487c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -65,6 +65,25 @@ version = "0.21.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +[[package]] +name = "bincode" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f11ea1a0346b94ef188834a65c068a03aec181c94896d481d7a0a40d85b0ce95" +dependencies = [ + "bincode_derive", + "serde", +] + +[[package]] +name = "bincode_derive" +version = "2.0.0-rc.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e30759b3b99a1b802a7a3aa21c85c3ded5c28e1c83170d82d70f08bbf7f3e4c" +dependencies = [ + "virtue", +] + [[package]] name = "bitflags" version = "1.3.2" @@ -304,6 +323,7 @@ dependencies = [ "log", "markup", "mime_guess", + "mond-client", "percent-encoding", "pin-project", "rustls", @@ -620,6 +640,22 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "mond-client" +version = "0.1.0" +dependencies = [ + "log", + "mond-protocol", +] + +[[package]] +name = "mond-protocol" +version = "0.1.0" +dependencies = [ + "bincode", + "serde", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -1092,6 +1128,12 @@ version = "0.9.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" +[[package]] +name = "virtue" +version = "0.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9dcc60c0624df774c82a0ef104151231d37da4962957d691c011c852b2473314" + [[package]] name = "want" version = "0.3.1" diff --git a/Cargo.toml b/Cargo.toml index 34017d7..95a52fd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -41,3 +41,9 @@ mime_guess = "2.0.4" bytes = "1.4.0" anyhow = "1.0.75" thiserror = "1.0.47" + +mond-client = { path = "../mond/client", optional = true } + +[features] +# default = ["mond"] +mond = ["dep:mond-client"] 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>, ServiceError> { debug!("{addr} ~> {:?} {}", req.headers().get(HOST), req.uri()); - - 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)?; + #[cfg(feature = "mond")] + state.reporting.request_in.inc(); + + 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>, 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>, + pub request_out: Aspect>, + pub hosts: HashMap, + // pub connections: Aspect>, +} +pub struct HostReporting { + pub requests_in: Aspect>, +} + +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::))), + request_out: rep.create(make_ident!("requests-out"), Push(Rate(PhantomData::))), + // 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::)), + ), + }, + ) + }) + .collect(), + } + } +} -- cgit v1.2.3-70-g09d2