• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #![allow(dead_code)]
2 use criterion::{black_box, measurement::WallTime, Bencher};
3 use tracing::{field, span, Event, Id, Metadata};
4 
5 use std::{
6     fmt::{self, Write},
7     sync::{Mutex, MutexGuard},
8 };
9 
for_all_recording( group: &mut criterion::BenchmarkGroup<'_, WallTime>, mut iter: impl FnMut(&mut Bencher<'_, WallTime>), )10 pub fn for_all_recording(
11     group: &mut criterion::BenchmarkGroup<'_, WallTime>,
12     mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
13 ) {
14     // first, run benchmarks with no subscriber
15     group.bench_function("none", &mut iter);
16 
17     // then, run benchmarks with a scoped default subscriber
18     tracing::subscriber::with_default(EnabledSubscriber, || {
19         group.bench_function("scoped", &mut iter)
20     });
21 
22     let subscriber = VisitingSubscriber(Mutex::new(String::from("")));
23     tracing::subscriber::with_default(subscriber, || {
24         group.bench_function("scoped_recording", &mut iter);
25     });
26 
27     // finally, set a global default subscriber, and run the benchmarks again.
28     tracing::subscriber::set_global_default(EnabledSubscriber)
29         .expect("global default should not have already been set!");
30     let _ = log::set_logger(&NOP_LOGGER);
31     log::set_max_level(log::LevelFilter::Trace);
32     group.bench_function("global", &mut iter);
33 }
34 
for_all_dispatches( group: &mut criterion::BenchmarkGroup<'_, WallTime>, mut iter: impl FnMut(&mut Bencher<'_, WallTime>), )35 pub fn for_all_dispatches(
36     group: &mut criterion::BenchmarkGroup<'_, WallTime>,
37     mut iter: impl FnMut(&mut Bencher<'_, WallTime>),
38 ) {
39     // first, run benchmarks with no subscriber
40     group.bench_function("none", &mut iter);
41 
42     // then, run benchmarks with a scoped default subscriber
43     tracing::subscriber::with_default(EnabledSubscriber, || {
44         group.bench_function("scoped", &mut iter)
45     });
46 
47     // finally, set a global default subscriber, and run the benchmarks again.
48     tracing::subscriber::set_global_default(EnabledSubscriber)
49         .expect("global default should not have already been set!");
50     let _ = log::set_logger(&NOP_LOGGER);
51     log::set_max_level(log::LevelFilter::Trace);
52     group.bench_function("global", &mut iter);
53 }
54 
55 const NOP_LOGGER: NopLogger = NopLogger;
56 
57 struct NopLogger;
58 
59 impl log::Log for NopLogger {
enabled(&self, _metadata: &log::Metadata) -> bool60     fn enabled(&self, _metadata: &log::Metadata) -> bool {
61         true
62     }
63 
log(&self, record: &log::Record)64     fn log(&self, record: &log::Record) {
65         if self.enabled(record.metadata()) {
66             let mut this = self;
67             let _ = write!(this, "{}", record.args());
68         }
69     }
70 
flush(&self)71     fn flush(&self) {}
72 }
73 
74 impl Write for &NopLogger {
write_str(&mut self, s: &str) -> std::fmt::Result75     fn write_str(&mut self, s: &str) -> std::fmt::Result {
76         black_box(s);
77         Ok(())
78     }
79 }
80 
81 /// Simulates a subscriber that records span data.
82 struct VisitingSubscriber(Mutex<String>);
83 
84 struct Visitor<'a>(MutexGuard<'a, String>);
85 
86 impl<'a> field::Visit for Visitor<'a> {
record_debug(&mut self, _field: &field::Field, value: &dyn fmt::Debug)87     fn record_debug(&mut self, _field: &field::Field, value: &dyn fmt::Debug) {
88         let _ = write!(&mut *self.0, "{:?}", value);
89     }
90 }
91 
92 impl tracing::Subscriber for VisitingSubscriber {
new_span(&self, span: &span::Attributes<'_>) -> Id93     fn new_span(&self, span: &span::Attributes<'_>) -> Id {
94         let mut visitor = Visitor(self.0.lock().unwrap());
95         span.record(&mut visitor);
96         Id::from_u64(0xDEAD_FACE)
97     }
98 
record(&self, _span: &Id, values: &span::Record<'_>)99     fn record(&self, _span: &Id, values: &span::Record<'_>) {
100         let mut visitor = Visitor(self.0.lock().unwrap());
101         values.record(&mut visitor);
102     }
103 
event(&self, event: &Event<'_>)104     fn event(&self, event: &Event<'_>) {
105         let mut visitor = Visitor(self.0.lock().unwrap());
106         event.record(&mut visitor);
107     }
108 
record_follows_from(&self, span: &Id, follows: &Id)109     fn record_follows_from(&self, span: &Id, follows: &Id) {
110         let _ = (span, follows);
111     }
112 
enabled(&self, metadata: &Metadata<'_>) -> bool113     fn enabled(&self, metadata: &Metadata<'_>) -> bool {
114         let _ = metadata;
115         true
116     }
117 
enter(&self, span: &Id)118     fn enter(&self, span: &Id) {
119         let _ = span;
120     }
121 
exit(&self, span: &Id)122     fn exit(&self, span: &Id) {
123         let _ = span;
124     }
125 }
126 
127 /// A subscriber that is enabled but otherwise does nothing.
128 struct EnabledSubscriber;
129 
130 impl tracing::Subscriber for EnabledSubscriber {
new_span(&self, span: &span::Attributes<'_>) -> Id131     fn new_span(&self, span: &span::Attributes<'_>) -> Id {
132         let _ = span;
133         Id::from_u64(0xDEAD_FACE)
134     }
135 
event(&self, event: &Event<'_>)136     fn event(&self, event: &Event<'_>) {
137         let _ = event;
138     }
139 
record(&self, span: &Id, values: &span::Record<'_>)140     fn record(&self, span: &Id, values: &span::Record<'_>) {
141         let _ = (span, values);
142     }
143 
record_follows_from(&self, span: &Id, follows: &Id)144     fn record_follows_from(&self, span: &Id, follows: &Id) {
145         let _ = (span, follows);
146     }
147 
enabled(&self, metadata: &Metadata<'_>) -> bool148     fn enabled(&self, metadata: &Metadata<'_>) -> bool {
149         let _ = metadata;
150         true
151     }
152 
enter(&self, span: &Id)153     fn enter(&self, span: &Id) {
154         let _ = span;
155     }
156 
exit(&self, span: &Id)157     fn exit(&self, span: &Id) {
158         let _ = span;
159     }
160 }
161