opentelemetry_spanprocessor_any/trace/
noop.rs1use crate::trace::TraceResult;
7use crate::{
8 sdk::export::trace::{ExportResult, SpanData, SpanExporter},
9 trace,
10 trace::{SpanBuilder, TraceContextExt, TraceFlags, TraceState},
11 Context, KeyValue,
12};
13use async_trait::async_trait;
14use std::borrow::Cow;
15use std::time::SystemTime;
16
17#[derive(Clone, Debug, Default)]
19pub struct NoopTracerProvider {
20 _private: (),
21}
22
23impl NoopTracerProvider {
24 pub fn new() -> Self {
26 NoopTracerProvider { _private: () }
27 }
28}
29
30impl trace::TracerProvider for NoopTracerProvider {
31 type Tracer = NoopTracer;
32
33 fn versioned_tracer(
35 &self,
36 _name: impl Into<Cow<'static, str>>,
37 _version: Option<&'static str>,
38 _schema_url: Option<&'static str>,
39 ) -> Self::Tracer {
40 NoopTracer::new()
41 }
42
43 fn force_flush(&self) -> Vec<TraceResult<()>> {
45 Vec::new()
46 }
47}
48
49#[derive(Clone, Debug)]
51pub struct NoopSpan {
52 span_context: trace::SpanContext,
53}
54
55impl Default for NoopSpan {
56 fn default() -> Self {
57 NoopSpan::new()
58 }
59}
60
61impl NoopSpan {
62 pub fn new() -> Self {
64 NoopSpan {
65 span_context: trace::SpanContext::new(
66 trace::TraceId::INVALID,
67 trace::SpanId::INVALID,
68 TraceFlags::default(),
69 false,
70 TraceState::default(),
71 ),
72 }
73 }
74}
75
76impl trace::Span for NoopSpan {
77 fn add_event<T>(&mut self, _name: T, _attributes: Vec<KeyValue>)
79 where
80 T: Into<Cow<'static, str>>,
81 {
82 }
84
85 fn add_event_with_timestamp<T>(
87 &mut self,
88 _name: T,
89 _timestamp: SystemTime,
90 _attributes: Vec<KeyValue>,
91 ) where
92 T: Into<Cow<'static, str>>,
93 {
94 }
96
97 fn span_context(&self) -> &trace::SpanContext {
99 &self.span_context
100 }
101
102 fn is_recording(&self) -> bool {
104 false
105 }
106
107 fn set_attribute(&mut self, _attribute: KeyValue) {
109 }
111
112 fn set_status(&mut self, _code: trace::StatusCode, _message: String) {
114 }
116
117 fn update_name<T>(&mut self, _new_name: T)
119 where
120 T: Into<Cow<'static, str>>,
121 {
122 }
124
125 fn end_with_timestamp(&mut self, _timestamp: SystemTime) {
127 }
129}
130
131#[derive(Clone, Debug, Default)]
133pub struct NoopTracer {
134 _private: (),
135}
136
137impl NoopTracer {
138 pub fn new() -> Self {
140 NoopTracer { _private: () }
141 }
142}
143
144impl trace::Tracer for NoopTracer {
145 type Span = NoopSpan;
146
147 fn start_with_context<T>(&self, name: T, parent_cx: &Context) -> Self::Span
151 where
152 T: Into<std::borrow::Cow<'static, str>>,
153 {
154 self.build_with_context(SpanBuilder::from_name(name), parent_cx)
155 }
156
157 fn span_builder<T>(&self, name: T) -> trace::SpanBuilder
159 where
160 T: Into<std::borrow::Cow<'static, str>>,
161 {
162 trace::SpanBuilder::from_name(name)
163 }
164
165 fn build_with_context(&self, _builder: trace::SpanBuilder, parent_cx: &Context) -> Self::Span {
170 if parent_cx.has_active_span() {
171 NoopSpan {
172 span_context: parent_cx.span().span_context().clone(),
173 }
174 } else {
175 NoopSpan::new()
176 }
177 }
178}
179
180#[derive(Debug, Default)]
184pub struct NoopSpanExporter {
185 _private: (),
186}
187
188impl NoopSpanExporter {
189 pub fn new() -> Self {
191 NoopSpanExporter { _private: () }
192 }
193}
194
195#[async_trait]
196impl SpanExporter for NoopSpanExporter {
197 async fn export(&mut self, _batch: Vec<SpanData>) -> ExportResult {
198 Ok(())
199 }
200}
201
202#[cfg(all(test, feature = "testing", feature = "trace"))]
203mod tests {
204 use super::*;
205 use crate::testing::trace::TestSpan;
206 use crate::trace::{self, Span, Tracer};
207
208 fn valid_span_context() -> trace::SpanContext {
209 trace::SpanContext::new(
210 trace::TraceId::from_u128(42),
211 trace::SpanId::from_u64(42),
212 trace::TraceFlags::default(),
213 true,
214 TraceState::default(),
215 )
216 }
217
218 #[test]
219 fn noop_tracer_defaults_to_invalid_span() {
220 let tracer = NoopTracer::new();
221 let span = tracer.start_with_context("foo", &Context::new());
222 assert!(!span.span_context().is_valid());
223 }
224
225 #[test]
226 fn noop_tracer_propagates_valid_span_context_from_builder() {
227 let tracer = NoopTracer::new();
228 let builder = tracer.span_builder("foo");
229 let span = tracer.build_with_context(
230 builder,
231 &Context::new().with_span(TestSpan(valid_span_context())),
232 );
233 assert!(span.span_context().is_valid());
234 }
235
236 #[test]
237 fn noop_tracer_propagates_valid_span_context_from_explicitly_specified_context() {
238 let tracer = NoopTracer::new();
239 let cx = Context::new().with_span(NoopSpan {
240 span_context: valid_span_context(),
241 });
242 let span = tracer.start_with_context("foo", &cx);
243 assert!(span.span_context().is_valid());
244 }
245
246 #[test]
247 fn noop_tracer_propagates_valid_span_context_from_remote_span_context() {
248 let tracer = NoopTracer::new();
249 let cx = Context::new().with_remote_span_context(valid_span_context());
250 let span = tracer.start_with_context("foo", &cx);
251 assert!(span.span_context().is_valid());
252 }
253}