Skip to content

Commit

Permalink
[metrics] Add H2 Histogram option to improve histogram granularity
Browse files Browse the repository at this point in the history
  • Loading branch information
rcoh committed Oct 10, 2024
1 parent 679d765 commit 02c0552
Show file tree
Hide file tree
Showing 10 changed files with 846 additions and 122 deletions.
5 changes: 5 additions & 0 deletions spellcheck.dic
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,15 @@
0xA
0xD
100ms
100ns
10ms
~12
12.5%
±1m
±1ms
1ms
1s
25%
250ms
2x
~4
Expand Down Expand Up @@ -116,9 +119,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::*",
]
64 changes: 61 additions & 3 deletions tokio/src/runtime/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::runtime::TaskMeta;
use crate::runtime::{blocking, driver, Callback, HistogramBuilder, Runtime, TaskCallback};
use crate::util::rand::{RngSeed, RngSeedGenerator};

#[cfg(tokio_unstable)]
use crate::runtime::metrics::HistogramConfiguration;
use std::fmt;
use std::io;
use std::time::Duration;
Expand Down Expand Up @@ -1068,6 +1070,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 @@ -1087,6 +1094,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 @@ -1108,14 +1117,58 @@ 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
/// ```
/// 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();
/// ```
///
/// [`LogHistogram`]: crate::runtime::LogHistogram
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 @@ -1139,19 +1192,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 @@ -1170,14 +1226,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 02c0552

Please sign in to comment.