Skip to content

Commit 1ddbfa8

Browse files
committed
Refactor InMemoryMetricExporter
1 parent 189078d commit 1ddbfa8

File tree

2 files changed

+119
-130
lines changed

2 files changed

+119
-130
lines changed

opentelemetry-sdk/src/metrics/in_memory_exporter.rs

Lines changed: 21 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,15 @@ use crate::error::{OTelSdkError, OTelSdkResult};
22
use crate::metrics::data::{self, Gauge, Sum};
33
use crate::metrics::data::{Histogram, Metric, ResourceMetrics, ScopeMetrics};
44
use crate::metrics::exporter::PushMetricExporter;
5-
use crate::metrics::MetricError;
6-
use crate::metrics::MetricResult;
75
use crate::metrics::Temporality;
86
use async_trait::async_trait;
9-
use std::collections::VecDeque;
107
use std::fmt;
118
use std::sync::{Arc, Mutex};
129

1310
/// An in-memory metrics exporter that stores metrics data in memory.
1411
///
1512
/// This exporter is useful for testing and debugging purposes. It stores
16-
/// metric data in a `VecDeque<ResourceMetrics>`. Metrics can be retrieved
17-
/// using the `get_finished_metrics` method.
13+
/// metric data in a user provided Vec.
1814
///
1915
/// # Panics
2016
///
@@ -34,11 +30,12 @@ use std::sync::{Arc, Mutex};
3430
///# #[tokio::main]
3531
///# async fn main() {
3632
/// // Create an InMemoryMetricExporter
37-
/// let exporter = InMemoryMetricExporter::default();
33+
/// let exported_metrics = Arc::new(Mutex::new(Vec::new()));
34+
/// let exporter = InMemoryMetricExporter::builder().with_metrics(exported_metrics.clone()).build();
3835
///
3936
/// // Create a MeterProvider and register the exporter
4037
/// let meter_provider = metrics::SdkMeterProvider::builder()
41-
/// .with_reader(PeriodicReader::builder(exporter.clone()).build())
38+
/// .with_reader(PeriodicReader::builder(exporter).build())
4239
/// .build();
4340
///
4441
/// // Create and record metrics using the MeterProvider
@@ -48,38 +45,28 @@ use std::sync::{Arc, Mutex};
4845
///
4946
/// meter_provider.force_flush().unwrap();
5047
///
51-
/// // Retrieve the finished metrics from the exporter
52-
/// let finished_metrics = exporter.get_finished_metrics().unwrap();
5348
///
5449
/// // Print the finished metrics
55-
/// for resource_metrics in finished_metrics {
50+
/// for resource_metrics in exported_metrics.lock().unwrap().iter() {
5651
/// println!("{:?}", resource_metrics);
5752
/// }
5853
///# }
5954
/// ```
6055
pub struct InMemoryMetricExporter {
61-
metrics: Arc<Mutex<VecDeque<ResourceMetrics>>>,
56+
metrics: Arc<Mutex<Vec<ResourceMetrics>>>,
6257
temporality: Temporality,
6358
}
6459

65-
impl Clone for InMemoryMetricExporter {
66-
fn clone(&self) -> Self {
67-
InMemoryMetricExporter {
68-
metrics: self.metrics.clone(),
69-
temporality: self.temporality,
70-
}
71-
}
72-
}
73-
7460
impl fmt::Debug for InMemoryMetricExporter {
7561
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
7662
f.debug_struct("InMemoryMetricExporter").finish()
7763
}
7864
}
7965

80-
impl Default for InMemoryMetricExporter {
81-
fn default() -> Self {
82-
InMemoryMetricExporterBuilder::new().build()
66+
impl InMemoryMetricExporter {
67+
/// Creates a builder.
68+
pub fn builder() -> InMemoryMetricExporterBuilder {
69+
InMemoryMetricExporterBuilder::new()
8370
}
8471
}
8572

@@ -93,6 +80,7 @@ impl Default for InMemoryMetricExporter {
9380
/// ```
9481
pub struct InMemoryMetricExporterBuilder {
9582
temporality: Option<Temporality>,
83+
metrics: Option<Arc<Mutex<Vec<ResourceMetrics>>>>,
9684
}
9785

9886
impl fmt::Debug for InMemoryMetricExporterBuilder {
@@ -110,7 +98,8 @@ impl Default for InMemoryMetricExporterBuilder {
11098
impl InMemoryMetricExporterBuilder {
11199
/// Creates a new instance of the `InMemoryMetricExporterBuilder`.
112100
pub fn new() -> Self {
113-
Self { temporality: None }
101+
Self { temporality: None,
102+
metrics: None }
114103
}
115104

116105
/// Set the [Temporality] of the exporter.
@@ -119,55 +108,23 @@ impl InMemoryMetricExporterBuilder {
119108
self
120109
}
121110

111+
/// Set the collection to store the metrics.
112+
pub fn with_metrics(mut self, metrics: Arc<Mutex<Vec<ResourceMetrics>>>) -> Self {
113+
self.metrics = Some(metrics);
114+
self
115+
}
116+
122117
/// Creates a new instance of the `InMemoryMetricExporter`.
123118
///
124119
pub fn build(self) -> InMemoryMetricExporter {
125120
InMemoryMetricExporter {
126-
metrics: Arc::new(Mutex::new(VecDeque::new())),
121+
metrics: self.metrics.expect("Metric collection is required"),
127122
temporality: self.temporality.unwrap_or_default(),
128123
}
129124
}
130125
}
131126

132127
impl InMemoryMetricExporter {
133-
/// Returns the finished metrics as a vector of `ResourceMetrics`.
134-
///
135-
/// # Errors
136-
///
137-
/// Returns a `MetricError` if the internal lock cannot be acquired.
138-
///
139-
/// # Example
140-
///
141-
/// ```
142-
/// # use opentelemetry_sdk::metrics::InMemoryMetricExporter;
143-
///
144-
/// let exporter = InMemoryMetricExporter::default();
145-
/// let finished_metrics = exporter.get_finished_metrics().unwrap();
146-
/// ```
147-
pub fn get_finished_metrics(&self) -> MetricResult<Vec<ResourceMetrics>> {
148-
self.metrics
149-
.lock()
150-
.map(|metrics_guard| metrics_guard.iter().map(Self::clone_metrics).collect())
151-
.map_err(MetricError::from)
152-
}
153-
154-
/// Clears the internal storage of finished metrics.
155-
///
156-
/// # Example
157-
///
158-
/// ```
159-
/// # use opentelemetry_sdk::metrics::InMemoryMetricExporter;
160-
///
161-
/// let exporter = InMemoryMetricExporter::default();
162-
/// exporter.reset();
163-
/// ```
164-
pub fn reset(&self) {
165-
let _ = self
166-
.metrics
167-
.lock()
168-
.map(|mut metrics_guard| metrics_guard.clear());
169-
}
170-
171128
fn clone_metrics(metric: &ResourceMetrics) -> ResourceMetrics {
172129
ResourceMetrics {
173130
resource: metric.resource.clone(),
@@ -269,7 +226,7 @@ impl PushMetricExporter for InMemoryMetricExporter {
269226
self.metrics
270227
.lock()
271228
.map(|mut metrics_guard| {
272-
metrics_guard.push_back(InMemoryMetricExporter::clone_metrics(metrics))
229+
metrics_guard.push(InMemoryMetricExporter::clone_metrics(metrics))
273230
})
274231
.map_err(|_| OTelSdkError::InternalFailure("Failed to lock metrics".to_string()))
275232
}

0 commit comments

Comments
 (0)