ts_opentelemetry_api/trace/
noop.rs1use crate::{
7 propagation::{text_map_propagator::FieldIter, Extractor, Injector, TextMapPropagator},
8 trace,
9 trace::{TraceContextExt, TraceFlags, TraceState},
10 Context, KeyValue,
11};
12use std::borrow::Cow;
13use std::time::SystemTime;
14
15#[derive(Clone, Debug, Default)]
17pub struct NoopTracerProvider {
18 _private: (),
19}
20
21impl NoopTracerProvider {
22 pub fn new() -> Self {
24 NoopTracerProvider { _private: () }
25 }
26}
27
28impl trace::TracerProvider for NoopTracerProvider {
29 type Tracer = NoopTracer;
30
31 fn versioned_tracer(
33 &self,
34 _name: impl Into<Cow<'static, str>>,
35 _version: Option<impl Into<Cow<'static, str>>>,
36 _schema_url: Option<impl Into<Cow<'static, str>>>,
37 _attributes: Option<Vec<KeyValue>>,
38 ) -> Self::Tracer {
39 NoopTracer::new()
40 }
41}
42
43#[derive(Clone, Debug)]
45pub struct NoopSpan {
46 span_context: trace::SpanContext,
47}
48
49impl Default for NoopSpan {
50 fn default() -> Self {
51 NoopSpan::new()
52 }
53}
54
55impl NoopSpan {
56 pub fn new() -> Self {
58 NoopSpan {
59 span_context: trace::SpanContext::new(
60 trace::TraceId::INVALID,
61 trace::SpanId::INVALID,
62 TraceFlags::default(),
63 false,
64 TraceState::default(),
65 ),
66 }
67 }
68}
69
70impl trace::Span for NoopSpan {
71 fn add_event<T>(&mut self, _name: T, _attributes: Vec<KeyValue>)
73 where
74 T: Into<Cow<'static, str>>,
75 {
76 }
78
79 fn add_event_with_timestamp<T>(
81 &mut self,
82 _name: T,
83 _timestamp: SystemTime,
84 _attributes: Vec<KeyValue>,
85 ) where
86 T: Into<Cow<'static, str>>,
87 {
88 }
90
91 fn span_context(&self) -> &trace::SpanContext {
93 &self.span_context
94 }
95
96 fn is_recording(&self) -> bool {
98 false
99 }
100
101 fn set_attribute(&mut self, _attribute: KeyValue) {
103 }
105
106 fn set_status(&mut self, _status: trace::Status) {
108 }
110
111 fn update_name<T>(&mut self, _new_name: T)
113 where
114 T: Into<Cow<'static, str>>,
115 {
116 }
118
119 fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
121 }
123}
124
125#[derive(Clone, Debug, Default)]
127pub struct NoopTracer {
128 _private: (),
129}
130
131impl NoopTracer {
132 pub fn new() -> Self {
134 NoopTracer { _private: () }
135 }
136}
137
138impl trace::Tracer for NoopTracer {
139 type Span = NoopSpan;
140
141 fn build_with_context(&self, _builder: trace::SpanBuilder, parent_cx: &Context) -> Self::Span {
146 if parent_cx.has_active_span() {
147 NoopSpan {
148 span_context: parent_cx.span().span_context().clone(),
149 }
150 } else {
151 NoopSpan::new()
152 }
153 }
154}
155
156#[derive(Debug, Default)]
160pub struct NoopTextMapPropagator {
161 _private: (),
162}
163
164impl NoopTextMapPropagator {
165 pub fn new() -> Self {
167 NoopTextMapPropagator { _private: () }
168 }
169}
170
171impl TextMapPropagator for NoopTextMapPropagator {
172 fn inject_context(&self, _cx: &Context, _injector: &mut dyn Injector) {
173 }
175
176 fn extract_with_context(&self, _cx: &Context, _extractor: &dyn Extractor) -> Context {
177 Context::current()
178 }
179
180 fn fields(&self) -> FieldIter<'_> {
181 FieldIter::new(&[])
182 }
183}
184
185#[cfg(all(test, feature = "testing", feature = "trace"))]
186mod tests {
187 use super::*;
188 use crate::testing::trace::TestSpan;
189 use crate::trace::{self, Span, Tracer};
190
191 fn valid_span_context() -> trace::SpanContext {
192 trace::SpanContext::new(
193 trace::TraceId::from_u128(42),
194 trace::SpanId::from_u64(42),
195 trace::TraceFlags::default(),
196 true,
197 TraceState::default(),
198 )
199 }
200
201 #[test]
202 fn noop_tracer_defaults_to_invalid_span() {
203 let tracer = NoopTracer::new();
204 let span = tracer.start_with_context("foo", &Context::new());
205 assert!(!span.span_context().is_valid());
206 }
207
208 #[test]
209 fn noop_tracer_propagates_valid_span_context_from_builder() {
210 let tracer = NoopTracer::new();
211 let builder = tracer.span_builder("foo");
212 let span = tracer.build_with_context(
213 builder,
214 &Context::new().with_span(TestSpan(valid_span_context())),
215 );
216 assert!(span.span_context().is_valid());
217 }
218
219 #[test]
220 fn noop_tracer_propagates_valid_span_context_from_explicitly_specified_context() {
221 let tracer = NoopTracer::new();
222 let cx = Context::new().with_span(NoopSpan {
223 span_context: valid_span_context(),
224 });
225 let span = tracer.start_with_context("foo", &cx);
226 assert!(span.span_context().is_valid());
227 }
228
229 #[test]
230 fn noop_tracer_propagates_valid_span_context_from_remote_span_context() {
231 let tracer = NoopTracer::new();
232 let cx = Context::new().with_remote_span_context(valid_span_context());
233 let span = tracer.start_with_context("foo", &cx);
234 assert!(span.span_context().is_valid());
235 }
236}