opentelemetry/trace/
noop.rs
1use crate::{
7 propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator},
8 trace::{self, TraceContextExt as _},
9 Context, InstrumentationLibrary, KeyValue,
10};
11use std::{borrow::Cow, sync::Arc, time::SystemTime};
12
13#[derive(Clone, Debug, Default)]
15pub struct NoopTracerProvider {
16 _private: (),
17}
18
19impl NoopTracerProvider {
20 pub fn new() -> Self {
22 NoopTracerProvider { _private: () }
23 }
24}
25
26impl trace::TracerProvider for NoopTracerProvider {
27 type Tracer = NoopTracer;
28
29 fn library_tracer(&self, _library: Arc<InstrumentationLibrary>) -> Self::Tracer {
31 NoopTracer::new()
32 }
33}
34
35#[derive(Clone, Debug)]
37pub struct NoopSpan {
38 span_context: trace::SpanContext,
39}
40
41impl NoopSpan {
42 pub const DEFAULT: NoopSpan = NoopSpan {
44 span_context: trace::SpanContext::NONE,
45 };
46}
47
48impl trace::Span for NoopSpan {
49 fn add_event<T>(&mut self, _name: T, _attributes: Vec<KeyValue>)
51 where
52 T: Into<Cow<'static, str>>,
53 {
54 }
56
57 fn add_event_with_timestamp<T>(
59 &mut self,
60 _name: T,
61 _timestamp: SystemTime,
62 _attributes: Vec<KeyValue>,
63 ) where
64 T: Into<Cow<'static, str>>,
65 {
66 }
68
69 fn span_context(&self) -> &trace::SpanContext {
71 &self.span_context
72 }
73
74 fn is_recording(&self) -> bool {
76 false
77 }
78
79 fn set_attribute(&mut self, _attribute: KeyValue) {
81 }
83
84 fn set_status(&mut self, _status: trace::Status) {
86 }
88
89 fn update_name<T>(&mut self, _new_name: T)
91 where
92 T: Into<Cow<'static, str>>,
93 {
94 }
96
97 fn add_link(&mut self, _span_context: trace::SpanContext, _attributes: Vec<KeyValue>) {
98 }
100
101 fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
103 }
105}
106
107#[derive(Clone, Debug, Default)]
109pub struct NoopTracer {
110 _private: (),
111}
112
113impl NoopTracer {
114 pub fn new() -> Self {
116 NoopTracer { _private: () }
117 }
118}
119
120impl trace::Tracer for NoopTracer {
121 type Span = NoopSpan;
122
123 fn build_with_context(&self, _builder: trace::SpanBuilder, parent_cx: &Context) -> Self::Span {
128 NoopSpan {
129 span_context: parent_cx.span().span_context().clone(),
130 }
131 }
132}
133
134#[derive(Debug, Default)]
138pub struct NoopTextMapPropagator {
139 _private: (),
140}
141
142impl NoopTextMapPropagator {
143 pub fn new() -> Self {
145 NoopTextMapPropagator { _private: () }
146 }
147}
148
149impl TextMapPropagator for NoopTextMapPropagator {
150 fn inject_context(&self, _cx: &Context, _injector: &mut dyn Injector) {
151 }
153
154 fn extract_with_context(&self, _cx: &Context, _extractor: &dyn Extractor) -> Context {
155 Context::current()
156 }
157
158 fn fields(&self) -> FieldIter<'_> {
159 FieldIter::new(&[])
160 }
161}
162
163#[cfg(all(test, feature = "testing", feature = "trace"))]
164mod tests {
165 use super::*;
166 use crate::testing::trace::TestSpan;
167 use crate::trace::{Span, TraceState, Tracer};
168
169 fn valid_span_context() -> trace::SpanContext {
170 trace::SpanContext::new(
171 trace::TraceId::from_u128(42),
172 trace::SpanId::from_u64(42),
173 trace::TraceFlags::default(),
174 true,
175 TraceState::default(),
176 )
177 }
178
179 #[test]
180 fn noop_tracer_defaults_to_invalid_span() {
181 let tracer = NoopTracer::new();
182 let span = tracer.start_with_context("foo", &Context::new());
183 assert!(!span.span_context().is_valid());
184 }
185
186 #[test]
187 fn noop_tracer_propagates_valid_span_context_from_builder() {
188 let tracer = NoopTracer::new();
189 let builder = tracer.span_builder("foo");
190 let span = tracer.build_with_context(
191 builder,
192 &Context::new().with_span(TestSpan(valid_span_context())),
193 );
194 assert!(span.span_context().is_valid());
195 }
196
197 #[test]
198 fn noop_tracer_propagates_valid_span_context_from_explicitly_specified_context() {
199 let tracer = NoopTracer::new();
200 let cx = Context::new().with_span(NoopSpan {
201 span_context: valid_span_context(),
202 });
203 let span = tracer.start_with_context("foo", &cx);
204 assert!(span.span_context().is_valid());
205 }
206
207 #[test]
208 fn noop_tracer_propagates_valid_span_context_from_remote_span_context() {
209 let tracer = NoopTracer::new();
210 let cx = Context::new().with_remote_span_context(valid_span_context());
211 let span = tracer.start_with_context("foo", &cx);
212 assert!(span.span_context().is_valid());
213 }
214}