Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 22 additions & 0 deletions opentelemetry-otlp/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,28 @@

- Add partial success response handling for OTLP exporters (traces, metrics, logs) per OTLP spec. Exporters now log warnings when the server returns partial success responses with rejected items and error messages. [#865](https://github.com/open-telemetry/opentelemetry-rust/issues/865)
- Refactor `internal-logs` feature in `opentelemetry-otlp` to reduce unnecessary dependencies[3191](https://github.com/open-telemetry/opentelemetry-rust/pull/3192)
- **Breaking** Make invalid protocol/transport combinations unrepresentable [#3082](https://github.com/open-telemetry/opentelemetry-rust/issues/3082)
- Removed `protocol` field from `ExportConfig` and `with_protocol()` method from `WithExportConfig` trait
- Added new HTTP-specific `Protocol` enum with `HttpProtobuf` and `HttpJson` variants
- Added `with_protocol()` method to `WithHttpConfig` trait that accepts the HTTP-specific `Protocol` enum
- The `Protocol` enum is now only available and only needed when using HTTP transport
- This change makes invalid protocol/transport combinations (like using HTTP protocol with gRPC transport) impossible to express
- Migration example:
```rust
// Before:
SpanExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary) // old Protocol from ExportConfig
.build()

// After:
use opentelemetry_otlp::Protocol;

SpanExporter::builder()
.with_http()
.with_protocol(Protocol::HttpProtobuf) // HTTP-specific Protocol enum
.build()
```

## 0.31.0

Expand Down
10 changes: 5 additions & 5 deletions opentelemetry-otlp/examples/basic-otlp-http/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use opentelemetry::{
InstrumentationScope, KeyValue,
};
use opentelemetry_appender_tracing::layer::OpenTelemetryTracingBridge;
use opentelemetry_otlp::WithExportConfig;
use opentelemetry_otlp::{LogExporter, MetricExporter, Protocol, SpanExporter};
use opentelemetry_otlp::{LogExporter, MetricExporter, SpanExporter};
use opentelemetry_otlp::{Protocol, WithHttpConfig};
use opentelemetry_sdk::Resource;
use opentelemetry_sdk::{
logs::SdkLoggerProvider, metrics::SdkMeterProvider, trace::SdkTracerProvider,
Expand All @@ -29,7 +29,7 @@ fn get_resource() -> Resource {
fn init_logs() -> SdkLoggerProvider {
let exporter = LogExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary)
.with_protocol(Protocol::HttpProtobuf)
.build()
.expect("Failed to create log exporter");

Expand All @@ -42,7 +42,7 @@ fn init_logs() -> SdkLoggerProvider {
fn init_traces() -> SdkTracerProvider {
let exporter = SpanExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary) //can be changed to `Protocol::HttpJson` to export in JSON format
.with_protocol(Protocol::HttpProtobuf)
.build()
.expect("Failed to create trace exporter");

Expand All @@ -55,7 +55,7 @@ fn init_traces() -> SdkTracerProvider {
fn init_metrics() -> SdkMeterProvider {
let exporter = MetricExporter::builder()
.with_http()
.with_protocol(Protocol::HttpBinary) //can be changed to `Protocol::HttpJson` to export in JSON format
.with_protocol(Protocol::HttpProtobuf)
.build()
.expect("Failed to create metric exporter");

Expand Down
17 changes: 12 additions & 5 deletions opentelemetry-otlp/src/exporter/http/logs.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
use super::OtlpHttpClient;
use crate::Protocol;
use super::{OtlpHttpClient, Protocol};
use opentelemetry::{otel_debug, otel_warn};
use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
use opentelemetry_sdk::logs::{LogBatch, LogExporter};
Expand Down Expand Up @@ -51,7 +50,15 @@ fn handle_partial_success(response_body: &[u8], protocol: Protocol) {
return;
}
},
_ => match Message::decode(response_body) {
Protocol::HttpProtobuf => match Message::decode(response_body) {
Ok(r) => r,
Err(e) => {
otel_debug!(name: "HttpLogsClient.ResponseParseError", error = e.to_string());
return;
}
},
#[cfg(not(feature = "http-json"))]
Protocol::HttpJson => match Message::decode(response_body) {
Ok(r) => r,
Err(e) => {
otel_debug!(name: "HttpLogsClient.ResponseParseError", error = e.to_string());
Expand Down Expand Up @@ -81,15 +88,15 @@ mod tests {
let invalid = vec![0xFF, 0xFF, 0xFF, 0xFF];

// Should not panic - logs debug and returns early
handle_partial_success(&invalid, Protocol::HttpBinary);
handle_partial_success(&invalid, Protocol::HttpProtobuf);
}

#[test]
fn test_handle_empty_response() {
let empty = vec![];

// Should not panic
handle_partial_success(&empty, Protocol::HttpBinary);
handle_partial_success(&empty, Protocol::HttpProtobuf);
}

#[cfg(feature = "http-json")]
Expand Down
17 changes: 12 additions & 5 deletions opentelemetry-otlp/src/exporter/http/metrics.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
use crate::metric::MetricsClient;
use crate::Protocol;
use opentelemetry::{otel_debug, otel_warn};
use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
use opentelemetry_sdk::metrics::data::ResourceMetrics;
use prost::Message;

use super::OtlpHttpClient;
use super::{OtlpHttpClient, Protocol};

impl MetricsClient for OtlpHttpClient {
async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult {
Expand Down Expand Up @@ -47,7 +46,15 @@ fn handle_partial_success(response_body: &[u8], protocol: Protocol) {
return;
}
},
_ => match Message::decode(response_body) {
Protocol::HttpProtobuf => match Message::decode(response_body) {
Ok(r) => r,
Err(e) => {
otel_debug!(name: "HttpMetricsClient.ResponseParseError", error = e.to_string());
return;
}
},
#[cfg(not(feature = "http-json"))]
Protocol::HttpJson => match Message::decode(response_body) {
Ok(r) => r,
Err(e) => {
otel_debug!(name: "HttpMetricsClient.ResponseParseError", error = e.to_string());
Expand Down Expand Up @@ -77,15 +84,15 @@ mod tests {
let invalid = vec![0xFF, 0xFF, 0xFF, 0xFF];

// Should not panic - logs debug and returns early
handle_partial_success(&invalid, Protocol::HttpBinary);
handle_partial_success(&invalid, Protocol::HttpProtobuf);
}

#[test]
fn test_handle_empty_response() {
let empty = vec![];

// Should not panic
handle_partial_success(&empty, Protocol::HttpBinary);
handle_partial_success(&empty, Protocol::HttpProtobuf);
}

#[cfg(feature = "http-json")]
Expand Down
Loading