Skip to content

Commit bc82d4f

Browse files
authored
fix: Cleanup MetricError and use OTelSdkResult instead (open-telemetry#2905)
1 parent e9ae9f9 commit bc82d4f

File tree

9 files changed

+45
-27
lines changed

9 files changed

+45
-27
lines changed

Diff for: opentelemetry-sdk/CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ also modified to suppress telemetry before invoking exporters.
2121
- TODO/Placeholder: Add ability to configure cardinality limits via Instrument
2222
advisory.
2323

24+
- *Breaking* change for custom `MetricReader` authors.
25+
The `shutdown_with_timeout` method is added to `MetricReader` trait.
26+
`collect` method on `MetricReader` modified to return `OTelSdkResult`.
27+
2428
## 0.29.0
2529

2630
Released 2025-Mar-21
@@ -78,7 +82,6 @@ Released 2025-Mar-21
7882
Custom exporters will need to internally synchronize any mutable state, if applicable.
7983

8084
- **Breaking** The `shutdown_with_timeout` method is added to MetricExporter trait. This is breaking change for custom `MetricExporter` authors.
81-
- **Breaking** The `shutdown_with_timeout` method is added to MetricReader trait. This is breaking change for custom `MetricReader` authors.
8285
- Bug Fix: `BatchLogProcessor` now correctly calls `shutdown` on the exporter
8386
when its `shutdown` is invoked.
8487

Diff for: opentelemetry-sdk/benches/metric.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@ use opentelemetry_sdk::{
77
error::OTelSdkResult,
88
metrics::{
99
data::ResourceMetrics, new_view, reader::MetricReader, Aggregation, Instrument,
10-
InstrumentKind, ManualReader, MetricResult, Pipeline, SdkMeterProvider, Stream,
11-
Temporality, View,
10+
InstrumentKind, ManualReader, Pipeline, SdkMeterProvider, Stream, Temporality, View,
1211
},
1312
Resource,
1413
};
@@ -24,7 +23,7 @@ impl MetricReader for SharedReader {
2423
self.0.register_pipeline(pipeline)
2524
}
2625

27-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
26+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
2827
self.0.collect(rm)
2928
}
3029

