Skip to content

Commit ac6cc5f

Browse files
scottgerringlalitb
andauthored
feat(otlp): add build() on base exporter builders to auto-select from env (#3394)
Co-authored-by: Lalit Kumar Bhasin <lalit_fin@yahoo.com>
1 parent fc2d5a4 commit ac6cc5f

File tree

5 files changed

+108
-3
lines changed

5 files changed

+108
-3
lines changed

opentelemetry-otlp/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## vNext
44

5+
- Add `build()` directly on `SpanExporterBuilder`, `MetricExporterBuilder`, and `LogExporterBuilder`
6+
(before selecting a transport), which auto-selects the transport based on the
7+
`OTEL_EXPORTER_OTLP_PROTOCOL` environment variable or enabled features.
8+
[#3394](https://github.com/open-telemetry/opentelemetry-rust/pull/3394)
59
- **Breaking** Removed `ExportConfig`, `HasExportConfig`, `with_export_config()`, `HasTonicConfig`, `HasHttpConfig`, `TonicConfig`, and `HttpConfig` from public API.
610
Use the public `WithExportConfig`, `WithTonicConfig`, and `WithHttpConfig` trait methods instead, which remain unchanged.
711
- The gRPC/tonic OTLP exporter's build method now returns an error for all signals (traces, metrics, logs) when

opentelemetry-otlp/examples/basic-otlp/src/main.rs

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ fn get_resource() -> Resource {
2626

2727
fn init_traces() -> SdkTracerProvider {
2828
let exporter = SpanExporter::builder()
29-
.with_tonic()
3029
.build()
3130
.expect("Failed to create span exporter");
3231
SdkTracerProvider::builder()
@@ -37,7 +36,6 @@ fn init_traces() -> SdkTracerProvider {
3736

3837
fn init_metrics() -> SdkMeterProvider {
3938
let exporter = MetricExporter::builder()
40-
.with_tonic()
4139
.build()
4240
.expect("Failed to create metric exporter");
4341

@@ -49,7 +47,6 @@ fn init_metrics() -> SdkMeterProvider {
4947

5048
fn init_logs() -> SdkLoggerProvider {
5149
let exporter = LogExporter::builder()
52-
.with_tonic()
5350
.build()
5451
.expect("Failed to create log exporter");
5552

opentelemetry-otlp/src/logs.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,28 @@ impl LogExporterBuilder<NoExporterBuilderSet> {
6161
endpoint: self.endpoint,
6262
}
6363
}
64+
65+
/// Build the [LogExporter] with the default transport selected by environment
66+
/// variable or feature flags.
67+
///
68+
/// The transport is chosen based on:
69+
/// 1. The `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable (if set and the
70+
/// corresponding feature is enabled)
71+
/// 2. Enabled features, with priority: `http-json` > `http-proto` > `grpc-tonic`
72+
///
73+
/// Use [`with_tonic`](Self::with_tonic) or [`with_http`](Self::with_http) to
74+
/// explicitly select a transport and access transport-specific configuration.
75+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
76+
pub fn build(self) -> Result<LogExporter, ExporterBuildError> {
77+
match crate::Protocol::default() {
78+
#[cfg(feature = "grpc-tonic")]
79+
crate::Protocol::Grpc => self.with_tonic().build(),
80+
#[cfg(feature = "http-proto")]
81+
crate::Protocol::HttpBinary => self.with_http().build(),
82+
#[cfg(feature = "http-json")]
83+
crate::Protocol::HttpJson => self.with_http().build(),
84+
}
85+
}
6486
}
6587

6688
#[cfg(feature = "grpc-tonic")]
@@ -172,3 +194,15 @@ impl opentelemetry_sdk::logs::LogExporter for LogExporter {
172194
}
173195
}
174196
}
197+
198+
#[cfg(test)]
199+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
200+
mod tests {
201+
use crate::LogExporter;
202+
203+
#[test]
204+
fn build_with_default_transport() {
205+
let result = LogExporter::builder().build();
206+
assert!(result.is_ok(), "build() should succeed: {:?}", result.err());
207+
}
208+
}

opentelemetry-otlp/src/metric.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,28 @@ impl MetricExporterBuilder<NoExporterBuilderSet> {
5858
pub fn new() -> Self {
5959
MetricExporterBuilder::default()
6060
}
61+
62+
/// Build the [MetricExporter] with the default transport selected by environment
63+
/// variable or feature flags.
64+
///
65+
/// The transport is chosen based on:
66+
/// 1. The `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable (if set and the
67+
/// corresponding feature is enabled)
68+
/// 2. Enabled features, with priority: `http-json` > `http-proto` > `grpc-tonic`
69+
///
70+
/// Use [`with_tonic`](Self::with_tonic) or [`with_http`](Self::with_http) to
71+
/// explicitly select a transport and access transport-specific configuration.
72+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
73+
pub fn build(self) -> Result<MetricExporter, ExporterBuildError> {
74+
match crate::Protocol::default() {
75+
#[cfg(feature = "grpc-tonic")]
76+
crate::Protocol::Grpc => self.with_tonic().build(),
77+
#[cfg(feature = "http-proto")]
78+
crate::Protocol::HttpBinary => self.with_http().build(),
79+
#[cfg(feature = "http-json")]
80+
crate::Protocol::HttpJson => self.with_http().build(),
81+
}
82+
}
6183
}
6284

6385
impl<C> MetricExporterBuilder<C> {
@@ -250,6 +272,20 @@ impl MetricExporter {
250272
}
251273
}
252274

275+
#[cfg(test)]
276+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
277+
mod build_tests {
278+
use crate::MetricExporter;
279+
280+
#[test]
281+
fn build_with_default_transport() {
282+
// Verify that `MetricExporter::builder().build()` succeeds
283+
// when at least one transport feature is enabled.
284+
let result = MetricExporter::builder().build();
285+
assert!(result.is_ok(), "build() should succeed: {:?}", result.err());
286+
}
287+
}
288+
253289
#[cfg(test)]
254290
mod tests {
255291
use super::*;

opentelemetry-otlp/src/span.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,28 @@ impl SpanExporterBuilder<NoExporterBuilderSet> {
6363
client: HttpExporterBuilderSet(HttpExporterBuilder::default()),
6464
}
6565
}
66+
67+
/// Build the [SpanExporter] with the default transport selected by environment
68+
/// variable or feature flags.
69+
///
70+
/// The transport is chosen based on:
71+
/// 1. The `OTEL_EXPORTER_OTLP_PROTOCOL` environment variable (if set and the
72+
/// corresponding feature is enabled)
73+
/// 2. Enabled features, with priority: `http-json` > `http-proto` > `grpc-tonic`
74+
///
75+
/// Use [`with_tonic`](Self::with_tonic) or [`with_http`](Self::with_http) to
76+
/// explicitly select a transport and access transport-specific configuration.
77+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
78+
pub fn build(self) -> Result<SpanExporter, ExporterBuildError> {
79+
match crate::Protocol::default() {
80+
#[cfg(feature = "grpc-tonic")]
81+
crate::Protocol::Grpc => self.with_tonic().build(),
82+
#[cfg(feature = "http-proto")]
83+
crate::Protocol::HttpBinary => self.with_http().build(),
84+
#[cfg(feature = "http-json")]
85+
crate::Protocol::HttpJson => self.with_http().build(),
86+
}
87+
}
6688
}
6789

6890
#[cfg(feature = "grpc-tonic")]
@@ -166,3 +188,15 @@ impl opentelemetry_sdk::trace::SpanExporter for SpanExporter {
166188
}
167189
}
168190
}
191+
192+
#[cfg(test)]
193+
#[cfg(any(feature = "grpc-tonic", feature = "http-proto", feature = "http-json"))]
194+
mod tests {
195+
use crate::SpanExporter;
196+
197+
#[test]
198+
fn build_with_default_transport() {
199+
let result = SpanExporter::builder().build();
200+
assert!(result.is_ok(), "build() should succeed: {:?}", result.err());
201+
}
202+
}

0 commit comments

Comments
 (0)