opentelemetry_otlp/
span.rs

1//! # OTLP - Span Exporter
2//!
3//! Defines a [SpanExporter] to send trace data via the OpenTelemetry Protocol (OTLP)
4
5use std::fmt::Debug;
6
7use futures_core::future::BoxFuture;
8use opentelemetry_sdk::error::OTelSdkResult;
9use opentelemetry_sdk::trace::SpanData;
10
11#[cfg(feature = "grpc-tonic")]
12use crate::{
13    exporter::tonic::{HasTonicConfig, TonicExporterBuilder},
14    TonicExporterBuilderSet,
15};
16
17#[cfg(any(feature = "http-proto", feature = "http-json"))]
18use crate::{
19    exporter::http::{HasHttpConfig, HttpExporterBuilder},
20    HttpExporterBuilderSet,
21};
22
23use crate::{exporter::HasExportConfig, NoExporterBuilderSet};
24
25/// Target to which the exporter is going to send spans, defaults to https://localhost:4317/v1/traces.
26/// Learn about the relationship between this constant and default/metrics/logs at
27/// <https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/protocol/exporter.md#endpoint-urls-for-otlphttp>
28pub const OTEL_EXPORTER_OTLP_TRACES_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT";
29/// Max waiting time for the backend to process each spans batch, defaults to 10s.
30pub const OTEL_EXPORTER_OTLP_TRACES_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_TRACES_TIMEOUT";
31/// Compression algorithm to use, defaults to none.
32pub const OTEL_EXPORTER_OTLP_TRACES_COMPRESSION: &str = "OTEL_EXPORTER_OTLP_TRACES_COMPRESSION";
33/// Key-value pairs to be used as headers associated with gRPC or HTTP requests
34/// for sending spans.
35/// Example: `k1=v1,k2=v2`
36/// Note: this is only supported for HTTP.
37pub const OTEL_EXPORTER_OTLP_TRACES_HEADERS: &str = "OTEL_EXPORTER_OTLP_TRACES_HEADERS";
38
39#[derive(Debug, Default, Clone)]
40pub struct SpanExporterBuilder<C> {
41    client: C,
42}
43
44impl SpanExporterBuilder<NoExporterBuilderSet> {
45    pub fn new() -> Self {
46        SpanExporterBuilder::default()
47    }
48
49    #[cfg(feature = "grpc-tonic")]
50    pub fn with_tonic(self) -> SpanExporterBuilder<TonicExporterBuilderSet> {
51        SpanExporterBuilder {
52            client: TonicExporterBuilderSet(TonicExporterBuilder::default()),
53        }
54    }
55
56    #[cfg(any(feature = "http-proto", feature = "http-json"))]
57    pub fn with_http(self) -> SpanExporterBuilder<HttpExporterBuilderSet> {
58        SpanExporterBuilder {
59            client: HttpExporterBuilderSet(HttpExporterBuilder::default()),
60        }
61    }
62}
63
64#[cfg(feature = "grpc-tonic")]
65impl SpanExporterBuilder<TonicExporterBuilderSet> {
66    pub fn build(self) -> Result<SpanExporter, opentelemetry::trace::TraceError> {
67        let span_exporter = self.client.0.build_span_exporter()?;
68        opentelemetry::otel_debug!(name: "SpanExporterBuilt");
69        Ok(SpanExporter::new(span_exporter))
70    }
71}
72
73#[cfg(any(feature = "http-proto", feature = "http-json"))]
74impl SpanExporterBuilder<HttpExporterBuilderSet> {
75    pub fn build(self) -> Result<SpanExporter, opentelemetry::trace::TraceError> {
76        let span_exporter = self.client.0.build_span_exporter()?;
77        Ok(SpanExporter::new(span_exporter))
78    }
79}
80
81#[cfg(feature = "grpc-tonic")]
82impl HasExportConfig for SpanExporterBuilder<TonicExporterBuilderSet> {
83    fn export_config(&mut self) -> &mut crate::ExportConfig {
84        &mut self.client.0.exporter_config
85    }
86}
87
88#[cfg(any(feature = "http-proto", feature = "http-json"))]
89impl HasExportConfig for SpanExporterBuilder<HttpExporterBuilderSet> {
90    fn export_config(&mut self) -> &mut crate::ExportConfig {
91        &mut self.client.0.exporter_config
92    }
93}
94
95#[cfg(feature = "grpc-tonic")]
96impl HasTonicConfig for SpanExporterBuilder<TonicExporterBuilderSet> {
97    fn tonic_config(&mut self) -> &mut crate::TonicConfig {
98        &mut self.client.0.tonic_config
99    }
100}
101
102#[cfg(any(feature = "http-proto", feature = "http-json"))]
103impl HasHttpConfig for SpanExporterBuilder<HttpExporterBuilderSet> {
104    fn http_client_config(&mut self) -> &mut crate::exporter::http::HttpConfig {
105        &mut self.client.0.http_config
106    }
107}
108
109/// OTLP exporter that sends tracing information
110#[derive(Debug)]
111pub struct SpanExporter(Box<dyn opentelemetry_sdk::trace::SpanExporter>);
112
113impl SpanExporter {
114    /// Obtain a builder to configure a [SpanExporter].
115    pub fn builder() -> SpanExporterBuilder<NoExporterBuilderSet> {
116        SpanExporterBuilder::default()
117    }
118
119    /// Build a new span exporter from a client
120    pub fn new(client: impl opentelemetry_sdk::trace::SpanExporter + 'static) -> Self {
121        SpanExporter(Box::new(client))
122    }
123}
124
125impl opentelemetry_sdk::trace::SpanExporter for SpanExporter {
126    fn export(&mut self, batch: Vec<SpanData>) -> BoxFuture<'static, OTelSdkResult> {
127        self.0.export(batch)
128    }
129
130    fn set_resource(&mut self, resource: &opentelemetry_sdk::Resource) {
131        self.0.set_resource(resource);
132    }
133}