Skip to content

Commit 02c0552

Browse files
committed
[metrics] Add H2 Histogram option to improve histogram granularity
1 parent 679d765 commit 02c0552

File tree

10 files changed

+846
-122
lines changed

10 files changed

+846
-122
lines changed

spellcheck.dic

+5
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,15 @@
1212
0xA
1313
0xD
1414
100ms
15+
100ns
1516
10ms
1617
~12
18+
12.5%
1719
±1m
1820
±1ms
1921
1ms
2022
1s
23+
25%
2124
250ms
2225
2x
2326
~4
@@ -116,9 +119,11 @@ GID
116119
goroutines
117120
Growable
118121
gzip
122+
H2
119123
hashmaps
120124
HashMaps
121125
hashsets
126+
HdrHistogram
122127
ie
123128
Illumos
124129
impl

tokio/Cargo.toml

+7-7
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ mio = { version = "1.0.1", optional = true, default-features = false }
9696
parking_lot = { version = "0.12.0", optional = true }
9797

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

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

130130
[dev-dependencies]
@@ -137,6 +137,7 @@ async-stream = "0.3"
137137
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
138138
socket2 = "0.5.5"
139139
tempfile = "3.1.0"
140+
proptest = "1"
140141

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

tokio/src/runtime/builder.rs

+61-3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use crate::runtime::TaskMeta;
66
use crate::runtime::{blocking, driver, Callback, HistogramBuilder, Runtime, TaskCallback};
77
use crate::util::rand::{RngSeed, RngSeedGenerator};
88

