summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2023-10-06 10:22:31 +0200
committermetamuffin <metamuffin@disroot.org>2023-10-06 10:22:31 +0200
commit6e4095bd811a53cb75092516ef303b746e9aafba (patch)
tree44875ca252da14cc8018413ed2a25f99ed1fa06d
parent452541087c6562fca94f24b9275b17d771622fbd (diff)
downloadgnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar
gnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar.bz2
gnix-6e4095bd811a53cb75092516ef303b746e9aafba.tar.zst
some basic reporting for mond
-rw-r--r--Cargo.lock42
-rw-r--r--Cargo.toml6
-rw-r--r--src/main.rs31
-rw-r--r--src/proxy.rs3
-rw-r--r--src/reporting.rs39
5 files changed, 110 insertions, 11 deletions
diff --git a/Cargo.lock b/Cargo.lock
index ee63174..c3a487c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
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<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(),
+ }
+ }
+}