opentelemetry_sdk/testing/trace/
span_exporters.rs1use crate::error::{OTelSdkError, OTelSdkResult};
2use crate::{
3 trace::{SpanData, SpanExporter},
4 trace::{SpanEvents, SpanLinks},
5 ExportError,
6};
7pub use opentelemetry::testing::trace::TestSpan;
8use opentelemetry::{
9 trace::{SpanContext, SpanId, SpanKind, Status, TraceFlags, TraceId, TraceState},
10 InstrumentationScope,
11};
12use std::fmt::{Display, Formatter};
13
14pub fn new_test_export_span_data() -> SpanData {
15 SpanData {
16 span_context: SpanContext::new(
17 TraceId::from_u128(1),
18 SpanId::from_u64(1),
19 TraceFlags::SAMPLED,
20 false,
21 TraceState::default(),
22 ),
23 parent_span_id: SpanId::INVALID,
24 span_kind: SpanKind::Internal,
25 name: "opentelemetry".into(),
26 start_time: opentelemetry::time::now(),
27 end_time: opentelemetry::time::now(),
28 attributes: Vec::new(),
29 dropped_attributes_count: 0,
30 events: SpanEvents::default(),
31 links: SpanLinks::default(),
32 status: Status::Unset,
33 instrumentation_scope: InstrumentationScope::default(),
34 }
35}
36
37#[derive(Debug)]
38pub struct TokioSpanExporter {
39 tx_export: tokio::sync::mpsc::UnboundedSender<SpanData>,
40 tx_shutdown: tokio::sync::mpsc::UnboundedSender<()>,
41}
42
43impl SpanExporter for TokioSpanExporter {
44 async fn export(&self, batch: Vec<SpanData>) -> OTelSdkResult {
45 batch.into_iter().try_for_each(|span_data| {
46 self.tx_export
47 .send(span_data)
48 .map_err(|err| OTelSdkError::InternalFailure(format!("Export failed: {:?}", err)))
49 })
50 }
51
52 fn shutdown(&mut self) -> OTelSdkResult {
53 self.tx_shutdown.send(()).map_err(|_| {
54 OTelSdkError::InternalFailure("Failed to send shutdown signal".to_string())
55 })
56 }
57}
58
59pub fn new_tokio_test_exporter() -> (
60 TokioSpanExporter,
61 tokio::sync::mpsc::UnboundedReceiver<SpanData>,
62 tokio::sync::mpsc::UnboundedReceiver<()>,
63) {
64 let (tx_export, rx_export) = tokio::sync::mpsc::unbounded_channel();
65 let (tx_shutdown, rx_shutdown) = tokio::sync::mpsc::unbounded_channel();
66 let exporter = TokioSpanExporter {
67 tx_export,
68 tx_shutdown,
69 };
70 (exporter, rx_export, rx_shutdown)
71}
72
73#[derive(Debug)]
74pub struct TestExportError(String);
75
76impl std::error::Error for TestExportError {}
77
78impl ExportError for TestExportError {
79 fn exporter_name(&self) -> &'static str {
80 "test"
81 }
82}
83
84impl Display for TestExportError {
85 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
86 write!(f, "{}", self.0)
87 }
88}
89
90#[cfg(any(feature = "rt-tokio", feature = "rt-tokio-current-thread"))]
91impl<T> From<tokio::sync::mpsc::error::SendError<T>> for TestExportError {
92 fn from(err: tokio::sync::mpsc::error::SendError<T>) -> Self {
93 TestExportError(err.to_string())
94 }
95}
96
97#[derive(Debug, Default)]
101pub struct NoopSpanExporter {
102 _private: (),
103}
104
105impl NoopSpanExporter {
106 pub fn new() -> Self {
108 NoopSpanExporter { _private: () }
109 }
110}
111
112impl SpanExporter for NoopSpanExporter {
113 async fn export(&self, _: Vec<SpanData>) -> OTelSdkResult {
114 Ok(())
115 }
116}