mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-27 00:00:12 +02:00
* trace-core: Pass dispatcher by ref to `dispatcher::with_default` As requested by @carllerche in https://github.com/tokio-rs/tokio/pull/966#discussion_r264380005, this branch changes the `dispatcher::with_default` function in `tokio-trace-core` to take the dispatcher by ref and perform the clone internally. This makes this function more consistant with other `with_default` functions in other crates. Signed-off-by: Eliza Weisman <[email protected]> * trace: Don't set the default dispatcher on entering a span Setting the default dispatcher on span entry is a relic of when spans tracked their parent's ID. At that time, it was necessary to ensure that any spans created inside a span were observed by the same subscriber that originally provided the entered span with an ID, as otherwise, new spans would be created with parent IDs that did not originate from that subscriber. Now that spans don't track their parent ID, this is no longer necessary. However, removing this behavior does mean that if a span is entered outside of the subscriber context it was created in, any subsequent spans will be observed by the current default subscriber and thus will not be part of the original span's trace tree. Since subscribers are not expected to change frequently, and spans are not expected to move between them, this is likely acceptable. I've removed the tests for the old behavior. Note that this change improves the performance of span entry/exit fairly significantly. Here are the results of running a benchmark that enters a span, does nothing, and immediately exits it, before this change: ``` test enter_span ... bench: 93 ns/iter (+/- 14) ``` ...and after: ``` test enter_span ... bench: 51 ns/iter (+/- 9) ``` Signed-off-by: Eliza Weisman <[email protected]>
153 lines
3.5 KiB
Rust
153 lines
3.5 KiB
Rust
#![feature(test)]
|
|
|
|
#[macro_use]
|
|
extern crate tokio_trace;
|
|
extern crate test;
|
|
use test::Bencher;
|
|
|
|
use std::{
|
|
fmt,
|
|
sync::{Mutex, MutexGuard},
|
|
};
|
|
use tokio_trace::{field, span, Event, Id, Metadata};
|
|
|
|
/// A subscriber that is enabled but otherwise does nothing.
|
|
struct EnabledSubscriber;
|
|
|
|
impl tokio_trace::Subscriber for EnabledSubscriber {
|
|
fn new_span(&self, span: &span::Attributes) -> Id {
|
|
let _ = span;
|
|
Id::from_u64(0)
|
|
}
|
|
|
|
fn event(&self, event: &Event) {
|
|
let _ = event;
|
|
}
|
|
|
|
fn record(&self, span: &Id, values: &span::Record) {
|
|
let _ = (span, values);
|
|
}
|
|
|
|
fn record_follows_from(&self, span: &Id, follows: &Id) {
|
|
let _ = (span, follows);
|
|
}
|
|
|
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
let _ = metadata;
|
|
true
|
|
}
|
|
|
|
fn enter(&self, span: &Id) {
|
|
let _ = span;
|
|
}
|
|
|
|
fn exit(&self, span: &Id) {
|
|
let _ = span;
|
|
}
|
|
}
|
|
|
|
/// Simulates a subscriber that records span data.
|
|
struct VisitingSubscriber(Mutex<String>);
|
|
|
|
struct Visitor<'a>(MutexGuard<'a, String>);
|
|
|
|
impl<'a> field::Visit for Visitor<'a> {
|
|
fn record_debug(&mut self, _field: &field::Field, value: &fmt::Debug) {
|
|
use std::fmt::Write;
|
|
let _ = write!(&mut *self.0, "{:?}", value);
|
|
}
|
|
}
|
|
|
|
impl tokio_trace::Subscriber for VisitingSubscriber {
|
|
fn new_span(&self, span: &span::Attributes) -> Id {
|
|
let mut visitor = Visitor(self.0.lock().unwrap());
|
|
span.record(&mut visitor);
|
|
Id::from_u64(0)
|
|
}
|
|
|
|
fn record(&self, _span: &Id, values: &span::Record) {
|
|
let mut visitor = Visitor(self.0.lock().unwrap());
|
|
values.record(&mut visitor);
|
|
}
|
|
|
|
fn event(&self, event: &Event) {
|
|
let mut visitor = Visitor(self.0.lock().unwrap());
|
|
event.record(&mut visitor);
|
|
}
|
|
|
|
fn record_follows_from(&self, span: &Id, follows: &Id) {
|
|
let _ = (span, follows);
|
|
}
|
|
|
|
fn enabled(&self, metadata: &Metadata) -> bool {
|
|
let _ = metadata;
|
|
true
|
|
}
|
|
|
|
fn enter(&self, span: &Id) {
|
|
let _ = span;
|
|
}
|
|
|
|
fn exit(&self, span: &Id) {
|
|
let _ = span;
|
|
}
|
|
}
|
|
|
|
const N_SPANS: usize = 100;
|
|
|
|
#[bench]
|
|
fn span_no_fields(b: &mut Bencher) {
|
|
tokio_trace::subscriber::with_default(EnabledSubscriber, || b.iter(|| span!("span")));
|
|
}
|
|
|
|
#[bench]
|
|
fn enter_span(b: &mut Bencher) {
|
|
tokio_trace::subscriber::with_default(EnabledSubscriber, || {
|
|
b.iter(|| test::black_box(span!("span").enter(|| {})))
|
|
});
|
|
}
|
|
|
|
#[bench]
|
|
fn span_repeatedly(b: &mut Bencher) {
|
|
#[inline]
|
|
fn mk_span(i: u64) -> tokio_trace::Span<'static> {
|
|
span!("span", i = i)
|
|
}
|
|
|
|
let n = test::black_box(N_SPANS);
|
|
tokio_trace::subscriber::with_default(EnabledSubscriber, || {
|
|
b.iter(|| (0..n).fold(mk_span(0), |_, i| mk_span(i as u64)))
|
|
});
|
|
}
|
|
|
|
#[bench]
|
|
fn span_with_fields(b: &mut Bencher) {
|
|
tokio_trace::subscriber::with_default(EnabledSubscriber, || {
|
|
b.iter(|| {
|
|
span!(
|
|
"span",
|
|
foo = "foo",
|
|
bar = "bar",
|
|
baz = 3,
|
|
quuux = tokio_trace::field::debug(0.99)
|
|
)
|
|
})
|
|
});
|
|
}
|
|
|
|
#[bench]
|
|
fn span_with_fields_record(b: &mut Bencher) {
|
|
let subscriber = VisitingSubscriber(Mutex::new(String::from("")));
|
|
tokio_trace::subscriber::with_default(subscriber, || {
|
|
b.iter(|| {
|
|
span!(
|
|
"span",
|
|
foo = "foo",
|
|
bar = "bar",
|
|
baz = 3,
|
|
quuux = tokio_trace::field::debug(0.99)
|
|
)
|
|
})
|
|
});
|
|
}
|