From 973bc0bf1d715b65242618cc7cceff2b68eb9436 Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 29 Apr 2025 18:43:48 -0700 Subject: [PATCH 1/3] fix: Pass immutable metrics to PushMetricExporter --- opentelemetry-otlp/src/exporter/http/metrics.rs | 2 +- opentelemetry-otlp/src/exporter/http/mod.rs | 4 ++-- opentelemetry-otlp/src/exporter/tonic/metrics.rs | 4 ++-- opentelemetry-otlp/src/metric.rs | 4 ++-- opentelemetry-sdk/CHANGELOG.md | 3 +++ opentelemetry-sdk/Cargo.toml | 2 +- opentelemetry-sdk/src/metrics/exporter.rs | 2 +- opentelemetry-sdk/src/metrics/in_memory_exporter.rs | 2 +- opentelemetry-sdk/src/metrics/periodic_reader.rs | 6 +++--- .../src/metrics/periodic_reader_with_async_runtime.rs | 2 +- opentelemetry-stdout/src/metrics/exporter.rs | 2 +- 11 files changed, 18 insertions(+), 15 deletions(-) diff --git a/opentelemetry-otlp/src/exporter/http/metrics.rs b/opentelemetry-otlp/src/exporter/http/metrics.rs index 15033686cc..b7b7f0363a 100644 --- a/opentelemetry-otlp/src/exporter/http/metrics.rs +++ b/opentelemetry-otlp/src/exporter/http/metrics.rs @@ -9,7 +9,7 @@ use opentelemetry_sdk::metrics::data::ResourceMetrics; use super::OtlpHttpClient; impl MetricsClient for OtlpHttpClient { - async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult { let client = self .client .lock() diff --git a/opentelemetry-otlp/src/exporter/http/mod.rs b/opentelemetry-otlp/src/exporter/http/mod.rs index ead431acfa..72defd081e 100644 --- a/opentelemetry-otlp/src/exporter/http/mod.rs +++ b/opentelemetry-otlp/src/exporter/http/mod.rs @@ -326,11 +326,11 @@ impl OtlpHttpClient { #[cfg(feature = "metrics")] fn build_metrics_export_body( &self, - metrics: &mut ResourceMetrics, + metrics: &ResourceMetrics, ) -> Option<(Vec, &'static str)> { use opentelemetry_proto::tonic::collector::metrics::v1::ExportMetricsServiceRequest; - let req: ExportMetricsServiceRequest = (&*metrics).into(); + let req: ExportMetricsServiceRequest = metrics.into(); match self.protocol { #[cfg(feature = "http-json")] diff --git a/opentelemetry-otlp/src/exporter/tonic/metrics.rs b/opentelemetry-otlp/src/exporter/tonic/metrics.rs index 2e5eb9df41..1d760bac76 100644 --- a/opentelemetry-otlp/src/exporter/tonic/metrics.rs +++ b/opentelemetry-otlp/src/exporter/tonic/metrics.rs @@ -52,7 +52,7 @@ impl TonicMetricsClient { } impl MetricsClient for TonicMetricsClient { - async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult { let (mut client, metadata, extensions) = self .inner .lock() @@ -81,7 +81,7 @@ impl MetricsClient for TonicMetricsClient { .export(Request::from_parts( metadata, extensions, - ExportMetricsServiceRequest::from(&*metrics), + ExportMetricsServiceRequest::from(metrics), )) .await .map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?; diff --git a/opentelemetry-otlp/src/metric.rs b/opentelemetry-otlp/src/metric.rs index bdb383b47b..9cfb6d3788 100644 --- a/opentelemetry-otlp/src/metric.rs +++ b/opentelemetry-otlp/src/metric.rs @@ -123,7 +123,7 @@ impl HasHttpConfig for MetricExporterBuilder { pub(crate) trait MetricsClient: fmt::Debug + Send + Sync + 'static { fn export( &self, - metrics: &mut ResourceMetrics, + metrics: &ResourceMetrics, ) -> impl std::future::Future + Send; fn shutdown(&self) -> OTelSdkResult; } @@ -149,7 +149,7 @@ impl Debug for MetricExporter { } impl PushMetricExporter for MetricExporter { - async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult { match &self.client { #[cfg(feature = "grpc-tonic")] SupportedTransportClient::Tonic(client) => client.export(metrics).await, diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 128cbc8c8f..cafa532fac 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -43,6 +43,9 @@ also modified to suppress telemetry before invoking exporters. - *Breaking* `Aggregation` enum moved behind feature flag "spec_unstable_metrics_views". This was only required when using Views. [#2928](https://github.com/open-telemetry/opentelemetry-rust/pull/2928) +- *Breaking* change, affecting custom `PushMetricExporter` authors: + - The `export` method on `PushMetricExporter` receives a `&ResourceMetrics` + instead of `&mut ResourceMetrics`. ## 0.29.0 diff --git a/opentelemetry-sdk/Cargo.toml b/opentelemetry-sdk/Cargo.toml index 171296e3ef..c42501a12d 100644 --- a/opentelemetry-sdk/Cargo.toml +++ b/opentelemetry-sdk/Cargo.toml @@ -40,7 +40,7 @@ temp-env = { workspace = true } pprof = { version = "0.14", features = ["flamegraph", "criterion"] } [features] -default = ["trace", "metrics", "logs", "internal-logs"] +default = ["trace", "metrics", "logs", "internal-logs", "experimental_metrics_periodicreader_with_async_runtime"] trace = ["opentelemetry/trace", "rand", "percent-encoding"] jaeger_remote_sampler = ["trace", "opentelemetry-http", "http", "serde", "serde_json", "url", "experimental_async_runtime"] logs = ["opentelemetry/logs", "serde_json"] diff --git a/opentelemetry-sdk/src/metrics/exporter.rs b/opentelemetry-sdk/src/metrics/exporter.rs index f8775a3836..c1280db7be 100644 --- a/opentelemetry-sdk/src/metrics/exporter.rs +++ b/opentelemetry-sdk/src/metrics/exporter.rs @@ -18,7 +18,7 @@ pub trait PushMetricExporter: Send + Sync + 'static { /// considered unrecoverable and will be logged. fn export( &self, - metrics: &mut ResourceMetrics, + metrics: &ResourceMetrics, ) -> impl std::future::Future + Send; /// Flushes any metric data held by an exporter. diff --git a/opentelemetry-sdk/src/metrics/in_memory_exporter.rs b/opentelemetry-sdk/src/metrics/in_memory_exporter.rs index 4d65b81d2f..903c2a46ec 100644 --- a/opentelemetry-sdk/src/metrics/in_memory_exporter.rs +++ b/opentelemetry-sdk/src/metrics/in_memory_exporter.rs @@ -237,7 +237,7 @@ impl InMemoryMetricExporter { } impl PushMetricExporter for InMemoryMetricExporter { - async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult { self.metrics .lock() .map(|mut metrics_guard| { diff --git a/opentelemetry-sdk/src/metrics/periodic_reader.rs b/opentelemetry-sdk/src/metrics/periodic_reader.rs index 518a0cc3be..28b391278e 100644 --- a/opentelemetry-sdk/src/metrics/periodic_reader.rs +++ b/opentelemetry-sdk/src/metrics/periodic_reader.rs @@ -411,7 +411,7 @@ impl PeriodicReaderInner { // Relying on futures executor to execute async call. // TODO: Pass timeout to exporter - futures_executor::block_on(self.exporter.export(&mut rm)) + futures_executor::block_on(self.exporter.export(&rm)) } fn force_flush(&self) -> OTelSdkResult { @@ -553,7 +553,7 @@ mod tests { } impl PushMetricExporter for MetricExporterThatFailsOnlyOnFirst { - async fn export(&self, _metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, _metrics: &ResourceMetrics) -> OTelSdkResult { if self.count.fetch_add(1, Ordering::Relaxed) == 0 { Err(OTelSdkError::InternalFailure("export failed".into())) } else { @@ -584,7 +584,7 @@ mod tests { } impl PushMetricExporter for MockMetricExporter { - async fn export(&self, _metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, _metrics: &ResourceMetrics) -> OTelSdkResult { Ok(()) } diff --git a/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs b/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs index 03e0230157..066db5b340 100644 --- a/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs +++ b/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs @@ -259,7 +259,7 @@ impl PeriodicReaderWorker { message = "Calling exporter's export method with collected metrics.", count = self.rm.scope_metrics.len(), ); - let export = self.reader.exporter.export(&mut self.rm); + let export = self.reader.exporter.export(&self.rm); let timeout = self.runtime.delay(self.timeout); pin_mut!(export); pin_mut!(timeout); diff --git a/opentelemetry-stdout/src/metrics/exporter.rs b/opentelemetry-stdout/src/metrics/exporter.rs index 2d94507e38..fabf28628b 100644 --- a/opentelemetry-stdout/src/metrics/exporter.rs +++ b/opentelemetry-stdout/src/metrics/exporter.rs @@ -42,7 +42,7 @@ impl fmt::Debug for MetricExporter { impl PushMetricExporter for MetricExporter { /// Write Metrics to stdout - async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult { + async fn export(&self, metrics: &ResourceMetrics) -> OTelSdkResult { if self.is_shutdown.load(atomic::Ordering::SeqCst) { Err(opentelemetry_sdk::error::OTelSdkError::AlreadyShutdown) } else { From c0e0a733c90c27e3c2d288ed0ac5630c5e60eb1f Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Tue, 29 Apr 2025 18:45:33 -0700 Subject: [PATCH 2/3] renert --- opentelemetry-sdk/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/Cargo.toml b/opentelemetry-sdk/Cargo.toml index c42501a12d..171296e3ef 100644 --- a/opentelemetry-sdk/Cargo.toml +++ b/opentelemetry-sdk/Cargo.toml @@ -40,7 +40,7 @@ temp-env = { workspace = true } pprof = { version = "0.14", features = ["flamegraph", "criterion"] } [features] -default = ["trace", "metrics", "logs", "internal-logs", "experimental_metrics_periodicreader_with_async_runtime"] +default = ["trace", "metrics", "logs", "internal-logs"] trace = ["opentelemetry/trace", "rand", "percent-encoding"] jaeger_remote_sampler = ["trace", "opentelemetry-http", "http", "serde", "serde_json", "url", "experimental_async_runtime"] logs = ["opentelemetry/logs", "serde_json"] From ad83b13e5673f09a861b6a3ca604ea2b9fd7049f Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Wed, 30 Apr 2025 09:45:37 -0700 Subject: [PATCH 3/3] clog --- opentelemetry-sdk/CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index cafa532fac..a61eab177b 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -44,7 +44,7 @@ also modified to suppress telemetry before invoking exporters. "spec_unstable_metrics_views". This was only required when using Views. [#2928](https://github.com/open-telemetry/opentelemetry-rust/pull/2928) - *Breaking* change, affecting custom `PushMetricExporter` authors: - - The `export` method on `PushMetricExporter` receives a `&ResourceMetrics` + - The `export` method on `PushMetricExporter` now accepts `&ResourceMetrics` instead of `&mut ResourceMetrics`. ## 0.29.0