From 3d6e2589e0f95107c801b4bd1104c579c3b116bf Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 15 May 2025 21:37:18 -0700 Subject: [PATCH 1/2] fix: MetricExporters use getter methods instead of direct access --- opentelemetry-proto/src/transform/metrics.rs | 16 +++---- opentelemetry-sdk/CHANGELOG.md | 6 +++ opentelemetry-sdk/src/metrics/data/mod.rs | 44 +++++++++++++++++--- opentelemetry-stdout/src/metrics/exporter.rs | 22 +++++----- 4 files changed, 63 insertions(+), 25 deletions(-) diff --git a/opentelemetry-proto/src/transform/metrics.rs b/opentelemetry-proto/src/transform/metrics.rs index 20f96720f7..e7cdf3ec42 100644 --- a/opentelemetry-proto/src/transform/metrics.rs +++ b/opentelemetry-proto/src/transform/metrics.rs @@ -114,9 +114,9 @@ pub mod tonic { fn from(rm: &ResourceMetrics) -> Self { ExportMetricsServiceRequest { resource_metrics: vec![TonicResourceMetrics { - resource: Some((&rm.resource).into()), + resource: Some((rm.resource()).into()), scope_metrics: rm.scope_metrics().map(Into::into).collect(), - schema_url: rm.resource.schema_url().map(Into::into).unwrap_or_default(), + schema_url: rm.resource().schema_url().map(Into::into).unwrap_or_default(), }], } } @@ -135,10 +135,10 @@ pub mod tonic { impl From<&SdkScopeMetrics> for TonicScopeMetrics { fn from(sm: &SdkScopeMetrics) -> Self { TonicScopeMetrics { - scope: Some((&sm.scope, None).into()), + scope: Some((sm.scope(), None).into()), metrics: sm.metrics().map(Into::into).collect(), schema_url: sm - .scope + .scope() .schema_url() .map(ToOwned::to_owned) .unwrap_or_default(), @@ -149,11 +149,11 @@ pub mod tonic { impl From<&SdkMetric> for TonicMetric { fn from(metric: &SdkMetric) -> Self { TonicMetric { - name: metric.name.to_string(), - description: metric.description.to_string(), - unit: metric.unit.to_string(), + name: metric.name().to_string(), + description: metric.description().to_string(), + unit: metric.unit().to_string(), metadata: vec![], // internal and currently unused - data: Some(match &metric.data { + data: Some(match metric.data() { AggregatedMetrics::F64(data) => data.into(), AggregatedMetrics::U64(data) => data.into(), AggregatedMetrics::I64(data) => data.into(), diff --git a/opentelemetry-sdk/CHANGELOG.md b/opentelemetry-sdk/CHANGELOG.md index 71547d6d72..32290a855b 100644 --- a/opentelemetry-sdk/CHANGELOG.md +++ b/opentelemetry-sdk/CHANGELOG.md @@ -64,6 +64,12 @@ also modified to suppress telemetry before invoking exporters. - `HistogramDataPoint` no longer exposes `bounds` and `bucket_counts`, but instead offers `bounds()` and `bucket_counts()` methods that returns an iterator over the same. + - `Metric` no longer exposes `name`, `description`, `unit`, `data` fields, but + instead offers `name()`, `description()`, `unit()`, and `data()` accessor methods. + - `ResourceMetrics` no longer exposes `resource` field, but instead offers + a `resource()` accessor method. + - `ScopeMetrics` no longer exposes `scope` field, but instead offers + a `scope()` accessor method. ## 0.29.0 diff --git a/opentelemetry-sdk/src/metrics/data/mod.rs b/opentelemetry-sdk/src/metrics/data/mod.rs index 2f39c5453f..10899cfed6 100644 --- a/opentelemetry-sdk/src/metrics/data/mod.rs +++ b/opentelemetry-sdk/src/metrics/data/mod.rs @@ -12,7 +12,7 @@ use super::Temporality; #[derive(Debug)] pub struct ResourceMetrics { /// The entity that collected the metrics. - pub resource: Resource, + pub(crate) resource: Resource, /// The collection of metrics with unique [InstrumentationScope]s. pub(crate) scope_metrics: Vec, } @@ -27,6 +27,11 @@ impl Default for ResourceMetrics { } impl ResourceMetrics { + /// Returns a reference to the [Resource] in [ResourceMetrics]. + pub fn resource(&self) -> &Resource { + &self.resource + } + /// Returns an iterator over the [ScopeMetrics] in [ResourceMetrics]. pub fn scope_metrics(&self) -> impl Iterator { self.scope_metrics.iter() @@ -37,12 +42,17 @@ impl ResourceMetrics { #[derive(Default, Debug)] pub struct ScopeMetrics { /// The [InstrumentationScope] that the meter was created with. - pub scope: InstrumentationScope, + pub(crate) scope: InstrumentationScope, /// The list of aggregations created by the meter. pub(crate) metrics: Vec, } impl ScopeMetrics { + /// Returns a reference to the [InstrumentationScope] in [ScopeMetrics]. + pub fn scope(&self) -> &InstrumentationScope { + &self.scope + } + /// Returns an iterator over the [Metric]s in [ScopeMetrics]. pub fn metrics(&self) -> impl Iterator { self.metrics.iter() @@ -55,13 +65,35 @@ impl ScopeMetrics { #[derive(Debug)] pub struct Metric { /// The name of the instrument that created this data. - pub name: Cow<'static, str>, + pub(crate) name: Cow<'static, str>, /// The description of the instrument, which can be used in documentation. - pub description: Cow<'static, str>, + pub(crate) description: Cow<'static, str>, /// The unit in which the instrument reports. - pub unit: Cow<'static, str>, + pub(crate) unit: Cow<'static, str>, /// The aggregated data from an instrument. - pub data: AggregatedMetrics, + pub(crate) data: AggregatedMetrics, +} + +impl Metric { + /// Returns the name of the instrument that created this data. + pub fn name(&self) -> &str { + &self.name + } + + /// Returns the description of the instrument. + pub fn description(&self) -> &str { + &self.description + } + + /// Returns the unit in which the instrument reports. + pub fn unit(&self) -> &str { + &self.unit + } + + /// Returns the aggregated data from the instrument. + pub fn data(&self) -> &AggregatedMetrics { + &self.data + } } /// Aggregated metrics data from an instrument diff --git a/opentelemetry-stdout/src/metrics/exporter.rs b/opentelemetry-stdout/src/metrics/exporter.rs index d4466366cd..8702ba3957 100644 --- a/opentelemetry-stdout/src/metrics/exporter.rs +++ b/opentelemetry-stdout/src/metrics/exporter.rs @@ -48,11 +48,11 @@ impl PushMetricExporter for MetricExporter { } else { println!("Metrics"); println!("Resource"); - if let Some(schema_url) = metrics.resource.schema_url() { + if let Some(schema_url) = metrics.resource().schema_url() { println!("\tResource SchemaUrl: {:?}", schema_url); } - metrics.resource.iter().for_each(|(k, v)| { + metrics.resource().iter().for_each(|(k, v)| { println!("\t -> {}={:?}", k, v); }); print_metrics(metrics.scope_metrics()); @@ -82,15 +82,15 @@ impl PushMetricExporter for MetricExporter { fn print_metrics<'a>(metrics: impl Iterator) { for (i, metric) in metrics.enumerate() { println!("\tInstrumentation Scope #{}", i); - println!("\t\tName : {}", &metric.scope.name()); - if let Some(version) = &metric.scope.version() { + let scope = metric.scope(); + println!("\t\tName : {}", scope.name()); + if let Some(version) = scope.version() { println!("\t\tVersion : {:?}", version); } - if let Some(schema_url) = &metric.scope.schema_url() { + if let Some(schema_url) = scope.schema_url() { println!("\t\tSchemaUrl: {:?}", schema_url); } - metric - .scope + scope .attributes() .enumerate() .for_each(|(index, kv)| { @@ -102,9 +102,9 @@ fn print_metrics<'a>(metrics: impl Iterator) { metric.metrics().enumerate().for_each(|(i, metric)| { println!("Metric #{}", i); - println!("\t\tName : {}", &metric.name); - println!("\t\tDescription : {}", &metric.description); - println!("\t\tUnit : {}", &metric.unit); + println!("\t\tName : {}", metric.name()); + println!("\t\tDescription : {}", metric.description()); + println!("\t\tUnit : {}", metric.unit()); fn print_info(data: &MetricData) where @@ -129,7 +129,7 @@ fn print_metrics<'a>(metrics: impl Iterator) { } } } - match &metric.data { + match metric.data() { AggregatedMetrics::F64(data) => print_info(data), AggregatedMetrics::U64(data) => print_info(data), AggregatedMetrics::I64(data) => print_info(data), From 39fa542fb668ba34e778e3700d397cc23c10778a Mon Sep 17 00:00:00 2001 From: Cijo Thomas Date: Thu, 15 May 2025 21:46:50 -0700 Subject: [PATCH 2/2] fmt --- opentelemetry-proto/src/transform/metrics.rs | 6 +++++- opentelemetry-stdout/src/metrics/exporter.rs | 15 ++++++--------- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/opentelemetry-proto/src/transform/metrics.rs b/opentelemetry-proto/src/transform/metrics.rs index e7cdf3ec42..391cb031d9 100644 --- a/opentelemetry-proto/src/transform/metrics.rs +++ b/opentelemetry-proto/src/transform/metrics.rs @@ -116,7 +116,11 @@ pub mod tonic { resource_metrics: vec![TonicResourceMetrics { resource: Some((rm.resource()).into()), scope_metrics: rm.scope_metrics().map(Into::into).collect(), - schema_url: rm.resource().schema_url().map(Into::into).unwrap_or_default(), + schema_url: rm + .resource() + .schema_url() + .map(Into::into) + .unwrap_or_default(), }], } } diff --git a/opentelemetry-stdout/src/metrics/exporter.rs b/opentelemetry-stdout/src/metrics/exporter.rs index 8702ba3957..995d883e45 100644 --- a/opentelemetry-stdout/src/metrics/exporter.rs +++ b/opentelemetry-stdout/src/metrics/exporter.rs @@ -90,15 +90,12 @@ fn print_metrics<'a>(metrics: impl Iterator) { if let Some(schema_url) = scope.schema_url() { println!("\t\tSchemaUrl: {:?}", schema_url); } - scope - .attributes() - .enumerate() - .for_each(|(index, kv)| { - if index == 0 { - println!("\t\tScope Attributes:"); - } - println!("\t\t\t -> {}: {}", kv.key, kv.value); - }); + scope.attributes().enumerate().for_each(|(index, kv)| { + if index == 0 { + println!("\t\tScope Attributes:"); + } + println!("\t\t\t -> {}: {}", kv.key, kv.value); + }); metric.metrics().enumerate().for_each(|(i, metric)| { println!("Metric #{}", i);