opentelemetry_spanprocessor_any/sdk/export/trace/mod.rs
1//! Trace exporters
2use crate::{
3 sdk,
4 trace::{Event, Link, SpanContext, SpanId, SpanKind, StatusCode, TraceError},
5};
6use async_trait::async_trait;
7#[cfg(feature = "serialize")]
8use serde::{Deserialize, Serialize};
9use std::borrow::Cow;
10use std::fmt::Debug;
11use std::sync::Arc;
12use std::time::SystemTime;
13
14pub mod stdout;
15
16/// Describes the result of an export.
17pub type ExportResult = Result<(), TraceError>;
18
19/// `SpanExporter` defines the interface that protocol-specific exporters must
20/// implement so that they can be plugged into OpenTelemetry SDK and support
21/// sending of telemetry data.
22///
23/// The goal of the interface is to minimize burden of implementation for
24/// protocol-dependent telemetry exporters. The protocol exporter is expected to
25/// be primarily a simple telemetry data encoder and transmitter.
26#[async_trait]
27pub trait SpanExporter: Send + Debug {
28 /// Exports a batch of readable spans. Protocol exporters that will
29 /// implement this function are typically expected to serialize and transmit
30 /// the data to the destination.
31 ///
32 /// This function will never be called concurrently for the same exporter
33 /// instance. It can be called again only after the current call returns.
34 ///
35 /// This function must not block indefinitely, there must be a reasonable
36 /// upper limit after which the call must time out with an error result.
37 ///
38 /// Any retry logic that is required by the exporter is the responsibility
39 /// of the exporter.
40 async fn export(&mut self, batch: Vec<SpanData>) -> ExportResult;
41
42 /// Shuts down the exporter. Called when SDK is shut down. This is an
43 /// opportunity for exporter to do any cleanup required.
44 ///
45 /// This function should be called only once for each `SpanExporter`
46 /// instance. After the call to `shutdown`, subsequent calls to `export` are
47 /// not allowed and should return an error.
48 ///
49 /// This function should not block indefinitely (e.g. if it attempts to
50 /// flush the data and the destination is unavailable). SDK authors
51 /// can decide if they want to make the shutdown timeout
52 /// configurable.
53 fn shutdown(&mut self) {}
54}
55
56/// `SpanData` contains all the information collected by a `Span` and can be used
57/// by exporters as a standard input.
58#[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]
59#[derive(Clone, Debug, PartialEq)]
60pub struct SpanData {
61 /// Exportable `SpanContext`
62 pub span_context: SpanContext,
63 /// Span parent id
64 pub parent_span_id: SpanId,
65 /// Span kind
66 pub span_kind: SpanKind,
67 /// Span name
68 pub name: Cow<'static, str>,
69 /// Span start time
70 pub start_time: SystemTime,
71 /// Span end time
72 pub end_time: SystemTime,
73 /// Span attributes
74 pub attributes: sdk::trace::EvictedHashMap,
75 /// Span events
76 pub events: sdk::trace::EvictedQueue<Event>,
77 /// Span Links
78 pub links: sdk::trace::EvictedQueue<Link>,
79 /// Span status code
80 pub status_code: StatusCode,
81 /// Span status message
82 pub status_message: Cow<'static, str>,
83 /// Resource contains attributes representing an entity that produced this span.
84 pub resource: Option<Arc<sdk::Resource>>,
85 /// Instrumentation library that produced this span
86 #[cfg_attr(feature = "serialize", serde(skip))]
87 pub instrumentation_lib: sdk::InstrumentationLibrary,
88}
89
90#[cfg(feature = "serialize")]
91#[cfg(test)]
92mod tests {
93 use super::*;
94 use crate::trace::{TraceFlags, TraceId, TraceState};
95
96 #[test]
97 fn test_serialise() {
98 let trace_id = 7;
99 let span_id = 99;
100
101 let trace_flags = TraceFlags::default();
102 let remote = false;
103 let span_context = SpanContext::new(
104 TraceId::from_u128(trace_id),
105 SpanId::from_u64(span_id),
106 trace_flags,
107 remote,
108 TraceState::default(),
109 );
110
111 let parent_span_id = 1;
112 let span_kind = SpanKind::Client;
113 let name = "foo/bar baz 人?!".into();
114 let start_time = crate::time::now();
115 let end_time = crate::time::now();
116
117 let capacity = 3;
118 let attributes = sdk::trace::EvictedHashMap::new(capacity, 0);
119 let events = sdk::trace::EvictedQueue::new(capacity);
120 let links = sdk::trace::EvictedQueue::new(capacity);
121
122 let status_code = StatusCode::Ok;
123 let status_message = "".into();
124 let resource = None;
125
126 let span_data = SpanData {
127 span_context,
128 parent_span_id: SpanId::from_u64(parent_span_id),
129 span_kind,
130 name,
131 start_time,
132 end_time,
133 attributes,
134 events,
135 links,
136 status_code,
137 status_message,
138 resource,
139 instrumentation_lib: sdk::InstrumentationLibrary::new("", None),
140 };
141
142 let encoded: Vec<u8> = bincode::serialize(&span_data).unwrap();
143
144 let decoded: SpanData = bincode::deserialize(&encoded[..]).unwrap();
145
146 assert_eq!(span_data, decoded);
147 }
148}