9+
#[cfg(tokio_unstable)]
10+
use crate::runtime::metrics::HistogramConfiguration;
911
use std::fmt;
1012
use std::io;
1113
use std::time::Duration;
@@ -1068,6 +1070,11 @@ impl Builder {
10681070
/// `metrics_poll_count_histogram_` builder methods to configure the
10691071
/// histogram details.
10701072
///
1073+
/// By default, a linear histogram with 10 buckets each 100 microseconds wide will be used.
1074+
/// This has an extremely low memory footprint, but may not provide enough granularity. For
1075+
/// better granularity with low memory usage, use [`metrics_poll_count_histogram_configuration()`]
1076+
/// to select [`LogHistogram`] instead.
1077+
///
10711078
/// # Examples
10721079
///
10731080
/// ```
@@ -1087,6 +1094,8 @@ impl Builder {
10871094
///
10881095
/// [`Handle::metrics()`]: crate::runtime::Handle::metrics
10891096
/// [`Instant::now()`]: std::time::Instant::now
1097+
/// [`LogHistogram`]: crate::runtime::LogHistogram
1098+
/// [`metrics_poll_count_histogram_configuration()`]: Builder::metrics_poll_count_histogram_configuration
10901099
pub fn enable_metrics_poll_count_histogram(&mut self) -> &mut Self {
10911100
self.metrics_poll_count_histogram_enable = true;
10921101
self
@@ -1108,14 +1117,58 @@ impl Builder {
11081117
/// ```
11091118
/// use tokio::runtime::{self, HistogramScale};
11101119
///
1120+
/// # #[allow(deprecated)]
11111121
/// let rt = runtime::Builder::new_multi_thread()
11121122
/// .enable_metrics_poll_count_histogram()
11131123
/// .metrics_poll_count_histogram_scale(HistogramScale::Log)
11141124
/// .build()
11151125
/// .unwrap();
11161126
/// ```
1127+
#[deprecated(note = "use metrics_poll_count_histogram_configuration")]
11171128
pub fn metrics_poll_count_histogram_scale(&mut self, histogram_scale: crate::runtime::HistogramScale) -> &mut Self {
1118-
self.metrics_poll_count_histogram.scale = histogram_scale;
1129+
self.metrics_poll_count_histogram.legacy_mut(|b|b.scale = histogram_scale);
1130+
self
1131+
}
1132+
1133+
/// Configure the histogram for tracking poll times
1134+
///
1135+
/// By default, a linear histogram with 10 buckets each 100 microseconds wide will be used.
1136+
/// This has an extremely low memory footprint, but may not provide enough granularity. For
1137+
/// better granularity with low memory usage, use [`LogHistogram`] instead.
1138+
///
1139+
/// # Examples
1140+
/// Configure a `LogHistogram` with default configuration:
1141+
/// ```
1142+
/// use tokio::runtime;
1143+
/// use tokio::runtime::{HistogramConfiguration, LogHistogram};
1144+
///
1145+
/// let rt = runtime::Builder::new_multi_thread()
1146+
/// .enable_metrics_poll_count_histogram()
1147+
/// .metrics_poll_count_histogram_configuration(
1148+
/// HistogramConfiguration::log(LogHistogram::default())
1149+
/// )
1150+
/// .build()
1151+
/// .unwrap();
1152+
/// ```
1153+
///
1154+
/// Configure a linear histogram
1155+
/// ```
1156+
/// use tokio::runtime;
1157+
/// use std::time::Duration;
1158+
/// use tokio::runtime::HistogramConfiguration;
1159+
///
1160+
/// let rt = runtime::Builder::new_multi_thread()
1161+
/// .enable_metrics_poll_count_histogram()
1162+
/// .metrics_poll_count_histogram_configuration(
1163+
/// HistogramConfiguration::linear(Duration::from_micros(10), 100)
1164+
/// )
1165+
/// .build()
1166+
/// .unwrap();
1167+
/// ```
1168+
///
1169+
/// [`LogHistogram`]: crate::runtime::LogHistogram
1170+
pub fn metrics_poll_count_histogram_configuration(&mut self, configuration: HistogramConfiguration) -> &mut Self {
1171+
self.metrics_poll_count_histogram.histogram_type = configuration.inner;
11191172
self
11201173
}
11211174

@@ -1139,19 +1192,22 @@ impl Builder {
11391192
/// use tokio::runtime;
11401193
/// use std::time::Duration;
11411194
///
1195+
/// # #[allow(deprecated)]
11421196
/// let rt = runtime::Builder::new_multi_thread()
11431197
/// .enable_metrics_poll_count_histogram()
11441198
/// .metrics_poll_count_histogram_resolution(Duration::from_micros(100))
11451199
/// .build()
11461200
/// .unwrap();
11471201
/// ```
1202+
#[deprecated(note = "use metrics_poll_count_histogram_configuration")]
11481203
pub fn metrics_poll_count_histogram_resolution(&mut self, resolution: Duration) -> &mut Self {
11491204
assert!(resolution > Duration::from_secs(0));
11501205
// Sanity check the argument and also make the cast below safe.
11511206
assert!(resolution <= Duration::from_secs(1));
11521207

11531208
let resolution = resolution.as_nanos() as u64;
1154-
self.metrics_poll_count_histogram.resolution = resolution;
1209+
1210+
self.metrics_poll_count_histogram.legacy_mut(|b|b.resolution = resolution);
11551211
self
11561212
}
11571213

@@ -1170,14 +1226,16 @@ impl Builder {
11701226
/// ```
11711227
/// use tokio::runtime;
11721228
///
1229+
/// # #[allow(deprecated)]
11731230
/// let rt = runtime::Builder::new_multi_thread()
11741231
/// .enable_metrics_poll_count_histogram()
11751232
/// .metrics_poll_count_histogram_buckets(15)
11761233
/// .build()
11771234
/// .unwrap();
11781235
/// ```
1236+
#[deprecated(note = "use `metrics_poll_count_histogram_configuration")]
11791237
pub fn metrics_poll_count_histogram_buckets(&mut self, buckets: usize) -> &mut Self {
1180-
self.metrics_poll_count_histogram.num_buckets = buckets;
1238+
self.metrics_poll_count_histogram.legacy_mut(|b|b.num_buckets = buckets);
11811239
self
11821240
}
11831241
}

tokio/src/runtime/metrics/batch.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,6 @@ cfg_rt_multi_thread! {
171171
}
172172
}
173173

174-
fn duration_as_u64(dur: Duration) -> u64 {
174+
pub(crate) fn duration_as_u64(dur: Duration) -> u64 {
175175
u64::try_from(dur.as_nanos()).unwrap_or(u64::MAX)
176176
}

0 commit comments

Comments
 (0)