diff options
author | metamuffin <metamuffin@disroot.org> | 2023-10-06 10:22:31 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2023-10-06 10:22:31 +0200 |
commit | 6e4095bd811a53cb75092516ef303b746e9aafba (patch) | |
tree | 44875ca252da14cc8018413ed2a25f99ed1fa06d | |
parent | 452541087c6562fca94f24b9275b17d771622fbd (diff) | |
download | gnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar gnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar.bz2 gnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar.zst |
some basic reporting for mond
-rw-r--r-- | Cargo.lock | 42 | ||||
-rw-r--r-- | Cargo.toml | 6 | ||||
-rw-r--r-- | src/main.rs | 31 | ||||
-rw-r--r-- | src/proxy.rs | 3 | ||||
-rw-r--r-- | src/reporting.rs | 39 |
5 files changed, 110 insertions, 11 deletions
@@ -66,6 +66,25 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -304,6 +323,7 @@ dependencies = [ "log", "markup", "mime_guess", + "mond-client", "percent-encoding", "pin-project", "rustls", @@ -621,6 +641,22 @@ dependencies = [ ] [[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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1093,6 +1129,12 @@ 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" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -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<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(), + } + } +} |