Diff for: opentelemetry-sdk/src/metrics/manual_reader.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use std::{
77

88
use crate::{
99
error::{OTelSdkError, OTelSdkResult},
10-
metrics::{MetricError, MetricResult, Temporality},
10+
metrics::Temporality,
1111
};
1212

1313
use super::{
@@ -90,12 +90,16 @@ impl MetricReader for ManualReader {
9090
/// callbacks necessary and returning the results.
9191
///
9292
/// Returns an error if called after shutdown.
93-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
94-
let inner = self.inner.lock()?;
93+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
94+
let inner = self
95+
.inner
96+
.lock()
97+
.map_err(|_| OTelSdkError::InternalFailure("Failed to lock pipeline".into()))?;
98+
9599
match &inner.sdk_producer.as_ref().and_then(|w| w.upgrade()) {
96100
Some(producer) => producer.produce(rm)?,
97101
None => {
98-
return Err(MetricError::Other(
102+
return Err(OTelSdkError::InternalFailure(
99103
"reader is shut down or not registered".into(),
100104
))
101105
}

Diff for: opentelemetry-sdk/src/metrics/periodic_reader.rs

+7-5
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use opentelemetry::{otel_debug, otel_error, otel_info, otel_warn, Context};
1212

1313
use crate::{
1414
error::{OTelSdkError, OTelSdkResult},
15-
metrics::{exporter::PushMetricExporter, reader::SdkProducer, MetricError, MetricResult},
15+
metrics::{exporter::PushMetricExporter, reader::SdkProducer},
1616
Resource,
1717
};
1818

@@ -357,11 +357,11 @@ impl<E: PushMetricExporter> PeriodicReaderInner<E> {
357357
self.exporter.temporality()
358358
}
359359

360-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
360+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
361361
let producer = self.producer.lock().expect("lock poisoned");
362362
if let Some(p) = producer.as_ref() {
363363
p.upgrade()
364-
.ok_or_else(|| MetricError::Other("pipeline is dropped".into()))?
364+
.ok_or(OTelSdkError::AlreadyShutdown)?
365365
.produce(rm)?;
366366
Ok(())
367367
} else {
@@ -371,7 +371,9 @@ impl<E: PushMetricExporter> PeriodicReaderInner<E> {
371371
This occurs when a periodic reader is created but not associated with a MeterProvider \
372372
by calling `.with_reader(reader)` on MeterProviderBuilder."
373373
);
374-
Err(MetricError::Other("MeterProvider is not registered".into()))
374+
Err(OTelSdkError::InternalFailure(
375+
"MeterProvider is not registered".into(),
376+
))
375377
}
376378
}
377379

@@ -479,7 +481,7 @@ impl<E: PushMetricExporter> MetricReader for PeriodicReader<E> {
479481
self.inner.register_pipeline(pipeline);
480482
}
481483

482-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
484+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
483485
self.inner.collect(rm)
484486
}
485487

Diff for: opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs

+13-7
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use opentelemetry::{otel_debug, otel_error};
1616
use crate::runtime::{to_interval_stream, Runtime};
1717
use crate::{
1818
error::{OTelSdkError, OTelSdkResult},
19-
metrics::{exporter::PushMetricExporter, reader::SdkProducer, MetricError, MetricResult},
19+
metrics::{exporter::PushMetricExporter, reader::SdkProducer},
2020
Resource,
2121
};
2222

@@ -351,10 +351,14 @@ impl<E: PushMetricExporter> MetricReader for PeriodicReader<E> {
351351
worker(self);
352352
}
353353

354-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
355-
let inner = self.inner.lock()?;
354+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
355+
let inner = self
356+
.inner
357+
.lock()
358+
.map_err(|_| OTelSdkError::InternalFailure("Failed to lock pipeline".into()))?;
359+
356360
if inner.is_shutdown {
357-
return Err(MetricError::Other("reader is shut down".into()));
361+
return Err(OTelSdkError::AlreadyShutdown);
358362
}
359363

360364
if let Some(producer) = match &inner.sdk_producer_or_worker {
@@ -363,7 +367,9 @@ impl<E: PushMetricExporter> MetricReader for PeriodicReader<E> {
363367
} {
364368
producer.produce(rm)?;
365369
} else {
366-
return Err(MetricError::Other("reader is not registered".into()));
370+
return Err(OTelSdkError::InternalFailure(
371+
"reader is not registered".into(),
372+
));
367373
}
368374

369375
Ok(())
@@ -434,8 +440,8 @@ impl<E: PushMetricExporter> MetricReader for PeriodicReader<E> {
434440
#[cfg(all(test, feature = "testing"))]
435441
mod tests {
436442
use super::PeriodicReader;
443+
use crate::error::OTelSdkError;
437444
use crate::metrics::reader::MetricReader;
438-
use crate::metrics::MetricError;
439445
use crate::{
440446
metrics::data::ResourceMetrics, metrics::InMemoryMetricExporter, metrics::SdkMeterProvider,
441447
runtime, Resource,
@@ -496,7 +502,7 @@ mod tests {
496502

497503
// Assert
498504
assert!(
499-
matches!(result.unwrap_err(), MetricError::Other(err) if err == "reader is not registered")
505+
matches!(result.unwrap_err(), OTelSdkError::InternalFailure(err) if err == "reader is not registered")
500506
);
501507
}
502508

Diff for: opentelemetry-sdk/src/metrics/pipeline.rs

+5-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,11 @@ impl Pipeline {
100100

101101
impl SdkProducer for Pipeline {
102102
/// Returns aggregated metrics from a single collection.
103-
fn produce(&self, rm: &mut ResourceMetrics) -> MetricResult<()> {
104-
let inner = self.inner.lock()?;
103+
fn produce(&self, rm: &mut ResourceMetrics) -> OTelSdkResult {
104+
let inner = self
105+
.inner
106+
.lock()
107+
.map_err(|_| OTelSdkError::InternalFailure("Failed to lock pipeline".into()))?;
105108
otel_debug!(
106109
name: "MeterProviderInvokingObservableCallbacks",
107110
count = inner.callbacks.len(),

Diff for: opentelemetry-sdk/src/metrics/reader.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
//! Interfaces for reading and producing metrics
2-
use crate::{error::OTelSdkResult, metrics::MetricResult};
2+
use crate::error::OTelSdkResult;
33
use std::time::Duration;
44
use std::{fmt, sync::Weak};
55

@@ -30,7 +30,7 @@ pub trait MetricReader: fmt::Debug + Send + Sync + 'static {
3030
/// SDK and stores it in the provided [ResourceMetrics] reference.
3131
///
3232
/// An error is returned if this is called after shutdown.
33-
fn collect(&self, rm: &mut ResourceMetrics) -> MetricResult<()>;
33+
fn collect(&self, rm: &mut ResourceMetrics) -> OTelSdkResult;
3434

3535
/// Flushes all metric measurements held in an export pipeline.
3636
///
@@ -63,5 +63,5 @@ pub trait MetricReader: fmt::Debug + Send + Sync + 'static {
6363
/// Produces metrics for a [MetricReader].
6464
pub(crate) trait SdkProducer: fmt::Debug + Send + Sync {
6565
/// Returns aggregated metrics from a single collection.
66-
fn produce(&self, rm: &mut ResourceMetrics) -> MetricResult<()>;
66+
fn produce(&self, rm: &mut ResourceMetrics) -> OTelSdkResult;
6767
}

Diff for: opentelemetry-sdk/src/metrics/view.rs

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ pub fn new_view(criteria: Instrument, mask: Stream) -> MetricResult<Box<dyn View
170170
}
171171

172172
#[cfg(test)]
173+
#[cfg(feature = "spec_unstable_metrics_views")]
173174
mod tests {
174175
use super::*;
175176
#[test]

Diff for: opentelemetry-sdk/src/testing/metrics/metric_reader.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
use crate::error::{OTelSdkError, OTelSdkResult};
2+
use crate::metrics::Temporality;
23
use crate::metrics::{
34
data::ResourceMetrics, pipeline::Pipeline, reader::MetricReader, InstrumentKind,
45
};
5-
use crate::metrics::{MetricResult, Temporality};
66
use std::sync::{Arc, Mutex, Weak};
77
use std::time::Duration;
88

@@ -34,7 +34,7 @@ impl Default for TestMetricReader {
3434
impl MetricReader for TestMetricReader {
3535
fn register_pipeline(&self, _pipeline: Weak<Pipeline>) {}
3636

37-
fn collect(&self, _rm: &mut ResourceMetrics) -> MetricResult<()> {
37+
fn collect(&self, _rm: &mut ResourceMetrics) -> OTelSdkResult {
3838
Ok(())
3939
}
4040

0 commit comments

Comments
 (0)