Skip to content

Commit

Permalink
metrics: add H2 Histogram option to improve histogram granularity (#6897
Browse files Browse the repository at this point in the history
)
  • Loading branch information
rcoh authored Oct 21, 2024
1 parent ce1c74f commit da745ff
Show file tree
Hide file tree
Showing 10 changed files with 869 additions and 127 deletions.
9 changes: 8 additions & 1 deletion spellcheck.dic
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
287
292
&
+
<
Expand All @@ -12,12 +12,17 @@
0xA
0xD
100ms
100ns
10ms
10μs
~12
120s
12.5%
±1m
±1ms
1ms
1s
25%
250ms
2x
~4
Expand Down Expand Up @@ -116,9 +121,11 @@ GID
goroutines
Growable
gzip
H2
hashmaps
HashMaps
hashsets
HdrHistogram
ie
Illumos
impl
Expand Down
14 changes: 7 additions & 7 deletions tokio/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ mio = { version = "1.0.1", optional = true, default-features = false }
parking_lot = { version = "0.12.0", optional = true }

[target.'cfg(not(target_family = "wasm"))'.dependencies]
socket2 = { version = "0.5.5", optional = true, features = [ "all" ] }
socket2 = { version = "0.5.5", optional = true, features = ["all"] }

# Currently unstable. The API exposed by these features may be broken at any time.
# Requires `--cfg tokio_unstable` to enable.
Expand All @@ -123,8 +123,8 @@ optional = true
[target.'cfg(windows)'.dev-dependencies.windows-sys]
version = "0.52"
features = [
"Win32_Foundation",
"Win32_Security_Authorization",
"Win32_Foundation",
"Win32_Security_Authorization",
]

[dev-dependencies]
Expand All @@ -137,6 +137,7 @@ async-stream = "0.3"
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
socket2 = "0.5.5"
tempfile = "3.1.0"
proptest = "1"

[target.'cfg(not(all(target_family = "wasm", target_os = "unknown")))'.dev-dependencies]
rand = "0.8.0"
Expand Down Expand Up @@ -165,8 +166,7 @@ features = ["full", "test-util"]
# The following are types that are allowed to be exposed in Tokio's public API.
# The standard library is allowed by default.
allowed_external_types = [
"bytes::buf::buf_impl::Buf",
"bytes::buf::buf_mut::BufMut",

"tokio_macros::*",
"bytes::buf::buf_impl::Buf",
"bytes::buf::buf_mut::BufMut",
"tokio_macros::*",
]
89 changes: 85 additions & 4 deletions tokio/src/runtime/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::runtime::handle::Handle;
use crate::runtime::{blocking, driver, Callback, HistogramBuilder, Runtime, TaskCallback};
#[cfg(tokio_unstable)]
use crate::runtime::{LocalOptions, LocalRuntime, TaskMeta};
use crate::runtime::{metrics::HistogramConfiguration, LocalOptions, LocalRuntime, TaskMeta};
use crate::util::rand::{RngSeed, RngSeedGenerator};

