aboutsummaryrefslogtreecommitdiff
path: root/src/https.rs
diff options
context:
space:
mode:
authorAlex Auvolat <alex@adnab.me>2022-12-05 18:43:48 +0100
committerAlex Auvolat <alex@adnab.me>2022-12-05 18:43:48 +0100
commit5d38f2cf7f312de69a3106556fc43219ca1473c3 (patch)
tree2ecc767ffeae5dd9b4a528f8294a61385a1fb5b1 /src/https.rs
parent43a0fe14b2ae6a3e97f39169cda7ca5579a3259c (diff)
downloadtricot-5d38f2cf7f312de69a3106556fc43219ca1473c3.tar.gz
tricot-5d38f2cf7f312de69a3106556fc43219ca1473c3.zip
Add basic support for metrics
Diffstat (limited to 'src/https.rs')
-rw-r--r--src/https.rs72
1 files changed, 66 insertions, 6 deletions
diff --git a/src/https.rs b/src/https.rs
index ba4365d..cb5e1c8 100644
--- a/src/https.rs
+++ b/src/https.rs
@@ -21,6 +21,8 @@ use tokio::sync::watch;
use tokio_rustls::TlsAcceptor;
use tokio_util::io::{ReaderStream, StreamReader};
+use opentelemetry::{metrics, KeyValue};
+
use crate::cert_store::{CertStore, StoreResolver};
use crate::proxy_config::ProxyConfig;
use crate::reverse_proxy;
@@ -33,6 +35,11 @@ pub struct HttpsConfig {
pub compress_mime_types: Vec<String>,
}
+struct HttpsMetrics {
+ requests_received: metrics::Counter<u64>,
+ requests_served: metrics::Counter<u64>,
+}
+
pub async fn serve_https(
config: HttpsConfig,
cert_store: Arc<CertStore>,
@@ -41,6 +48,18 @@ pub async fn serve_https(
) -> Result<()> {
let config = Arc::new(config);
+ let meter = opentelemetry::global::meter("tricot");
+ let metrics = Arc::new(HttpsMetrics {
+ requests_received: meter
+ .u64_counter("https_requests_received")
+ .with_description("Total number of requests received over HTTPS")
+ .init(),
+ requests_served: meter
+ .u64_counter("https_requests_served")
+ .with_description("Total number of requests served over HTTPS")
+ .init(),
+ });
+
let mut tls_cfg = rustls::ServerConfig::builder()
.with_safe_defaults()
.with_no_client_auth()
@@ -71,6 +90,7 @@ pub async fn serve_https(
let rx_proxy_config = rx_proxy_config.clone();
let tls_acceptor = tls_acceptor.clone();
let config = config.clone();
+ let metrics = metrics.clone();
let mut must_exit_2 = must_exit.clone();
let conn = tokio::spawn(async move {
@@ -84,7 +104,8 @@ pub async fn serve_https(
let https_config = config.clone();
let proxy_config: Arc<ProxyConfig> =
rx_proxy_config.borrow().clone();
- handle_outer(remote_addr, req, https_config, proxy_config)
+ let metrics = metrics.clone();
+ handle_outer(remote_addr, req, https_config, proxy_config, metrics)
}),
)
.with_upgrades();
@@ -124,17 +145,43 @@ async fn handle_outer(
req: Request<Body>,
https_config: Arc<HttpsConfig>,
proxy_config: Arc<ProxyConfig>,
+ metrics: Arc<HttpsMetrics>,
) -> Result<Response<Body>, Infallible> {
- match handle(remote_addr, req, https_config, proxy_config).await {
+ let mut tags = vec![
+ KeyValue::new("method", req.method().to_string()),
+ KeyValue::new(
+ "host",
+ req.uri()
+ .authority()
+ .map(|auth| auth.to_string())
+ .or_else(|| {
+ req.headers()
+ .get("host")
+ .map(|host| host.to_str().unwrap_or_default().to_string())
+ })
+ .unwrap_or_default(),
+ ),
+ ];
+ metrics.requests_received.add(1, &tags);
+
+ let resp = match handle(remote_addr, req, https_config, proxy_config, &mut tags).await {
Err(e) => {
warn!("Handler error: {}", e);
- Ok(Response::builder()
+ Response::builder()
.status(StatusCode::INTERNAL_SERVER_ERROR)
.body(Body::from(format!("{}", e)))
- .unwrap())
+ .unwrap()
}
- Ok(r) => Ok(r),
- }
+ Ok(r) => r,
+ };
+
+ tags.push(KeyValue::new(
+ "response_code",
+ resp.status().as_u16().to_string(),
+ ));
+ metrics.requests_served.add(1, &tags);
+
+ Ok(resp)
}
// Custom echo service, handling two different routes and a
@@ -144,6 +191,7 @@ async fn handle(
req: Request<Body>,
https_config: Arc<HttpsConfig>,
proxy_config: Arc<ProxyConfig>,
+ tags: &mut Vec<KeyValue>,
) -> Result<Response<Body>, anyhow::Error> {
let method = req.method().clone();
let uri = req.uri().to_string();
@@ -184,6 +232,18 @@ async fn handle(
});
if let Some(proxy_to) = best_match {
+ tags.push(KeyValue::new("service_name", proxy_to.service_name.clone()));
+ tags.push(KeyValue::new(
+ "target_addr",
+ proxy_to.target_addr.to_string(),
+ ));
+ tags.push(KeyValue::new(
+ "https_target",
+ proxy_to.https_target.to_string(),
+ ));
+ tags.push(KeyValue::new("same_node", proxy_to.same_node.to_string()));
+ tags.push(KeyValue::new("same_site", proxy_to.same_site.to_string()));
+
proxy_to.calls.fetch_add(1, Ordering::SeqCst);
debug!("{}{} -> {}", host, path, proxy_to);