summaryrefslogtreecommitdiffstats
path: root/tokio/src/runtime/mod.rs
diff options
context:
space:
mode:
authorEliza Weisman <eliza@buoyant.io>2020-11-01 10:48:44 -0800
committerGitHub <noreply@github.com>2020-11-01 10:48:44 -0800
commitfede3db76aef95c010c3e0c3da3b732380285097 (patch)
tree0aa934da682d7f31cf093e69e420ba88601acb6e /tokio/src/runtime/mod.rs
parent2b23aa7389686f341e564c8da565a3b4c8b1188f (diff)
tracing: replace future names with spawn locations in task spans (#3074)
## Motivation Currently, the per-task `tracing` spans generated by tokio's `tracing` feature flag include the `std::any::type_name` of the future that was spawned. When future combinators and/or libraries like Tower are in use, these future names can get _quite_ long. Furthermore, when formatting the `tracing` spans with their parent spans as context, any other task spans in the span context where the future was spawned from can _also_ include extremely long future names. In some cases, this can result in extremely high memory use just to store the future names. For example, in Linkerd, when we enable `tokio=trace` to enable the task spans, there's a spawned task whose future name is _232990 characters long_. A proxy with only 14 spawned tasks generates a task list that's over 690 KB. Enabling task spans under load results in the process getting OOM killed very quickly. ## Solution This branch removes future type names from the spans generated by `spawn`. As a replacement, to allow identifying which `spawn` call a span corresponds to, the task span now contains the source code location where `spawn` was called, when the compiler supports the `#[track_caller]` attribute. Since `track_caller` was stabilized in Rust 1.46.0, and our minimum supported Rust version is 1.45.0, we can't assume that `#[track_caller]` is always available. Instead, we have a RUSTFLAGS cfg, `tokio_track_caller`, that guards whether or not we use it. I've also added a `build.rs` that detects the compiler minor version, and sets the cfg flag automatically if the current compiler version is >= 1.46. This means users shouldn't have to enable `tokio_track_caller` manually. Here's the trace output from the `chat` example, before this change: ![Screenshot_20201030_110157](https://user-images.githubusercontent.com/2796466/97741071-6d408800-1a9f-11eb-9ed6-b25e72f58c7b.png) ...and after: ![Screenshot_20201030_110303](https://user-images.githubusercontent.com/2796466/97741112-7e899480-1a9f-11eb-9197-c5a3f9ea1c05.png) Closes #3073 Signed-off-by: Eliza Weisman <eliza@buoyant.io>
Diffstat (limited to 'tokio/src/runtime/mod.rs')
-rw-r--r--tokio/src/runtime/mod.rs4
1 files changed, 4 insertions, 0 deletions
diff --git a/tokio/src/runtime/mod.rs b/tokio/src/runtime/mod.rs
index 01788b9c..c76f5cf6 100644
--- a/tokio/src/runtime/mod.rs
+++ b/tokio/src/runtime/mod.rs
@@ -357,11 +357,14 @@ cfg_rt! {
/// });
/// # }
/// ```
+ #[cfg_attr(tokio_track_caller, track_caller)]
pub fn spawn<F>(&self, future: F) -> JoinHandle<F::Output>
where
F: Future + Send + 'static,
F::Output: Send + 'static,
{
+ #[cfg(feature = "tracing")]
+ let future = crate::util::trace::task(future, "task");
match &self.kind {
#[cfg(feature = "rt-multi-thread")]
Kind::ThreadPool(exec) => exec.spawn(future),
@@ -385,6 +388,7 @@ cfg_rt! {
/// println!("now running on a worker thread");
/// });
/// # }
+ #[cfg_attr(tokio_track_caller, track_caller)]
pub fn spawn_blocking<F, R>(&self, func: F) -> JoinHandle<R>
where
F: FnOnce() -> R + Send + 'static,