From 424a53d44ae68b5b86e6f850f6aa3f301e074f2e Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Tue, 17 Mar 2026 23:36:17 +0000 Subject: [PATCH 1/6] add tokio runtime metrics --- README.md | 11 +++ src/app.rs | 33 +++++---- src/metrics.rs | 1 + src/metrics/tokio_runtime.rs | 134 +++++++++++++++++++++++++++++++++++ 4 files changed, 165 insertions(+), 14 deletions(-) create mode 100644 src/metrics/tokio_runtime.rs diff --git a/README.md b/README.md index 18be705a2b..2c383d17e3 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,17 @@ accessible by making an HTTP request to either "/stats/prometheus" or "/metrics" - XDS Connection terminations (`istio_xds_connection_terminations_total`) +#### Tokio metrics + +Metrics for the data plane worker pool Tokio runtime. + +- Number of worker threads (`tokio_num_workers`) +- Tasks in global queue (`tokio_global_queue_depth`) +- Alive tasks (`tokio_num_alive_tasks`) +- Worker busy duration (`tokio_worker_total_busy_duration_seconds`): Per-worker counter with `worker` label +- Worker park count (`tokio_worker_park_count`): Per-worker counter with `worker` label +- Worker park/unpark count (`tokio_worker_park_unpark_count`): Per-worker counter with `worker` label + ## Logging Ztunnel exposes a variety of logs, both operational and "access logs". diff --git a/src/app.rs b/src/app.rs index 01e214de21..f654184f04 100644 --- a/src/app.rs +++ b/src/app.rs @@ -37,7 +37,7 @@ pub async fn build_with_cert( cert_manager: Arc, ) -> anyhow::Result { // Start the data plane worker pool. - let data_plane_pool = new_data_plane_pool(config.num_worker_threads); + let (data_plane_pool, data_plane_handle) = new_data_plane_pool(config.num_worker_threads); let shutdown = signal::Shutdown::new(); // Setup a drain channel. drain_tx is used to trigger a drain, which will complete @@ -78,6 +78,7 @@ pub async fn build_with_cert( // Register metrics. let mut registry = Registry::default(); register_process_metrics(&mut registry); + metrics::tokio_runtime::TokioRuntimeCollector::register(&mut registry, &data_plane_handle); let istio_registry = metrics::sub_registry(&mut registry); let _ = metrics::meta::Metrics::new(istio_registry); let xds_metrics = xds::Metrics::new(istio_registry); @@ -261,23 +262,27 @@ struct DataPlaneTask { fut: Pin> + Send + Sync + 'static>>, } -fn new_data_plane_pool(num_worker_threads: usize) -> mpsc::Sender { +fn new_data_plane_pool( + num_worker_threads: usize, +) -> (mpsc::Sender, tokio::runtime::Handle) { let (tx, rx) = mpsc::channel(); + let runtime = tokio::runtime::Builder::new_multi_thread() + .worker_threads(num_worker_threads) + .thread_name_fn(|| { + static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0); + let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst); + format!("ztunnel-{id}") + }) + .enable_all() + .build() + .unwrap(); + + let handle = runtime.handle().clone(); + let span = tracing::span::Span::current(); thread::spawn(move || { let _span = span.enter(); - let runtime = tokio::runtime::Builder::new_multi_thread() - .worker_threads(num_worker_threads) - .thread_name_fn(|| { - static ATOMIC_ID: AtomicUsize = AtomicUsize::new(0); - let id = ATOMIC_ID.fetch_add(1, Ordering::SeqCst); - // Thread name can only be 16 chars so keep it short - format!("ztunnel-{id}") - }) - .enable_all() - .build() - .unwrap(); runtime.block_on( async move { let mut join_set = JoinSet::new(); @@ -309,7 +314,7 @@ fn new_data_plane_pool(num_worker_threads: usize) -> mpsc::Sender ); }); - tx + (tx, handle) } pub async fn build(config: Arc) -> anyhow::Result { diff --git a/src/metrics.rs b/src/metrics.rs index f6d63c6e1f..ac2108cefa 100644 --- a/src/metrics.rs +++ b/src/metrics.rs @@ -26,6 +26,7 @@ use crate::identity::Identity; pub mod meta; pub mod process; pub mod server; +pub mod tokio_runtime; use crate::strng::{RichStrng, Strng}; pub use server::*; diff --git a/src/metrics/tokio_runtime.rs b/src/metrics/tokio_runtime.rs new file mode 100644 index 0000000000..144935698f --- /dev/null +++ b/src/metrics/tokio_runtime.rs @@ -0,0 +1,134 @@ +// Copyright Istio Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +use prometheus_client::collector::Collector; +use prometheus_client::encoding::{DescriptorEncoder, EncodeLabelSet, EncodeMetric}; +use prometheus_client::metrics::MetricType; +use prometheus_client::metrics::counter::ConstCounter; +use prometheus_client::metrics::gauge::ConstGauge; +use prometheus_client::registry::Registry; + +#[derive(Debug)] +pub struct TokioRuntimeCollector { + metrics: tokio::runtime::RuntimeMetrics, +} + +impl TokioRuntimeCollector { + pub fn new(handle: &tokio::runtime::Handle) -> Self { + Self { + metrics: handle.metrics(), + } + } + + pub fn register(registry: &mut Registry, handle: &tokio::runtime::Handle) { + registry + .sub_registry_with_prefix("tokio") + .register_collector(Box::new(Self::new(handle))); + } +} + +#[derive(Clone, Debug, Hash, PartialEq, Eq, EncodeLabelSet)] +struct LabelSet { + worker: usize, +} + +macro_rules! encode_gauge { + ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ + let metric = ConstGauge::new($self.metrics.$name() as i64); + let metric_encoder = + $encoder.encode_descriptor(stringify!($name), $help, None, metric.metric_type())?; + metric.encode(metric_encoder)?; + }}; +} + +macro_rules! encode_per_worker_duration_seconds { + ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ + let mut family_encoder = $encoder.encode_descriptor( + concat!(stringify!($name), "_seconds"), + $help, + None, + MetricType::Counter, + )?; + for worker in 0..$self.metrics.num_workers() { + let metric = ConstCounter::new($self.metrics.$name(worker).as_secs_f64()); + let labels = LabelSet { worker }; + let metric_encoder = family_encoder.encode_family(&labels)?; + metric.encode(metric_encoder)?; + } + }}; +} + +macro_rules! encode_per_worker_count { + ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ + let mut family_encoder = + $encoder.encode_descriptor(stringify!($name), $help, None, MetricType::Counter)?; + for worker in 0..$self.metrics.num_workers() { + let metric = ConstGauge::new($self.metrics.$name(worker) as i64); + let labels = LabelSet { worker }; + let metric_encoder = family_encoder.encode_family(&labels)?; + metric.encode(metric_encoder)?; + } + }}; +} + +impl Collector for TokioRuntimeCollector { + fn encode(&self, mut encoder: DescriptorEncoder) -> Result<(), std::fmt::Error> { + encode_gauge!( + self, + &mut encoder, + num_workers, + "the number of worker threads used by the runtime" + ); + + encode_gauge!( + self, + &mut encoder, + global_queue_depth, + "the number of tasks currently scheduled in the runtime's global queue" + ); + + encode_gauge!( + self, + &mut encoder, + num_alive_tasks, + "the number of alive tasks in the runtime" + ); + + #[cfg(target_has_atomic = "64")] + encode_per_worker_duration_seconds!( + self, + &mut encoder, + worker_total_busy_duration, + "the amount of time worker threads have been busy" + ); + + #[cfg(target_has_atomic = "64")] + encode_per_worker_count!( + self, + &mut encoder, + worker_park_count, + "the total number of times the given worker thread has parked" + ); + + #[cfg(target_has_atomic = "64")] + encode_per_worker_count!( + self, + &mut encoder, + worker_park_unpark_count, + "the total number of times the given worker thread has parked and unparked" + ); + + Ok(()) + } +} From 351db6688fa1e3953dcd4b4f3a9a5547354b3d1a Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Wed, 18 Mar 2026 13:43:22 +0000 Subject: [PATCH 2/6] fix test_stats_exist --- tests/direct.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tests/direct.rs b/tests/direct.rs index e1b7af3fdc..8d7e97ee6e 100644 --- a/tests/direct.rs +++ b/tests/direct.rs @@ -384,6 +384,12 @@ async fn test_stats_exist() { "istio_tcp_sent_bytes", "process_max_fds", "process_open_fds", + "tokio_num_workers", + "tokio_global_queue_depth", + "tokio_num_alive_tasks", + "tokio_worker_park_count", + "tokio_worker_park_unpark_count", + "tokio_worker_total_busy_duration_seconds", ]); { for (name, doc) in metric_info { From 0d30bd1efd082f7dd2a50ca537fa71966e568c00 Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Wed, 8 Apr 2026 20:35:18 +0200 Subject: [PATCH 3/6] cd fuzz && cargo update --- fuzz/Cargo.lock | 160 +++++++++++++++++++++++------------------------- 1 file changed, 77 insertions(+), 83 deletions(-) diff --git a/fuzz/Cargo.lock b/fuzz/Cargo.lock index 40bd1e5db7..632489b1ca 100644 --- a/fuzz/Cargo.lock +++ b/fuzz/Cargo.lock @@ -199,9 +199,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.39.0" +version = "0.39.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fa7e52a4c5c547c741610a2c6f123f3881e409b714cd27e6798ef020c514f0a" +checksum = "83a25cf98105baa966497416dbd42565ce3a8cf8dbfd59803ec9ad46f3126399" dependencies = [ "cc", "cmake", @@ -288,9 +288,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.58" +version = "1.2.59" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +checksum = "b7a4d3ec6524d28a329fc53654bbadc9bdd7b0431f5d65f1a56ffb28a1ee5283" dependencies = [ "find-msvc-tools", "jobserver", @@ -699,9 +699,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.3.0" +version = "2.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +checksum = "9f1f227452a390804cdb637b74a86990f2a7d7ba4b7d5693aac9b4dd6defd8d6" [[package]] name = "file-id" @@ -1150,9 +1150,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -1165,7 +1165,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -1240,12 +1239,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -1253,9 +1253,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -1266,9 +1266,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -1280,15 +1280,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -1300,15 +1300,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -1348,9 +1348,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -1465,9 +1465,9 @@ dependencies = [ [[package]] name = "js-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b49715b7073f385ba4bc528e5747d02e66cb39c6146efb66b781f131f0fb399c" +checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ "once_cell", "wasm-bindgen", @@ -1516,9 +1516,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libfuzzer-sys" @@ -1544,9 +1544,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -1929,12 +1929,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pingora-pool" version = "0.8.0" @@ -1999,9 +1993,9 @@ checksum = "c33a9471896f1c69cecef8d20cbe2f7accd12527ce60845ff44c153bb2a21b49" [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -2085,9 +2079,9 @@ dependencies = [ [[package]] name = "prometheus-client" -version = "0.24.0" +version = "0.24.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e4500adecd7af8e0e9f4dbce15cfee07ce913fbf6ad605cc468b83f2d531ee94" +checksum = "cca3d75b4566b9a29fe1ed623587fb058e826eb329a0be4b7c4da1ebb2d7a6ca" dependencies = [ "dtoa", "itoa", @@ -2628,9 +2622,9 @@ checksum = "689224d06523904ebcc9b482c6a3f4f7fb396096645c4cd10c0d2ff7371a34d3" [[package]] name = "semver" -version = "1.0.27" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +checksum = "8a7852d02fc848982e0c167ef163aaff9cd91dc640ba85e263cb1ce46fae51cd" [[package]] name = "serde" @@ -2764,9 +2758,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.17.3" +version = "12.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52ca086c1eb5c7ee74b151ba83c6487d5d33f8c08ad991b86f3f58f6629e68d5" +checksum = "803d14d7cb9c6fa5b95a6f3de8af95b356a528d391998fa45a07d320a5573e51" dependencies = [ "debugid", "memmap2", @@ -2776,9 +2770,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.17.3" +version = "12.17.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baa911a28a62823aaf2cc2e074212492a3ee69d0d926cc8f5b12b4a108ff5c0c" +checksum = "39505731ae891b2dde47b0e4ae2ec40a7ced3476ab1129f1bf829e3fba62bb83" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -2954,9 +2948,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -3001,9 +2995,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "f66bf9585cda4b724d3e78ab34b73fb2bbaba9011b9bfdf69dc836382ea13b8c" dependencies = [ "bytes", "libc", @@ -3018,9 +3012,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -3368,9 +3362,9 @@ dependencies = [ [[package]] name = "wasm-bindgen" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6532f9a5c1ece3798cb1c2cfdba640b9b3ba884f5db45973a6f442510a87d38e" +checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ "cfg-if", "once_cell", @@ -3381,9 +3375,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "18a2d50fcf105fb33bb15f00e7a77b772945a2ee45dcf454961fd843e74c18e6" +checksum = "7fbdf9a35adf44786aecd5ff89b4563a90325f9da0923236f6104e603c7e86be" dependencies = [ "quote", "wasm-bindgen-macro-support", @@ -3391,9 +3385,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-macro-support" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "03ce4caeaac547cdf713d280eda22a730824dd11e6b8c3ca9e42247b25c631e3" +checksum = "dca9693ef2bab6d4e6707234500350d8dad079eb508dca05530c85dc3a529ff2" dependencies = [ "bumpalo", "proc-macro2", @@ -3404,9 +3398,9 @@ dependencies = [ [[package]] name = "wasm-bindgen-shared" -version = "0.2.114" +version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "75a326b8c223ee17883a4251907455a2431acc2791c98c26279376490c378c16" +checksum = "39129a682a6d2d841b6c429d0c51e5cb0ed1a03829d8b3d1e69a011e62cb3d3b" dependencies = [ "unicode-ident", ] @@ -3447,9 +3441,9 @@ dependencies = [ [[package]] name = "web-sys" -version = "0.3.91" +version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "854ba17bb104abfb26ba36da9729addc7ce7f06f5c0f90f3c391f8461cca21f9" +checksum = "cd70027e39b12f0849461e08ffc50b9cd7688d942c1c8e3c7b22273236b4dd0a" dependencies = [ "js-sys", "wasm-bindgen", @@ -3838,9 +3832,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "x509-parser" @@ -3872,9 +3866,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -3883,9 +3877,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -3895,18 +3889,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efbb2a062be311f2ba113ce66f697a4dc589f85e78a4aea276200804cea0ed87" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.47" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e8bc7269b54418e7aeeef514aa68f8690b8c0489a06b0136e5f57c4c5ccab89" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -3915,18 +3909,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -3942,9 +3936,9 @@ checksum = "b97154e67e32c85465826e8bcc1c59429aaaf107c1e4a9e53c8d8ccd5eff88d0" [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -3953,9 +3947,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -3964,9 +3958,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", From 8f5960de0629d4fa6ff65af870e515448dc66c10 Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Sun, 12 Apr 2026 19:56:47 +0200 Subject: [PATCH 4/6] replace macros with regular functions --- src/metrics/tokio_runtime.rs | 135 +++++++++++++++++++---------------- 1 file changed, 72 insertions(+), 63 deletions(-) diff --git a/src/metrics/tokio_runtime.rs b/src/metrics/tokio_runtime.rs index 144935698f..80c5d964a9 100644 --- a/src/metrics/tokio_runtime.rs +++ b/src/metrics/tokio_runtime.rs @@ -43,91 +43,100 @@ struct LabelSet { worker: usize, } -macro_rules! encode_gauge { - ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ - let metric = ConstGauge::new($self.metrics.$name() as i64); - let metric_encoder = - $encoder.encode_descriptor(stringify!($name), $help, None, metric.metric_type())?; - metric.encode(metric_encoder)?; - }}; +fn encode_gauge( + encoder: &mut DescriptorEncoder, + name: &str, + help: &str, + value: i64, +) -> Result<(), std::fmt::Error> { + let metric = ConstGauge::new(value); + let metric_encoder = encoder.encode_descriptor(name, help, None, metric.metric_type())?; + metric.encode(metric_encoder) } -macro_rules! encode_per_worker_duration_seconds { - ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ - let mut family_encoder = $encoder.encode_descriptor( - concat!(stringify!($name), "_seconds"), - $help, - None, - MetricType::Counter, - )?; - for worker in 0..$self.metrics.num_workers() { - let metric = ConstCounter::new($self.metrics.$name(worker).as_secs_f64()); - let labels = LabelSet { worker }; - let metric_encoder = family_encoder.encode_family(&labels)?; - metric.encode(metric_encoder)?; - } - }}; +fn encode_per_worker_duration_seconds( + encoder: &mut DescriptorEncoder, + name: &str, + help: &str, + num_workers: usize, + value_for_worker: impl Fn(usize) -> std::time::Duration, +) -> Result<(), std::fmt::Error> { + let mut family_encoder = encoder.encode_descriptor(name, help, None, MetricType::Counter)?; + for worker in 0..num_workers { + let metric = ConstCounter::new(value_for_worker(worker).as_secs_f64()); + let labels = LabelSet { worker }; + let metric_encoder = family_encoder.encode_family(&labels)?; + metric.encode(metric_encoder)?; + } + Ok(()) } -macro_rules! encode_per_worker_count { - ($self:expr, $encoder:expr, $name:tt, $help:expr) => {{ - let mut family_encoder = - $encoder.encode_descriptor(stringify!($name), $help, None, MetricType::Counter)?; - for worker in 0..$self.metrics.num_workers() { - let metric = ConstGauge::new($self.metrics.$name(worker) as i64); - let labels = LabelSet { worker }; - let metric_encoder = family_encoder.encode_family(&labels)?; - metric.encode(metric_encoder)?; - } - }}; +fn encode_per_worker_count( + encoder: &mut DescriptorEncoder, + name: &str, + help: &str, + num_workers: usize, + value_for_worker: impl Fn(usize) -> u64, +) -> Result<(), std::fmt::Error> { + let mut family_encoder = encoder.encode_descriptor(name, help, None, MetricType::Counter)?; + for worker in 0..num_workers { + let metric = ConstGauge::new(value_for_worker(worker) as i64); + let labels = LabelSet { worker }; + let metric_encoder = family_encoder.encode_family(&labels)?; + metric.encode(metric_encoder)?; + } + Ok(()) } impl Collector for TokioRuntimeCollector { fn encode(&self, mut encoder: DescriptorEncoder) -> Result<(), std::fmt::Error> { - encode_gauge!( - self, + encode_gauge( &mut encoder, - num_workers, - "the number of worker threads used by the runtime" - ); + "num_workers", + "the number of worker threads used by the runtime", + self.metrics.num_workers() as i64, + )?; - encode_gauge!( - self, + encode_gauge( &mut encoder, - global_queue_depth, - "the number of tasks currently scheduled in the runtime's global queue" - ); + "global_queue_depth", + "the number of tasks currently scheduled in the runtime's global queue", + self.metrics.global_queue_depth() as i64, + )?; - encode_gauge!( - self, + encode_gauge( &mut encoder, - num_alive_tasks, - "the number of alive tasks in the runtime" - ); + "num_alive_tasks", + "the number of alive tasks in the runtime", + self.metrics.num_alive_tasks() as i64, + )?; #[cfg(target_has_atomic = "64")] - encode_per_worker_duration_seconds!( - self, + encode_per_worker_duration_seconds( &mut encoder, - worker_total_busy_duration, - "the amount of time worker threads have been busy" - ); + "worker_total_busy_duration_seconds", + "the amount of time worker threads have been busy", + self.metrics.num_workers(), + |w| self.metrics.worker_total_busy_duration(w), + )?; #[cfg(target_has_atomic = "64")] - encode_per_worker_count!( - self, + encode_per_worker_count( &mut encoder, - worker_park_count, - "the total number of times the given worker thread has parked" - ); + "worker_park_count", + "the total number of times the given worker thread has parked", + self.metrics.num_workers(), + |w| self.metrics.worker_park_count(w), + )?; #[cfg(target_has_atomic = "64")] - encode_per_worker_count!( - self, + encode_per_worker_count( &mut encoder, - worker_park_unpark_count, - "the total number of times the given worker thread has parked and unparked" - ); + "worker_park_unpark_count", + "the total number of times the given worker thread has parked and unparked", + self.metrics.num_workers(), + |w| self.metrics.worker_park_unpark_count(w), + )?; Ok(()) } From 9aa3bedcf62aeaea8fa040504ac7f885e9b12188 Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Mon, 13 Apr 2026 18:31:18 +0200 Subject: [PATCH 5/6] ConstGauge -> ConstCounter --- src/metrics/tokio_runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics/tokio_runtime.rs b/src/metrics/tokio_runtime.rs index 80c5d964a9..8c143d10c7 100644 --- a/src/metrics/tokio_runtime.rs +++ b/src/metrics/tokio_runtime.rs @@ -80,7 +80,7 @@ fn encode_per_worker_count( ) -> Result<(), std::fmt::Error> { let mut family_encoder = encoder.encode_descriptor(name, help, None, MetricType::Counter)?; for worker in 0..num_workers { - let metric = ConstGauge::new(value_for_worker(worker) as i64); + let metric = ConstCounter::new(value_for_worker(worker) as i64); let labels = LabelSet { worker }; let metric_encoder = family_encoder.encode_family(&labels)?; metric.encode(metric_encoder)?; From 5fd6c3fa42570f4f96a5b38380733c0c891e4782 Mon Sep 17 00:00:00 2001 From: Martin Zacho Date: Mon, 13 Apr 2026 18:35:25 +0200 Subject: [PATCH 6/6] fix ConstGauge -> ConstCounter bug --- src/metrics/tokio_runtime.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/metrics/tokio_runtime.rs b/src/metrics/tokio_runtime.rs index 8c143d10c7..833117a9e8 100644 --- a/src/metrics/tokio_runtime.rs +++ b/src/metrics/tokio_runtime.rs @@ -80,7 +80,7 @@ fn encode_per_worker_count( ) -> Result<(), std::fmt::Error> { let mut family_encoder = encoder.encode_descriptor(name, help, None, MetricType::Counter)?; for worker in 0..num_workers { - let metric = ConstCounter::new(value_for_worker(worker) as i64); + let metric = ConstCounter::new(value_for_worker(worker)); let labels = LabelSet { worker }; let metric_encoder = family_encoder.encode_family(&labels)?; metric.encode(metric_encoder)?;