use crate::runtime::blocking::BlockingPool;
Expand Down Expand Up @@ -1102,6 +1102,11 @@ impl Builder {
/// `metrics_poll_count_histogram_` builder methods to configure the
/// histogram details.
///
/// By default, a linear histogram with 10 buckets each 100 microseconds wide will be used.
/// This has an extremely low memory footprint, but may not provide enough granularity. For
/// better granularity with low memory usage, use [`metrics_poll_count_histogram_configuration()`]
/// to select [`LogHistogram`] instead.
///
/// # Examples
///
/// ```
Expand All @@ -1121,6 +1126,8 @@ impl Builder {
///
/// [`Handle::metrics()`]: crate::runtime::Handle::metrics
/// [`Instant::now()`]: std::time::Instant::now
/// [`LogHistogram`]: crate::runtime::LogHistogram
/// [`metrics_poll_count_histogram_configuration()`]: Builder::metrics_poll_count_histogram_configuration
pub fn enable_metrics_poll_count_histogram(&mut self) -> &mut Self {
self.metrics_poll_count_histogram_enable = true;
self
Expand All @@ -1142,14 +1149,83 @@ impl Builder {
/// ```
/// use tokio::runtime::{self, HistogramScale};
///
/// # #[allow(deprecated)]
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_scale(HistogramScale::Log)
/// .build()
/// .unwrap();
/// ```
#[deprecated(note = "use metrics_poll_count_histogram_configuration")]
pub fn metrics_poll_count_histogram_scale(&mut self, histogram_scale: crate::runtime::HistogramScale) -> &mut Self {
self.metrics_poll_count_histogram.scale = histogram_scale;
self.metrics_poll_count_histogram.legacy_mut(|b|b.scale = histogram_scale);
self
}

/// Configure the histogram for tracking poll times
///
/// By default, a linear histogram with 10 buckets each 100 microseconds wide will be used.
/// This has an extremely low memory footprint, but may not provide enough granularity. For
/// better granularity with low memory usage, use [`LogHistogram`] instead.
///
/// # Examples
/// Configure a [`LogHistogram`] with [default configuration]:
/// ```
/// use tokio::runtime;
/// use tokio::runtime::{HistogramConfiguration, LogHistogram};
///
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_configuration(
/// HistogramConfiguration::log(LogHistogram::default())
/// )
/// .build()
/// .unwrap();
/// ```
///
/// Configure a linear histogram with 100 buckets, each 10μs wide
/// ```
/// use tokio::runtime;
/// use std::time::Duration;
/// use tokio::runtime::HistogramConfiguration;
///
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_configuration(
/// HistogramConfiguration::linear(Duration::from_micros(10), 100)
/// )
/// .build()
/// .unwrap();
/// ```
///
/// Configure a [`LogHistogram`] with the following settings:
/// - Measure times from 100ns to 120s
/// - Max error of 0.1
/// - No more than 1024 buckets
/// ```
/// use std::time::Duration;
/// use tokio::runtime;
/// use tokio::runtime::{HistogramConfiguration, LogHistogram};
///
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_configuration(
/// HistogramConfiguration::log(LogHistogram::builder()
/// .max_value(Duration::from_secs(120))
/// .min_value(Duration::from_nanos(100))
/// .max_error(0.1)
/// .max_buckets(1024)
/// .expect("configuration uses 488 buckets")
/// )
/// )
/// .build()
/// .unwrap();
/// ```
///
/// [`LogHistogram`]: crate::runtime::LogHistogram
/// [default configuration]: crate::runtime::LogHistogramBuilder
pub fn metrics_poll_count_histogram_configuration(&mut self, configuration: HistogramConfiguration) -> &mut Self {
self.metrics_poll_count_histogram.histogram_type = configuration.inner;
self
}

Expand All @@ -1173,19 +1249,22 @@ impl Builder {
/// use tokio::runtime;
/// use std::time::Duration;
///
/// # #[allow(deprecated)]
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_resolution(Duration::from_micros(100))
/// .build()
/// .unwrap();
/// ```
#[deprecated(note = "use metrics_poll_count_histogram_configuration")]
pub fn metrics_poll_count_histogram_resolution(&mut self, resolution: Duration) -> &mut Self {
assert!(resolution > Duration::from_secs(0));
// Sanity check the argument and also make the cast below safe.
assert!(resolution <= Duration::from_secs(1));

let resolution = resolution.as_nanos() as u64;
self.metrics_poll_count_histogram.resolution = resolution;

self.metrics_poll_count_histogram.legacy_mut(|b|b.resolution = resolution);
self
}

Expand All @@ -1204,14 +1283,16 @@ impl Builder {
/// ```
/// use tokio::runtime;
///
/// # #[allow(deprecated)]
/// let rt = runtime::Builder::new_multi_thread()
/// .enable_metrics_poll_count_histogram()
/// .metrics_poll_count_histogram_buckets(15)
/// .build()
/// .unwrap();
/// ```
#[deprecated(note = "use `metrics_poll_count_histogram_configuration")]
pub fn metrics_poll_count_histogram_buckets(&mut self, buckets: usize) -> &mut Self {
self.metrics_poll_count_histogram.num_buckets = buckets;
self.metrics_poll_count_histogram.legacy_mut(|b|b.num_buckets = buckets);
self
}
}
Expand Down
2 changes: 1 addition & 1 deletion tokio/src/runtime/metrics/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,6 @@ cfg_rt_multi_thread! {
}
}

fn duration_as_u64(dur: Duration) -> u64 {
pub(crate) fn duration_as_u64(dur: Duration) -> u64 {
u64::try_from(dur.as_nanos()).unwrap_or(u64::MAX)
}
Loading

0 comments on commit da745ff

Please sign in to comment.