Skip to content

Commit 9801db6

Browse files
authored
Merge branch 'main' into fix-clear-baggage
2 parents 8fa1f7b + cab5565 commit 9801db6

File tree

11 files changed

+178
-30
lines changed

11 files changed

+178
-30
lines changed

docs/release_0.30.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Release Notes 0.30
2+
3+
OpenTelemetry Rust 0.30 introduces a few breaking changes to the
4+
`opentelemetry_sdk` crate in the `metrics` feature. These changes were essential
5+
to drive the Metrics SDK towards stability. With this release, the Metrics SDK
6+
is officially declared stable. The Metrics API was declared stable last year,
7+
and previously, the Logs API, SDK, and OTel-Appender-Tracing were also marked
8+
stable. Importantly, no breaking changes have been introduced to components
9+
already marked as stable.
10+
11+
It is worth noting that the `opentelemetry-otlp` crate remains in a
12+
Release-Candidate state and is not yet considered stable. With the API and SDK
13+
for Logs and Metrics now stable, the focus will shift towards further refining
14+
and stabilizing the OTLP Exporters in upcoming releases. Additionally,
15+
Distributed Tracing is expected to progress towards stability, addressing key
16+
interoperability challenges.
17+
18+
For detailed changelogs of individual crates, please refer to their respective
19+
changelog files. This document serves as a summary of the main changes.
20+
21+
## Key Changes
22+
23+
### Metrics SDK Improvements
24+
25+
1. **Stabilized "view" features**: Previously under an experimental feature
26+
flag, views can now be used to modify the name, unit, description, and
27+
cardinality limit of a metric. Advanced view capabilities, such as changing
28+
aggregation or dropping attributes, remain under the experimental feature
29+
flag.
30+
31+
2. **Cardinality capping**: Introduced the ability to cap cardinality and
32+
configure limits using views.
33+
34+
3. **Polished public API**: Refined the public API to hide implementation
35+
details from exporters, enabling future internal optimizations and ensuring
36+
consistency. Some APIs related to authoring custom metric readers have been
37+
moved behind experimental feature flags. These advanced use cases require
38+
more time to finalize the API surface before being included in the stable
39+
release.
40+
41+
### Context-Based Suppression
42+
43+
Added the ability to suppress telemetry based on Context. This feature prevents
44+
telemetry-induced-telemetry scenarios and addresses a long-standing issue. Note
45+
that suppression relies on proper context propagation. Certain libraries used in
46+
OTLP Exporters utilize `tracing` but do not adopt OpenTelemetry's context
47+
propagation. As a result, not all telemetry is automatically suppressed with
48+
this feature. Improvements in this area are expected in future releases.
49+
50+
## Next Release
51+
52+
In the [next
53+
release](https://github.com/open-telemetry/opentelemetry-rust/milestone/22), the
54+
focus will shift to OTLP Exporters and Distributed Tracing, specifically
55+
resolving
56+
[interoperability](https://github.com/open-telemetry/opentelemetry-rust/issues/2420)
57+
issues with `tokio-tracing` and other fixes required to drive Distributed
58+
Tracing towards stability.
59+
60+
## Acknowledgments
61+
62+
Thank you to everyone who contributed to this milestone. We welcome your
63+
feedback through GitHub issues or discussions in the OTel-Rust Slack channel
64+
[here](https://cloud-native.slack.com/archives/C03GDP0H023).
65+
66+
We are also excited to announce that [Anton Grübel](https://github.com/gruebel)
67+
and [Björn Antonsson](https://github.com/bantonsson) have joined the OTel Rust
68+
project as Approvers.

opentelemetry-otlp/src/exporter/http/logs.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,20 +30,24 @@ impl LogExporter for OtlpHttpClient {
3030
}
3131

3232
let request_uri = request.uri().to_string();
33-
otel_debug!(name: "HttpLogsClient.CallingExport");
33+
otel_debug!(name: "HttpLogsClient.ExportStarted");
3434
let response = client
3535
.send_bytes(request)
3636
.await
3737
.map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
38+
3839
if !response.status().is_success() {
3940
let error = format!(
4041
"OpenTelemetry logs export failed. Url: {}, Status Code: {}, Response: {:?}",
4142
request_uri,
4243
response.status().as_u16(),
4344
response.body()
4445
);
46+
otel_debug!(name: "HttpLogsClient.ExportFailed", error = &error);
4547
return Err(OTelSdkError::InternalFailure(error));
4648
}
49+
50+
otel_debug!(name: "HttpLogsClient.ExportSucceeded");
4751
Ok(())
4852
}
4953

opentelemetry-otlp/src/exporter/http/metrics.rs

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,30 @@ impl MetricsClient for OtlpHttpClient {
3333
request.headers_mut().insert(k.clone(), v.clone());
3434
}
3535

36-
otel_debug!(name: "HttpMetricsClient.CallingExport");
37-
client
38-
.send_bytes(request)
39-
.await
40-
.map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
36+
otel_debug!(name: "HttpMetricsClient.ExportStarted");
37+
let result = client.send_bytes(request).await;
4138

42-
Ok(())
39+
match result {
40+
Ok(response) => {
41+
if response.status().is_success() {
42+
otel_debug!(name: "HttpMetricsClient.ExportSucceeded");
43+
Ok(())
44+
} else {
45+
let error = format!(
46+
"OpenTelemetry metrics export failed. Status Code: {}, Response: {:?}",
47+
response.status().as_u16(),
48+
response.body()
49+
);
50+
otel_debug!(name: "HttpMetricsClient.ExportFailed", error = &error);
51+
Err(OTelSdkError::InternalFailure(error))
52+
}
53+
}
54+
Err(e) => {
55+
let error = format!("{e:?}");
56+
otel_debug!(name: "HttpMetricsClient.ExportFailed", error = &error);
57+
Err(OTelSdkError::InternalFailure(error))
58+
}
59+
}
4360
}
4461

4562
fn shutdown(&self) -> OTelSdkResult {

opentelemetry-otlp/src/exporter/http/mod.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ fn resolve_http_endpoint(
365365
provided_endpoint: Option<&str>,
366366
) -> Result<Uri, ExporterBuildError> {
367367
// programmatic configuration overrides any value set via environment variables
368-
if let Some(provider_endpoint) = provided_endpoint {
368+
if let Some(provider_endpoint) = provided_endpoint.filter(|s| !s.is_empty()) {
369369
provider_endpoint
370370
.parse()
371371
.map_err(|er: http::uri::InvalidUri| {
@@ -528,6 +528,15 @@ mod tests {
528528
);
529529
}
530530

531+
#[test]
532+
fn test_use_default_when_empty_string_for_option() {
533+
run_env_test(vec![], || {
534+
let endpoint =
535+
super::resolve_http_endpoint("non_existent_var", "/v1/traces", Some("")).unwrap();
536+
assert_eq!(endpoint, "http://localhost:4318/v1/traces");
537+
});
538+
}
539+
531540
#[test]
532541
fn test_use_default_when_others_missing() {
533542
run_env_test(vec![], || {

opentelemetry-otlp/src/exporter/http/trace.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ impl SpanExporter for OtlpHttpClient {
4242
}
4343

4444
let request_uri = request.uri().to_string();
45-
otel_debug!(name: "HttpTracesClient.CallingExport");
45+
otel_debug!(name: "HttpTracesClient.ExportStarted");
4646
let response = client
4747
.send_bytes(request)
4848
.await
@@ -51,13 +51,15 @@ impl SpanExporter for OtlpHttpClient {
5151
if !response.status().is_success() {
5252
let error = format!(
5353
"OpenTelemetry trace export failed. Url: {}, Status Code: {}, Response: {:?}",
54-
response.status().as_u16(),
5554
request_uri,
55+
response.status().as_u16(),
5656
response.body()
5757
);
58+
otel_debug!(name: "HttpTracesClient.ExportFailed", error = &error);
5859
return Err(OTelSdkError::InternalFailure(error));
5960
}
6061

62+
otel_debug!(name: "HttpTracesClient.ExportSucceeded");
6163
Ok(())
6264
}
6365

opentelemetry-otlp/src/exporter/tonic/logs.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,27 @@ impl LogExporter for TonicLogsClient {
7272

7373
let resource_logs = group_logs_by_resource_and_scope(batch, &self.resource);
7474

75-
otel_debug!(name: "TonicsLogsClient.CallingExport");
75+
otel_debug!(name: "TonicLogsClient.ExportStarted");
7676

77-
client
77+
let result = client
7878
.export(Request::from_parts(
7979
metadata,
8080
extensions,
8181
ExportLogsServiceRequest { resource_logs },
8282
))
83-
.await
84-
.map_err(|e| OTelSdkError::InternalFailure(format!("export error: {:?}", e)))?;
85-
Ok(())
83+
.await;
84+
85+
match result {
86+
Ok(_) => {
87+
otel_debug!(name: "TonicLogsClient.ExportSucceeded");
88+
Ok(())
89+
}
90+
Err(e) => {
91+
let error = format!("export error: {:?}", e);
92+
otel_debug!(name: "TonicLogsClient.ExportFailed", error = &error);
93+
Err(OTelSdkError::InternalFailure(error))
94+
}
95+
}
8696
}
8797

8898
fn shutdown_with_timeout(&self, _timeout: time::Duration) -> OTelSdkResult {

opentelemetry-otlp/src/exporter/tonic/metrics.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,18 +75,27 @@ impl MetricsClient for TonicMetricsClient {
7575
)),
7676
})?;
7777

78-
otel_debug!(name: "TonicsMetricsClient.CallingExport");
78+
otel_debug!(name: "TonicMetricsClient.ExportStarted");
7979

80-
client
80+
let result = client
8181
.export(Request::from_parts(
8282
metadata,
8383
extensions,
8484
ExportMetricsServiceRequest::from(metrics),
8585
))
86-
.await
87-
.map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
86+
.await;
8887

89-
Ok(())
88+
match result {
89+
Ok(_) => {
90+
otel_debug!(name: "TonicMetricsClient.ExportSucceeded");
91+
Ok(())
92+
}
93+
Err(e) => {
94+
let error = format!("{e:?}");
95+
otel_debug!(name: "TonicMetricsClient.ExportFailed", error = &error);
96+
Err(OTelSdkError::InternalFailure(error))
97+
}
98+
}
9099
}
91100

92101
fn shutdown(&self) -> OTelSdkResult {

opentelemetry-otlp/src/exporter/tonic/mod.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ impl TonicExporterBuilder {
225225
// If users for some reason want to use a custom path, they can use env var or builder to pass it
226226
//
227227
// programmatic configuration overrides any value set via environment variables
228-
if let Some(endpoint) = provided_endpoint {
228+
if let Some(endpoint) = provided_endpoint.filter(|s| !s.is_empty()) {
229229
endpoint
230230
} else if let Ok(endpoint) = env::var(default_endpoint_var) {
231231
endpoint
@@ -666,4 +666,15 @@ mod tests {
666666
assert_eq!(url, "http://localhost:4317");
667667
});
668668
}
669+
670+
#[test]
671+
fn test_use_default_when_empty_string_for_option() {
672+
run_env_test(vec![], || {
673+
let url = TonicExporterBuilder::resolve_endpoint(
674+
OTEL_EXPORTER_OTLP_TRACES_ENDPOINT,
675+
Some(String::new()),
676+
);
677+
assert_eq!(url, "http://localhost:4317");
678+
});
679+
}
669680
}

opentelemetry-otlp/src/exporter/tonic/trace.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -76,17 +76,27 @@ impl SpanExporter for TonicTracesClient {
7676

7777
let resource_spans = group_spans_by_resource_and_scope(batch, &self.resource);
7878

79-
otel_debug!(name: "TonicsTracesClient.CallingExport");
79+
otel_debug!(name: "TonicTracesClient.ExportStarted");
8080

81-
client
81+
let result = client
8282
.export(Request::from_parts(
8383
metadata,
8484
extensions,
8585
ExportTraceServiceRequest { resource_spans },
8686
))
87-
.await
88-
.map_err(|e| OTelSdkError::InternalFailure(e.to_string()))?;
89-
Ok(())
87+
.await;
88+
89+
match result {
90+
Ok(_) => {
91+
otel_debug!(name: "TonicTracesClient.ExportSucceeded");
92+
Ok(())
93+
}
94+
Err(e) => {
95+
let error = e.to_string();
96+
otel_debug!(name: "TonicTracesClient.ExportFailed", error = &error);
97+
Err(OTelSdkError::InternalFailure(error))
98+
}
99+
}
90100
}
91101

92102
fn shutdown(&mut self) -> OTelSdkResult {

opentelemetry-sdk/CHANGELOG.md

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

33
## vNext
44

5+
- TODO: Placeholder for Span processor related things
6+
- *Fix* SpanProcessor::on_start is no longer called on non recording spans
7+
58
## 0.30.0
69

710
Released 2025-May-23

0 commit comments

Comments
 (0)