From 7cbc9178d8ca14ec01d75332dded44aae2c867aa Mon Sep 17 00:00:00 2001 From: Saraj Munjal Date: Thu, 29 Aug 2024 07:47:58 -0700 Subject: [PATCH] Bump the hyper crate to v1.4.1 and rework prometheus server handling (#778) Bump hyper to v1.4.1 and rework prometheus server handling --- Cargo.lock | 92 ++++++++++++++++++++++++++--------------------- Cargo.toml | 4 ++- src/prometheus.rs | 46 +++++++++++++++++++----- 3 files changed, 92 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6699ce6..e0dff6e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -146,6 +146,12 @@ dependencies = [ "syn 2.0.26", ] +[[package]] +name = "atomic-waker" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" + [[package]] name = "atomic_enum" version = "0.2.0" @@ -542,29 +548,23 @@ checksum = "b6c80984affa11d98d1b88b66ac8853f143217b399d3c74116778ff8fdb4ed2e" [[package]] name = "h2" -version = "0.3.20" +version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97ec8491ebaf99c8eaa73058b045fe58073cd6be7f596ac993ced0b0a0c01049" +checksum = "524e8ac6999421f49a846c2d4411f337e53497d8ec55d67753beffa43c5d9205" dependencies = [ + "atomic-waker", "bytes", "fnv", "futures-core", "futures-sink", - "futures-util", "http", - "indexmap 1.9.3", + "indexmap", "slab", "tokio", "tokio-util", "tracing", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "hashbrown" version = "0.14.0" @@ -609,9 +609,9 @@ dependencies = [ [[package]] name = "http" -version = "0.2.9" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" dependencies = [ "bytes", "fnv", @@ -620,12 +620,24 @@ dependencies = [ [[package]] name = "http-body" -version = "0.4.5" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" +checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", "http", +] + +[[package]] +name = "http-body-util" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", "pin-project-lite", ] @@ -643,13 +655,12 @@ checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" [[package]] name = "hyper" -version = "0.14.27" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffb1cfd654a8219eaef89881fdb3bb3b1cdc5fa75ded05d6933b2b382e395468" +checksum = "50dfd22e0e76d0f662d429a5f80fcaf3855009297eab6a0a9f8543834744ba05" dependencies = [ "bytes", "futures-channel", - "futures-core", "futures-util", "h2", "http", @@ -658,13 +669,26 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "socket2 0.4.9", + "smallvec", "tokio", - "tower-service", - "tracing", "want", ] +[[package]] +name = "hyper-util" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cde7055719c54e36e95e8719f95883f22072a48ede39db7fc17a4e1d5281e9b9" +dependencies = [ + "bytes", + "futures-util", + "http", + "http-body", + "hyper", + "pin-project-lite", + "tokio", +] + [[package]] name = "iana-time-zone" version = "0.1.57" @@ -709,16 +733,6 @@ dependencies = [ "unicode-normalization", ] -[[package]] -name = "indexmap" -version = "1.9.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" -dependencies = [ - "autocfg", - "hashbrown 0.12.3", -] - [[package]] name = "indexmap" version = "2.0.0" @@ -726,7 +740,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5477fe2230a79769d8dc68e0eabf5437907c0457a5614a9e8dddb67f65eb65d" dependencies = [ "equivalent", - "hashbrown 0.14.0", + "hashbrown", ] [[package]] @@ -848,7 +862,7 @@ version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efa59af2ddfad1854ae27d75009d538d0998b4b2fd47083e743ac1a10e46c60" dependencies = [ - "hashbrown 0.14.0", + "hashbrown", ] [[package]] @@ -1034,7 +1048,9 @@ dependencies = [ "fallible-iterator", "futures", "hmac", + "http-body-util", "hyper", + "hyper-util", "itertools", "jemallocator", "log", @@ -1478,9 +1494,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" +checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "socket2" @@ -1741,19 +1757,13 @@ version = "0.19.14" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f8123f27e969974a3dfba720fdb560be359f57b44302d280ba72e76a74480e8a" dependencies = [ - "indexmap 2.0.0", + "indexmap", "serde", "serde_spanned", "toml_datetime", "winnow", ] -[[package]] -name = "tower-service" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" - [[package]] name = "tracing" version = "0.1.37" diff --git a/Cargo.toml b/Cargo.toml index f408ba4..390d9d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,7 +29,9 @@ base64 = "0.21" stringprep = "0.1" tokio-rustls = "0.24" rustls-pemfile = "1" -hyper = { version = "0.14", features = ["full"] } +http-body-util = "0.1.2" +hyper = { version = "1.4.1", features = ["full"] } +hyper-util = { version = "0.1.7", features = ["tokio"] } phf = { version = "0.11.1", features = ["macros"] } exitcode = "1.1.2" futures = "0.3" diff --git a/src/prometheus.rs b/src/prometheus.rs index 7e264dc..d8e2346 100644 --- a/src/prometheus.rs +++ b/src/prometheus.rs @@ -1,5 +1,11 @@ -use hyper::service::{make_service_fn, service_fn}; -use hyper::{Body, Method, Request, Response, Server, StatusCode}; +use http_body_util::Full; +use hyper::body; +use hyper::body::Bytes; + +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Method, Request, Response, StatusCode}; +use hyper_util::rt::TokioIo; use log::{debug, error, info}; use phf::phf_map; use std::collections::HashMap; @@ -7,6 +13,7 @@ use std::fmt; use std::net::SocketAddr; use std::sync::atomic::Ordering; use std::sync::Arc; +use tokio::net::TcpListener; use crate::config::Address; use crate::pool::{get_all_pools, PoolIdentifier}; @@ -243,7 +250,9 @@ impl PrometheusMetric { } } -async fn prometheus_stats(request: Request) -> Result, hyper::http::Error> { +async fn prometheus_stats( + request: Request, +) -> Result>, hyper::http::Error> { match (request.method(), request.uri().path()) { (&Method::GET, "/metrics") => { let mut lines = Vec::new(); @@ -374,14 +383,35 @@ fn push_server_stats(lines: &mut Vec) { } pub async fn start_metric_server(http_addr: SocketAddr) { - let http_service_factory = - make_service_fn(|_conn| async { Ok::<_, hyper::Error>(service_fn(prometheus_stats)) }); - let server = Server::bind(&http_addr).serve(http_service_factory); + let listener = TcpListener::bind(http_addr); + let listener = match listener.await { + Ok(listener) => listener, + Err(e) => { + error!("Failed to bind prometheus server to HTTP address: {}.", e); + return; + } + }; info!( "Exposing prometheus metrics on http://{}/metrics.", http_addr ); - if let Err(e) = server.await { - error!("Failed to run HTTP server: {}.", e); + loop { + let stream = match listener.accept().await { + Ok((stream, _)) => stream, + Err(e) => { + error!("Error accepting connection: {}", e); + continue; + } + }; + let io = TokioIo::new(stream); + + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(prometheus_stats)) + .await + { + eprintln!("Error serving HTTP connection for metrics: {:?}", err); + } + }); } }