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}