From 7cbba823f8139a49a03401a7200c1b03e82b3ab3 Mon Sep 17 00:00:00 2001 From: Drazen Date: Mon, 18 Mar 2024 20:14:59 +0100 Subject: [PATCH 01/13] metrics macros --- common/nym-metrics/src/lib.rs | 14 ++++++++++++++ mixnode/src/node/http/legacy/stats.rs | 6 +++--- mixnode/src/node/node_statistics.rs | 13 +++++++------ 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index d67aae7b94..a878deaad3 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -7,6 +7,20 @@ pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; +#[macro_export] +macro_rules! count { + ($name:literal, $x:expr) => { + $crate::REGISTRY.inc_by($name, $x); + }; +} + +#[macro_export] +macro_rules! metrics { + () => { + $crate::REGISTRY.to_string(); + }; +} + #[macro_export] macro_rules! nanos { ( $name:literal, $x:expr ) => {{ diff --git a/mixnode/src/node/http/legacy/stats.rs b/mixnode/src/node/http/legacy/stats.rs index 1bbc6eea21..c986acee2b 100644 --- a/mixnode/src/node/http/legacy/stats.rs +++ b/mixnode/src/node/http/legacy/stats.rs @@ -7,7 +7,7 @@ use axum::{ extract::{Query, State}, http::HeaderMap, }; -use nym_metrics::REGISTRY; +use nym_metrics::metrics; use nym_node::http::api::{FormattedResponse, Output}; use serde::{Deserialize, Serialize}; @@ -24,7 +24,7 @@ pub(crate) async fn metrics(State(state): State, headers: Heade if let Some(metrics_key) = state.metrics_key { if let Some(auth) = headers.get("Authorization") { if auth.to_str().unwrap_or_default() == format!("Bearer {}", metrics_key) { - REGISTRY.to_string() + metrics!() } else { "Unauthorized".to_string() } @@ -50,7 +50,7 @@ pub(crate) async fn stats( async fn generate_stats(full: bool, stats: SharedNodeStats) -> NodeStatsResponse { let snapshot_data = stats.clone_data().await; if full { - NodeStatsResponse::Full(REGISTRY.to_string()) + NodeStatsResponse::Full(metrics!()) } else { NodeStatsResponse::Simple(snapshot_data.simplify()) } diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 935ce6f3df..116bfd0a4a 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_metrics::REGISTRY; +use nym_metrics::count; use super::TaskClient; use futures::channel::mpsc; @@ -65,11 +65,11 @@ impl SharedNodeStats { guard.packets_dropped_since_startup_all += count; } - REGISTRY.inc_by("packets_received_since_startup", new_received); - REGISTRY.inc_by("packets_sent_since_startup_all", new_sent.values().sum()); - REGISTRY.inc_by( + count!("packets_received_since_startup", new_received); + count!("packets_sent_since_startup_all", new_sent.values().sum()); + count!( "packets_dropped_since_startup_all", - new_dropped.values().sum(), + new_dropped.values().sum() ); guard.packets_received_since_last_update = new_received; @@ -509,6 +509,7 @@ impl Controller { #[cfg(test)] mod tests { use super::*; + use nym_metrics::metrics; use nym_task::TaskManager; #[tokio::test] @@ -538,6 +539,6 @@ mod tests { assert_eq!(&stats.packets_sent_since_last_update.len(), &1); assert_eq!(&stats.packets_received_since_startup, &0.); assert_eq!(&stats.packets_dropped_since_startup_all, &0.); - assert_eq!(REGISTRY.to_string(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") + assert_eq!(metrics!(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") } } From 5753c309735e75fd59c589debef1d16ad4f10818 Mon Sep 17 00:00:00 2001 From: Drazen Date: Mon, 18 Mar 2024 20:43:33 +0100 Subject: [PATCH 02/13] Instrument client-core --- Cargo.lock | 1 + common/client-core/Cargo.toml | 1 + .../src/client/packet_statistics_control.rs | 19 ++++++ common/nym-metrics/src/lib.rs | 68 ++++++++++++++++--- mixnode/src/node/node_statistics.rs | 13 ++-- 5 files changed, 87 insertions(+), 15 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 06ff9e5780..07760e7212 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5201,6 +5201,7 @@ dependencies = [ "nym-explorer-client", "nym-gateway-client", "nym-gateway-requests", + "nym-metrics", "nym-network-defaults", "nym-nonexhaustive-delayqueue", "nym-pemstore", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index dc6c9bba2b..4179195c97 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -38,6 +38,7 @@ nym-crypto = { path = "../crypto" } nym-explorer-client = { path = "../../explorer-api/explorer-client" } nym-gateway-client = { path = "../client-libs/gateway-client" } nym-gateway-requests = { path = "../../gateway/gateway-requests" } +nym-metrics = { path = "../nym-metrics" } nym-nonexhaustive-delayqueue = { path = "../nonexhaustive-delayqueue" } nym-sphinx = { path = "../nymsphinx" } nym-pemstore = { path = "../pemstore" } diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index a50e0c596c..81cd3034a0 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,6 +3,7 @@ use std::{ time::{Duration, Instant}, }; +use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; use crate::spawn_future; @@ -53,42 +54,60 @@ impl PacketStatistics { PacketStatisticsEvent::RealPacketSent(packet_size) => { self.real_packets_sent += 1; self.real_packets_sent_size += packet_size; + inc!("real_packets_sent"); + inc_by!("real_packets_sent_size", packet_size); } PacketStatisticsEvent::CoverPacketSent(packet_size) => { self.cover_packets_sent += 1; self.cover_packets_sent_size += packet_size; + inc!("cover_packets_sent"); + inc_by!("cover_packets_sent_size", packet_size); } PacketStatisticsEvent::RealPacketReceived(packet_size) => { self.real_packets_received += 1; self.real_packets_received_size += packet_size; + inc!("real_packets_received"); + inc_by!("real_packets_received_size", packet_size); } PacketStatisticsEvent::CoverPacketReceived(packet_size) => { self.cover_packets_received += 1; self.cover_packets_received_size += packet_size; + inc!("cover_packets_received"); + inc_by!("cover_packets_received_size", packet_size); } PacketStatisticsEvent::AckReceived(packet_size) => { self.total_acks_received += 1; self.total_acks_received_size += packet_size; + inc!("total_acks_received"); + inc_by!("total_acks_received_size", packet_size); } PacketStatisticsEvent::RealAckReceived(packet_size) => { self.real_acks_received += 1; self.real_acks_received_size += packet_size; + inc!("real_acks_received"); + inc_by!("real_acks_received_size", packet_size); } PacketStatisticsEvent::CoverAckReceived(packet_size) => { self.cover_acks_received += 1; self.cover_acks_received_size += packet_size; + inc!("cover_acks_received"); + inc_by!("cover_acks_received_size", packet_size); } PacketStatisticsEvent::RealPacketQueued => { self.real_packets_queued += 1; + inc!("real_packets_queued"); } PacketStatisticsEvent::RetransmissionQueued => { self.retransmissions_queued += 1; + inc!("retransmissions_queued"); } PacketStatisticsEvent::ReplySurbRequestQueued => { self.reply_surbs_queued += 1; + inc!("reply_surbs_queued"); } PacketStatisticsEvent::AdditionalReplySurbRequestQueued => { self.additional_reply_surbs_queued += 1; + inc!("additional_reply_surbs_queued"); } } } diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index a878deaad3..6df54bb8e4 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -8,9 +8,16 @@ pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; #[macro_export] -macro_rules! count { +macro_rules! inc_by { ($name:literal, $x:expr) => { - $crate::REGISTRY.inc_by($name, $x); + $crate::REGISTRY.inc_by($name, $x as f64); + }; +} + +#[macro_export] +macro_rules! inc { + ($name:literal) => { + $crate::REGISTRY.inc($name); }; } @@ -57,6 +64,7 @@ fn fq_name(c: &dyn Collector) -> String { } impl Metric { + #[inline(always)] fn fq_name(&self) -> String { match self { Metric::C(c) => fq_name(c.as_ref()), @@ -64,6 +72,15 @@ impl Metric { } } + #[inline(always)] + fn inc(&self) { + match self { + Metric::C(c) => c.inc(), + Metric::G(g) => g.inc(), + } + } + + #[inline(always)] fn inc_by(&self, value: f64) { match self { Metric::C(c) => c.inc_by(value), @@ -71,6 +88,7 @@ impl Metric { } } + #[inline(always)] fn set(&self, value: f64) { match self { Metric::C(_c) => { @@ -83,14 +101,8 @@ impl Metric { impl fmt::Display for MetricsController { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - let mut buffer = vec![]; - let encoder = TextEncoder::new(); - let metrics = self.registry.gather(); - match encoder.encode(&metrics, &mut buffer) { - Ok(_) => {} - Err(e) => return write!(f, "Error encoding metrics to buffer: {}", e), - } - let output = match String::from_utf8(buffer) { + let metrics = self.gather(); + let output = match String::from_utf8(metrics) { Ok(output) => output, Err(e) => return write!(f, "Error decoding metrics to String: {}", e), }; @@ -99,6 +111,26 @@ impl fmt::Display for MetricsController { } impl MetricsController { + #[inline(always)] + pub fn gather(&self) -> Vec { + let mut buffer = vec![]; + let encoder = TextEncoder::new(); + let metrics = self.registry.gather(); + match encoder.encode(&metrics, &mut buffer) { + Ok(_) => {} + Err(e) => error!("Error encoding metrics to buffer: {}", e), + } + buffer + } + + pub fn to_writer(&self, writer: &mut dyn std::io::Write) { + let metrics = self.gather(); + match writer.write_all(&metrics) { + Ok(_) => {} + Err(e) => error!("Error writing metrics to writer: {}", e), + } + } + pub fn set(&self, name: &str, value: f64) { if let Some(metric) = self.registry_index.get(name) { metric.set(value); @@ -115,6 +147,22 @@ impl MetricsController { } } + pub fn inc(&self, name: &str) { + if let Some(metric) = self.registry_index.get(name) { + metric.inc(); + } else { + let counter = match Counter::new(sanitize_metric_name(name), name) { + Ok(c) => c, + Err(e) => { + debug!("Failed to create counter {:?}:\n{}", name, e); + return; + } + }; + self.register_counter(Box::new(counter)); + self.inc(name) + } + } + pub fn inc_by(&self, name: &str, value: f64) { if let Some(metric) = self.registry_index.get(name) { metric.inc_by(value); diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 116bfd0a4a..9ac08b2f0e 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -1,7 +1,7 @@ // Copyright 2023 - Nym Technologies SA // SPDX-License-Identifier: GPL-3.0-only -use nym_metrics::count; +use nym_metrics::inc_by; use super::TaskClient; use futures::channel::mpsc; @@ -65,11 +65,14 @@ impl SharedNodeStats { guard.packets_dropped_since_startup_all += count; } - count!("packets_received_since_startup", new_received); - count!("packets_sent_since_startup_all", new_sent.values().sum()); - count!( + inc_by!("packets_received_since_startup", new_received); + inc_by!( + "packets_sent_since_startup_all", + new_sent.values().sum::() + ); + inc_by!( "packets_dropped_since_startup_all", - new_dropped.values().sum() + new_dropped.values().sum::() ); guard.packets_received_since_last_update = new_received; From 72cffc71cc9dbcfcdce814a623feab7c8ab48477 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 10:22:20 +0100 Subject: [PATCH 03/13] Light server to statistics control --- Cargo.lock | 171 ++++++++++++++---- common/client-core/Cargo.toml | 15 +- .../src/client/packet_statistics_control.rs | 40 ++++ 3 files changed, 186 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 07760e7212..48c5ae1753 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -557,9 +557,9 @@ dependencies = [ "bitflags 1.3.2", "bytes", "futures-util", - "http", - "http-body", - "hyper", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "itoa", "matchit", "memchr", @@ -587,8 +587,8 @@ dependencies = [ "async-trait", "bytes", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "mime", "rustversion", "tower-layer", @@ -3011,7 +3011,7 @@ dependencies = [ "futures-core", "futures-sink", "gloo-utils", - "http", + "http 0.2.9", "js-sys", "pin-project", "serde", @@ -3080,7 +3080,7 @@ dependencies = [ "futures-core", "futures-sink", "futures-util", - "http", + "http 0.2.9", "indexmap 1.9.3", "slab", "tokio", @@ -3088,6 +3088,25 @@ dependencies = [ "tracing", ] +[[package]] +name = "h2" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" +dependencies = [ + "bytes", + "fnv", + "futures-core", + "futures-sink", + "futures-util", + "http 1.1.0", + "indexmap 2.0.2", + "slab", + "tokio", + "tokio-util", + "tracing", +] + [[package]] name = "half" version = "1.8.2" @@ -3290,6 +3309,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http-api-client" version = "0.1.0" @@ -3311,7 +3341,30 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" dependencies = [ "bytes", - "http", + "http 0.2.9", + "pin-project-lite 0.2.13", +] + +[[package]] +name = "http-body" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" +dependencies = [ + "bytes", + "http 1.1.0", +] + +[[package]] +name = "http-body-util" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0475f8b2ac86659c21b64320d5d653f9efe42acd2a4e560073ec61a155a34f1d" +dependencies = [ + "bytes", + "futures-core", + "http 1.1.0", + "http-body 1.0.0", "pin-project-lite 0.2.13", ] @@ -3378,9 +3431,9 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2", - "http", - "http-body", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", "httparse", "httpdate", "itoa", @@ -3392,6 +3445,27 @@ dependencies = [ "want", ] +[[package]] +name = "hyper" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "186548d73ac615b32a73aafe38fb4f56c0d340e110e5a200bcadbaf2e199263a" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "h2 0.4.3", + "http 1.1.0", + "http-body 1.0.0", + "httparse", + "httpdate", + "itoa", + "pin-project-lite 0.2.13", + "smallvec", + "tokio", + "want", +] + [[package]] name = "hyper-rustls" version = "0.24.1" @@ -3399,8 +3473,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d78e1e73ec14cf7375674f74d7dde185c8206fd9dea6fb6295e8a98098aaa97" dependencies = [ "futures-util", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "rustls 0.21.10", "tokio", "tokio-rustls 0.24.1", @@ -3412,12 +3486,32 @@ version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bbb958482e8c7be4bc3cf272a766a2b0bf1a6755e7a6ae777f017a31d11b13b1" dependencies = [ - "hyper", + "hyper 0.14.27", "pin-project-lite 0.2.13", "tokio", "tokio-io-timeout", ] +[[package]] +name = "hyper-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" +dependencies = [ + "bytes", + "futures-channel", + "futures-util", + "http 1.1.0", + "http-body 1.0.0", + "hyper 1.2.0", + "pin-project-lite 0.2.13", + "socket2 0.5.4", + "tokio", + "tower", + "tower-service", + "tracing", +] + [[package]] name = "iana-time-zone" version = "0.1.58" @@ -3742,7 +3836,7 @@ dependencies = [ "curl-sys", "event-listener", "futures-lite", - "http", + "http 0.2.9", "log", "once_cell", "polling", @@ -4555,7 +4649,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 0.2.9", "httparse", "log", "memchr", @@ -5192,7 +5286,10 @@ dependencies = [ "dirs 4.0.0", "futures", "gloo-timers", + "http-body-util", "humantime-serde", + "hyper 1.2.0", + "hyper-util", "log", "nym-bandwidth-controller", "nym-config", @@ -5515,7 +5612,7 @@ dependencies = [ "dotenvy", "futures", "humantime-serde", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "log", "nym-api-requests", @@ -5951,7 +6048,7 @@ dependencies = [ "dashmap", "fastrand 2.0.1", "hmac 0.12.1", - "hyper", + "hyper 0.14.27", "ipnetwork 0.16.0", "mime", "nym-config", @@ -6104,7 +6201,7 @@ dependencies = [ "dotenvy", "futures", "hex", - "http", + "http 0.2.9", "httpcodec", "libp2p", "log", @@ -6844,7 +6941,7 @@ checksum = "a819b71d6530c4297b49b3cae2939ab3a8cc1b9f382826a1bc29dd0ca3864906" dependencies = [ "async-trait", "bytes", - "http", + "http 0.2.9", "isahc", "opentelemetry_api", ] @@ -6858,7 +6955,7 @@ dependencies = [ "async-trait", "futures", "futures-executor", - "http", + "http 0.2.9", "isahc", "once_cell", "opentelemetry", @@ -8038,10 +8135,10 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-rustls", "ipnet", "js-sys", @@ -8200,7 +8297,7 @@ version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfac3a1df83f8d4fc96aa41dba3b86c786417b7fc0f52ec76295df2ba781aa69" dependencies = [ - "http", + "http 0.2.9", "log", "regex", "rocket", @@ -8220,8 +8317,8 @@ dependencies = [ "cookie", "either", "futures", - "http", - "hyper", + "http 0.2.9", + "hyper 0.14.27", "indexmap 2.0.2", "log", "memchr", @@ -9025,9 +9122,9 @@ dependencies = [ [[package]] name = "smallvec" -version = "1.11.1" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "snafu" @@ -9978,10 +10075,10 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2", - "http", - "http-body", - "hyper", + "h2 0.3.21", + "http 0.2.9", + "http-body 0.4.5", + "hyper 0.14.27", "hyper-timeout", "percent-encoding", "pin-project", @@ -10024,8 +10121,8 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "http", - "http-body", + "http 0.2.9", + "http-body 0.4.5", "http-range-header", "httpdate", "mime", @@ -10303,7 +10400,7 @@ dependencies = [ "byteorder", "bytes", "data-encoding", - "http", + "http 0.2.9", "httparse", "log", "rand 0.8.5", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 4179195c97..607ca15c36 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -27,10 +27,15 @@ tap = "1.0.1" thiserror = { workspace = true } url = { workspace = true, features = ["serde"] } tungstenite = { workspace = true, default-features = false } -tokio = { workspace = true, features = ["macros"]} +tokio = { workspace = true, features = ["macros"] } time = "0.3.17" zeroize = { workspace = true } +# For serving metrics +hyper = { version = "1", features = ["full"] } +http-body-util = "0.1" +hyper-util = { version = "0.1", features = ["full"] } + # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } @@ -92,11 +97,15 @@ tempfile = "3.1.0" [build-dependencies] tokio = { workspace = true, features = ["rt-multi-thread", "macros"] } -sqlx = { workspace = true, features = ["runtime-tokio-rustls", "sqlite", "macros", "migrate"] } +sqlx = { workspace = true, features = [ + "runtime-tokio-rustls", + "sqlite", + "macros", + "migrate", +] } [features] default = [] cli = ["clap"] fs-surb-storage = ["sqlx"] wasm = ["nym-gateway-client/wasm"] - diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 81cd3034a0..27fc90f0e4 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,9 +3,21 @@ use std::{ time::{Duration, Instant}, }; +use log::warn; use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; +// Metrics server +use http_body_util::Full; +use hyper::body::Bytes; +use hyper::server::conn::http1; +use hyper::service::service_fn; +use hyper::{Request, Response}; +use hyper_util::rt::TokioIo; +use std::convert::Infallible; +use std::net::SocketAddr; +use tokio::net::TcpListener; + use crate::spawn_future; // Time interval between reporting packet statistics @@ -484,6 +496,12 @@ impl PacketStatisticsControl { let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS); let mut snapshot_interval = tokio::time::interval(snapshot_interval); + let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener = TcpListener::bind(addr) + .await + .expect(&format!("Cannot bind metrics server to {metrics_port}!")); + loop { tokio::select! { stats_event = self.stats_rx.recv() => match stats_event { @@ -496,6 +514,22 @@ impl PacketStatisticsControl { break; } }, + result = listener.accept() => { + if let Ok((stream, _)) = result { + let io = TokioIo::new(stream); + + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(serve_metrics)) + .await + { + warn!("Error serving connection: {:?}", err); + } + }); + } else { + warn!("Error accepting connection"); + } + } _ = snapshot_interval.tick() => { self.update_history(); self.update_rates(); @@ -520,3 +554,9 @@ impl PacketStatisticsControl { }) } } + +async fn serve_metrics( + _: Request, +) -> Result>, Infallible> { + Ok(Response::new(Full::new(Bytes::from(metrics!())))) +} From 27978908d015e4a1c2d4e9232deb42d8c39dac08 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 12:41:35 +0100 Subject: [PATCH 04/13] Disable metrics server for wasm --- Cargo.lock | 31 ++----------------- common/client-core/Cargo.toml | 18 ++++++++--- .../src/client/packet_statistics_control.rs | 29 +++++++++++++---- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 48c5ae1753..d7ab5721bc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3088,25 +3088,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "h2" -version = "0.4.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51ee2dd2e4f378392eeff5d51618cd9a63166a2513846bbc55f21cfacd9199d4" -dependencies = [ - "bytes", - "fnv", - "futures-core", - "futures-sink", - "futures-util", - "http 1.1.0", - "indexmap 2.0.2", - "slab", - "tokio", - "tokio-util", - "tracing", -] - [[package]] name = "half" version = "1.8.2" @@ -3431,7 +3412,7 @@ dependencies = [ "futures-channel", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "httparse", @@ -3454,7 +3435,6 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "h2 0.4.3", "http 1.1.0", "http-body 1.0.0", "httparse", @@ -3463,7 +3443,6 @@ dependencies = [ "pin-project-lite 0.2.13", "smallvec", "tokio", - "want", ] [[package]] @@ -3499,7 +3478,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ca38ef113da30126bbff9cd1705f9273e15d45498615d138b0c20279ac7a76aa" dependencies = [ "bytes", - "futures-channel", "futures-util", "http 1.1.0", "http-body 1.0.0", @@ -3507,9 +3485,6 @@ dependencies = [ "pin-project-lite 0.2.13", "socket2 0.5.4", "tokio", - "tower", - "tower-service", - "tracing", ] [[package]] @@ -8135,7 +8110,7 @@ dependencies = [ "encoding_rs", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", @@ -10075,7 +10050,7 @@ dependencies = [ "bytes", "futures-core", "futures-util", - "h2 0.3.21", + "h2", "http 0.2.9", "http-body 0.4.5", "hyper 0.14.27", diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 607ca15c36..013efbeef5 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -31,11 +31,6 @@ tokio = { workspace = true, features = ["macros"] } time = "0.3.17" zeroize = { workspace = true } -# For serving metrics -hyper = { version = "1", features = ["full"] } -http-body-util = "0.1" -hyper-util = { version = "0.1", features = ["full"] } - # internal nym-bandwidth-controller = { path = "../bandwidth-controller" } nym-config = { path = "../config" } @@ -54,6 +49,19 @@ nym-credential-storage = { path = "../credential-storage" } nym-network-defaults = { path = "../network-defaults" } si-scale = "0.2.2" +### For serving prometheus metrics +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] +version = "1.2" +features = ["server", "http1"] + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util] +version = "0.1" + +[target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper-util] +version = "0.1" +features = ["tokio"] +### + [target."cfg(not(target_arch = \"wasm32\"))".dependencies.tokio-stream] version = "0.1.11" features = ["time"] diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 27fc90f0e4..f05054f73b 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -8,14 +8,23 @@ use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; // Metrics server +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use http_body_util::Full; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::body::Bytes; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::server::conn::http1; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::service::service_fn; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper::{Request, Response}; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use hyper_util::rt::TokioIo; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::convert::Infallible; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use std::net::SocketAddr; +#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] use tokio::net::TcpListener; use crate::spawn_future; @@ -496,11 +505,18 @@ impl PacketStatisticsControl { let snapshot_interval = Duration::from_millis(SNAPSHOT_INTERVAL_MS); let mut snapshot_interval = tokio::time::interval(snapshot_interval); - let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); - let listener = TcpListener::bind(addr) - .await - .expect(&format!("Cannot bind metrics server to {metrics_port}!")); + cfg_if::cfg_if! { + if #[cfg(all(target_arch = "wasm32", target_os = "unknown"))] { + log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); + let listener = None; + } else { + let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener = Some(TcpListener::bind(addr) + .await + .unwrap_or_else(|_ | panic!("Cannot bind metrics server to {metrics_port}!"))); + } + } loop { tokio::select! { @@ -514,7 +530,8 @@ impl PacketStatisticsControl { break; } }, - result = listener.accept() => { + // conditional will disable the branch if we're in wasm32-unknown-unknown + result = listener.as_ref().unwrap().accept(), if listener.is_some() => { if let Ok((stream, _)) = result { let io = TokioIo::new(stream); From af68da940643d2d4e0cc702e5c954edf05a07953 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 15:26:40 +0100 Subject: [PATCH 05/13] Dont panic on error --- .../src/client/packet_statistics_control.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index f05054f73b..27c7c7f48b 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -512,9 +512,13 @@ impl PacketStatisticsControl { } else { let metrics_port = 18000; let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); - let listener = Some(TcpListener::bind(addr) - .await - .unwrap_or_else(|_ | panic!("Cannot bind metrics server to {metrics_port}!"))); + let listener = match TcpListener::bind(addr).await { + Ok(listener) => Some(listener), + Err(err) => { + log::error!("Failed to bind metrics server: {:?}", err); + None + } + }; } } From 46a319bd7a3acb9354bbf0741ebd2486bac326cd Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 16:36:47 +0100 Subject: [PATCH 06/13] Randomize port assignemnt --- .../src/client/packet_statistics_control.rs | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 27c7c7f48b..7119687809 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -3,7 +3,7 @@ use std::{ time::{Duration, Instant}, }; -use log::warn; +use log::{info, warn}; use nym_metrics::{inc, inc_by, metrics}; use si_scale::helpers::bibytes2; @@ -510,10 +510,16 @@ impl PacketStatisticsControl { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); let listener = None; } else { - let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + // let metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], 0)); + let listener = match TcpListener::bind(addr).await { - Ok(listener) => Some(listener), + Ok(listener) => { + info!("###############################"); + info!("Metrics endpoint is at: {:?}", listener.local_addr()); + info!("###############################"); + Some(listener) + }, Err(err) => { log::error!("Failed to bind metrics server: {:?}", err); None From 0b82109e3c25991523af2191b9e0f73de72b91dd Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 16:53:47 +0100 Subject: [PATCH 07/13] Predictable IP range --- .../src/client/packet_statistics_control.rs | 32 +++++++++++-------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 7119687809..287dc944c9 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -510,21 +510,25 @@ impl PacketStatisticsControl { log::warn!("Metrics server is not supported on wasm32-unknown-unknown"); let listener = None; } else { - // let metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], 0)); + let mut metrics_port = 18000; + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); + let listener: Option; + loop { + match TcpListener::bind(addr).await { + Ok(l) => { + info!("###############################"); + info!("Metrics endpoint is at: {:?}", l.local_addr()); + info!("###############################"); + listener = Some(l); + break; + }, + Err(err) => { + log::warn!("Failed to bind metrics server: {:?}", err); + metrics_port += 1; + } + }; + } - let listener = match TcpListener::bind(addr).await { - Ok(listener) => { - info!("###############################"); - info!("Metrics endpoint is at: {:?}", listener.local_addr()); - info!("###############################"); - Some(listener) - }, - Err(err) => { - log::error!("Failed to bind metrics server: {:?}", err); - None - } - }; } } From 7ecac4a7b432a1e61e40172117779b5b94471582 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 16:58:30 +0100 Subject: [PATCH 08/13] Fix predictable port range :) --- common/client-core/src/client/packet_statistics_control.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 287dc944c9..124688a10d 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -511,9 +511,9 @@ impl PacketStatisticsControl { let listener = None; } else { let mut metrics_port = 18000; - let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); let listener: Option; loop { + let addr = SocketAddr::from(([0, 0, 0, 0], metrics_port)); match TcpListener::bind(addr).await { Ok(l) => { info!("###############################"); From e2aa7aa31cc924117e20b54220522918d1bda042 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 19:49:44 +0100 Subject: [PATCH 09/13] Relax hyper dependency --- common/client-core/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/common/client-core/Cargo.toml b/common/client-core/Cargo.toml index 013efbeef5..fdc6a39b7a 100644 --- a/common/client-core/Cargo.toml +++ b/common/client-core/Cargo.toml @@ -51,7 +51,7 @@ si-scale = "0.2.2" ### For serving prometheus metrics [target."cfg(not(target_arch = \"wasm32\"))".dependencies.hyper] -version = "1.2" +version = "1" features = ["server", "http1"] [target."cfg(not(target_arch = \"wasm32\"))".dependencies.http-body-util] From e67d3d816ccdda8e57df6154c286c8cbedf4a5c1 Mon Sep 17 00:00:00 2001 From: durch Date: Tue, 19 Mar 2024 20:50:46 +0100 Subject: [PATCH 10/13] Push package name to metrics --- Cargo.lock | 1 - common/nym-metrics/Cargo.toml | 1 - common/nym-metrics/src/lib.rs | 50 +++++++++++++++++++++++++---- mixnode/src/node/node_statistics.rs | 2 +- 4 files changed, 44 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7ab5721bc..95685f31c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5792,7 +5792,6 @@ dependencies = [ "lazy_static", "log", "prometheus", - "regex", ] [[package]] diff --git a/common/nym-metrics/Cargo.toml b/common/nym-metrics/Cargo.toml index 0b49297719..537a69a142 100644 --- a/common/nym-metrics/Cargo.toml +++ b/common/nym-metrics/Cargo.toml @@ -14,5 +14,4 @@ license.workspace = true prometheus = { workspace = true } log = { workspace = true } dashmap = { workspace = true } -regex = "1.1" lazy_static = "1.4" diff --git a/common/nym-metrics/src/lib.rs b/common/nym-metrics/src/lib.rs index 6df54bb8e4..a9e22909d3 100644 --- a/common/nym-metrics/src/lib.rs +++ b/common/nym-metrics/src/lib.rs @@ -1,23 +1,37 @@ use dashmap::DashMap; pub use log::error; use log::{debug, warn}; -use regex::Regex; use std::fmt; pub use std::time::Instant; use prometheus::{core::Collector, Counter, Encoder as _, Gauge, Registry, TextEncoder}; +#[macro_export] +macro_rules! prepend_package_name { + ($name: literal) => { + &format!( + "{}_{}", + std::module_path!() + .split("::") + .next() + .unwrap_or("x") + .to_string(), + $name + ) + }; +} + #[macro_export] macro_rules! inc_by { ($name:literal, $x:expr) => { - $crate::REGISTRY.inc_by($name, $x as f64); + $crate::REGISTRY.inc_by($crate::prepend_package_name!($name), $x as f64); }; } #[macro_export] macro_rules! inc { ($name:literal) => { - $crate::REGISTRY.inc($name); + $crate::REGISTRY.inc($crate::prepend_package_name!($name)); }; } @@ -35,13 +49,13 @@ macro_rules! nanos { // if the block needs to return something, we can return it let r = $x; let duration = start.elapsed().as_nanos() as f64; + let name = $crate::prepend_package_name!($name); $crate::REGISTRY.inc_by(&format!("{}_nanos", $name), duration); r }}; } lazy_static::lazy_static! { - pub static ref RE: Regex = Regex::new(r"[^a-zA-Z0-9_]").unwrap(); pub static ref REGISTRY: MetricsController = MetricsController::default(); } @@ -223,9 +237,31 @@ impl MetricsController { } } -#[inline(always)] fn sanitize_metric_name(name: &str) -> String { - RE.replace_all(name, "_").to_string() + // The first character must be [a-zA-Z_:], and all subsequent characters must be [a-zA-Z0-9_:]. + let mut out = String::with_capacity(name.len()); + let mut is_invalid: fn(char) -> bool = invalid_metric_name_start_character; + for c in name.chars() { + if is_invalid(c) { + out.push('_'); + } else { + out.push(c); + } + is_invalid = invalid_metric_name_character; + } + out +} + +#[inline] +fn invalid_metric_name_start_character(c: char) -> bool { + // Essentially, needs to match the regex pattern of [a-zA-Z_:]. + !(c.is_ascii_alphabetic() || c == '_' || c == ':') +} + +#[inline] +fn invalid_metric_name_character(c: char) -> bool { + // Essentially, needs to match the regex pattern of [a-zA-Z0-9_:]. + !(c.is_ascii_alphanumeric() || c == '_' || c == ':') } #[cfg(test)] @@ -236,7 +272,7 @@ mod tests { fn test_sanitization() { assert_eq!( sanitize_metric_name("packets_sent_34.242.65.133:1789"), - "packets_sent_34_242_65_133_1789" + "packets_sent_34_242_65_133:1789" ) } } diff --git a/mixnode/src/node/node_statistics.rs b/mixnode/src/node/node_statistics.rs index 9ac08b2f0e..aaabbb7a30 100644 --- a/mixnode/src/node/node_statistics.rs +++ b/mixnode/src/node/node_statistics.rs @@ -542,6 +542,6 @@ mod tests { assert_eq!(&stats.packets_sent_since_last_update.len(), &1); assert_eq!(&stats.packets_received_since_startup, &0.); assert_eq!(&stats.packets_dropped_since_startup_all, &0.); - assert_eq!(metrics!(), "# HELP packets_dropped_since_startup_all packets_dropped_since_startup_all\n# TYPE packets_dropped_since_startup_all counter\npackets_dropped_since_startup_all 0\n# HELP packets_received_since_startup packets_received_since_startup\n# TYPE packets_received_since_startup counter\npackets_received_since_startup 0\n# HELP packets_sent_since_startup_all packets_sent_since_startup_all\n# TYPE packets_sent_since_startup_all counter\npackets_sent_since_startup_all 2\n") + assert_eq!(metrics!(), "# HELP nym_mixnode_packets_dropped_since_startup_all nym_mixnode_packets_dropped_since_startup_all\n# TYPE nym_mixnode_packets_dropped_since_startup_all counter\nnym_mixnode_packets_dropped_since_startup_all 0\n# HELP nym_mixnode_packets_received_since_startup nym_mixnode_packets_received_since_startup\n# TYPE nym_mixnode_packets_received_since_startup counter\nnym_mixnode_packets_received_since_startup 0\n# HELP nym_mixnode_packets_sent_since_startup_all nym_mixnode_packets_sent_since_startup_all\n# TYPE nym_mixnode_packets_sent_since_startup_all counter\nnym_mixnode_packets_sent_since_startup_all 2\n") } } From 7ccba11d82766cc49b5fe4d60251775505977748 Mon Sep 17 00:00:00 2001 From: durch Date: Wed, 20 Mar 2024 12:57:08 +0100 Subject: [PATCH 11/13] Static targets script --- scripts/static_prom_targets.py | 43 ++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 scripts/static_prom_targets.py diff --git a/scripts/static_prom_targets.py b/scripts/static_prom_targets.py new file mode 100644 index 0000000000..e3490ea089 --- /dev/null +++ b/scripts/static_prom_targets.py @@ -0,0 +1,43 @@ +import json +import os + + +ips = [ + "2.221.182.179", + "54.232.20.104", + "15.237.112.155", + "54.93.108.209", + "13.38.74.100", + "15.237.93.154", + "18.156.175.57", + "3.76.123.170", +] + +port_range = range(18000, 18999) + + +def make_prom_target(ip, port, env): + return { + "targets": [f"{ip}:{port}"], + "labels": { + "mixnet_env": env, + }, + } + + +if __name__ == "__main__": + outfile = "/tmp/tmp_static_prom_tragets.json" + outlink = "/tmp/static_prom_tragets.json" + targets = [] + for ip in ips: + for port in port_range: + targets.append(make_prom_target(ip, port, "performance")) + + with open(outfile, "w") as f: + json.dump(targets, f) + + os.chmod(outfile, 0o777) + os.rename(outfile, outlink) + os.chmod(outlink, 0o777) + + print(f"Prometheus -> {len(targets)} targets written to {outlink}") From 9a5d6103d691ed1865cfb508e4b02da61d573190 Mon Sep 17 00:00:00 2001 From: durch Date: Wed, 20 Mar 2024 13:25:26 +0100 Subject: [PATCH 12/13] Fix gateway target generation --- scripts/prom_targets.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/scripts/prom_targets.py b/scripts/prom_targets.py index e7887e1ed1..44ea2a3c83 100644 --- a/scripts/prom_targets.py +++ b/scripts/prom_targets.py @@ -72,7 +72,9 @@ def config_to_targets(config, mixnodes, labels=None): def make_prom_target(env, mixnode, port=None, labels=None): bond_info = mixnode.get("bond_information", {}) - mix_node = bond_info.get("mix_node", {}) + mix_node = bond_info.get("mix_node") + if mix_node is None: + mix_node = mixnode.get("gateway") host = mix_node.get("host", None) port = port if port else mix_node.get("http_api_port", None) if host is None or port is None: From eb914463dcf5678d5f731e78404cf581b9aa77e0 Mon Sep 17 00:00:00 2001 From: durch Date: Wed, 20 Mar 2024 13:27:58 +0100 Subject: [PATCH 13/13] Fix wasm build --- .../src/client/packet_statistics_control.rs | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/common/client-core/src/client/packet_statistics_control.rs b/common/client-core/src/client/packet_statistics_control.rs index 124688a10d..8f5aaf434d 100644 --- a/common/client-core/src/client/packet_statistics_control.rs +++ b/common/client-core/src/client/packet_statistics_control.rs @@ -546,19 +546,23 @@ impl PacketStatisticsControl { }, // conditional will disable the branch if we're in wasm32-unknown-unknown result = listener.as_ref().unwrap().accept(), if listener.is_some() => { - if let Ok((stream, _)) = result { - let io = TokioIo::new(stream); + cfg_if::cfg_if! { + if #[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))] { + if let Ok((stream, _)) = result { + let io = TokioIo::new(stream); - tokio::task::spawn(async move { - if let Err(err) = http1::Builder::new() - .serve_connection(io, service_fn(serve_metrics)) - .await - { - warn!("Error serving connection: {:?}", err); + tokio::task::spawn(async move { + if let Err(err) = http1::Builder::new() + .serve_connection(io, service_fn(serve_metrics)) + .await + { + warn!("Error serving connection: {:?}", err); + } + }); + } else { + warn!("Error accepting connection"); } - }); - } else { - warn!("Error accepting connection"); + } } } _ = snapshot_interval.tick() => {