-
Notifications
You must be signed in to change notification settings - Fork 597
feat: Redesigns the InMemoryMetricExporter
#3257
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
emadpres
wants to merge
9
commits into
open-telemetry:main
Choose a base branch
from
emadpres:fix/2725-resign-in-memory-metric-exporter
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+1,224
−1,086
Open
Changes from all commits
Commits
Show all changes
9 commits
Select commit
Hold shift + click to select a range
bbf0e3c
Redesign InMemoryMetricExporter to receive Vec
emadpres afbc334
Fix get_from_multiple_aggregations
emadpres cd397aa
Fix get_aggregation
emadpres d5b3c66
fmt
emadpres 18a754f
Update leftover old API uses
emadpres ba9847f
fix doc code
emadpres 1b9d7bb
cargo doc
emadpres a3f5570
cargo lint
emadpres c6832c2
Updates CHANGELOG
emadpres File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,19 +4,20 @@ use crate::metrics::data::{ | |||||||||||||||||||
| }; | ||||||||||||||||||||
| use crate::metrics::exporter::PushMetricExporter; | ||||||||||||||||||||
| use crate::metrics::Temporality; | ||||||||||||||||||||
| use crate::InMemoryExporterError; | ||||||||||||||||||||
| use std::collections::VecDeque; | ||||||||||||||||||||
| use std::fmt; | ||||||||||||||||||||
| use std::sync::{Arc, Mutex}; | ||||||||||||||||||||
| use std::time::Duration; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| use super::data::{AggregatedMetrics, Metric, ScopeMetrics}; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| // Not a user-facing type, just a type alias for clarity within this module. | ||||||||||||||||||||
| type InMemoryMetrics = Vec<ResourceMetrics>; | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// An in-memory metrics exporter that stores metrics data in memory. | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// This exporter is useful for testing and debugging purposes. It stores | ||||||||||||||||||||
| /// metric data in a `VecDeque<ResourceMetrics>`. Metrics can be retrieved | ||||||||||||||||||||
| /// using the `get_finished_metrics` method. | ||||||||||||||||||||
| /// metric data in a user-provided `Vec<ResourceMetrics>`, from which the | ||||||||||||||||||||
| /// exported data can be retrieved as well. | ||||||||||||||||||||
|
Comment on lines
18
to
+20
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we should be more explicit here. Something like this perhaps?
Suggested change
|
||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// # Panics | ||||||||||||||||||||
| /// | ||||||||||||||||||||
|
|
@@ -27,6 +28,7 @@ use super::data::{AggregatedMetrics, Metric, ScopeMetrics}; | |||||||||||||||||||
| /// # Example | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| ///# use std::sync::{Arc, Mutex}; | ||||||||||||||||||||
| ///# use opentelemetry_sdk::metrics; | ||||||||||||||||||||
| ///# use opentelemetry::{KeyValue}; | ||||||||||||||||||||
| ///# use opentelemetry::metrics::MeterProvider; | ||||||||||||||||||||
|
|
@@ -35,12 +37,15 @@ use super::data::{AggregatedMetrics, Metric, ScopeMetrics}; | |||||||||||||||||||
| /// | ||||||||||||||||||||
| ///# #[tokio::main] | ||||||||||||||||||||
| ///# async fn main() { | ||||||||||||||||||||
| /// // Create an InMemoryMetricExporter | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporter::default(); | ||||||||||||||||||||
| /// // Create an InMemoryMetricExporter | ||||||||||||||||||||
| /// let metrics = Arc::new(Mutex::new(Vec::new())); | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporter::builder() | ||||||||||||||||||||
| /// .with_metrics(metrics.clone()) | ||||||||||||||||||||
| /// .build(); | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// // Create a MeterProvider and register the exporter | ||||||||||||||||||||
| /// let meter_provider = metrics::SdkMeterProvider::builder() | ||||||||||||||||||||
| /// .with_reader(PeriodicReader::builder(exporter.clone()).build()) | ||||||||||||||||||||
| /// .with_reader(PeriodicReader::builder(exporter).build()) | ||||||||||||||||||||
| /// .build(); | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// // Create and record metrics using the MeterProvider | ||||||||||||||||||||
|
|
@@ -50,26 +55,21 @@ use super::data::{AggregatedMetrics, Metric, ScopeMetrics}; | |||||||||||||||||||
| /// | ||||||||||||||||||||
| /// meter_provider.force_flush().unwrap(); | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// // Retrieve the finished metrics from the exporter | ||||||||||||||||||||
| /// let finished_metrics = exporter.get_finished_metrics().unwrap(); | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// // Print the finished metrics | ||||||||||||||||||||
| /// for resource_metrics in finished_metrics { | ||||||||||||||||||||
| /// for resource_metrics in metrics.lock().unwrap().iter() { | ||||||||||||||||||||
| /// println!("{:?}", resource_metrics); | ||||||||||||||||||||
| /// } | ||||||||||||||||||||
| ///# } | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| pub struct InMemoryMetricExporter { | ||||||||||||||||||||
| metrics: Arc<Mutex<VecDeque<ResourceMetrics>>>, | ||||||||||||||||||||
| metrics: Arc<Mutex<InMemoryMetrics>>, | ||||||||||||||||||||
| temporality: Temporality, | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| impl Clone for InMemoryMetricExporter { | ||||||||||||||||||||
| fn clone(&self) -> Self { | ||||||||||||||||||||
| InMemoryMetricExporter { | ||||||||||||||||||||
| metrics: self.metrics.clone(), | ||||||||||||||||||||
| temporality: self.temporality, | ||||||||||||||||||||
| } | ||||||||||||||||||||
| impl InMemoryMetricExporter { | ||||||||||||||||||||
| /// Creates a new instance of the [`InMemoryMetricExporterBuilder`]. | ||||||||||||||||||||
| pub fn builder() -> InMemoryMetricExporterBuilder { | ||||||||||||||||||||
| InMemoryMetricExporterBuilder::new() | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
|
|
@@ -79,22 +79,20 @@ impl fmt::Debug for InMemoryMetricExporter { | |||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| impl Default for InMemoryMetricExporter { | ||||||||||||||||||||
| fn default() -> Self { | ||||||||||||||||||||
| InMemoryMetricExporterBuilder::new().build() | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// Builder for [`InMemoryMetricExporter`]. | ||||||||||||||||||||
| /// # Example | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| /// # use opentelemetry_sdk::metrics::{InMemoryMetricExporter, InMemoryMetricExporterBuilder}; | ||||||||||||||||||||
| ///# use opentelemetry_sdk::metrics::{InMemoryMetricExporter, InMemoryMetricExporterBuilder}; | ||||||||||||||||||||
| ///# use std::sync::{Arc, Mutex}; | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporterBuilder::new().build(); | ||||||||||||||||||||
| /// let metrics = Arc::new(Mutex::new(Vec::new())); | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporterBuilder::new() | ||||||||||||||||||||
| /// .with_metrics(metrics.clone()).build(); | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| pub struct InMemoryMetricExporterBuilder { | ||||||||||||||||||||
| temporality: Option<Temporality>, | ||||||||||||||||||||
| metrics: Option<Arc<Mutex<InMemoryMetrics>>>, | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| impl fmt::Debug for InMemoryMetricExporterBuilder { | ||||||||||||||||||||
|
|
@@ -112,7 +110,10 @@ impl Default for InMemoryMetricExporterBuilder { | |||||||||||||||||||
| impl InMemoryMetricExporterBuilder { | ||||||||||||||||||||
| /// Creates a new instance of the `InMemoryMetricExporterBuilder`. | ||||||||||||||||||||
| pub fn new() -> Self { | ||||||||||||||||||||
| Self { temporality: None } | ||||||||||||||||||||
| Self { | ||||||||||||||||||||
| temporality: None, | ||||||||||||||||||||
| metrics: None, | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// Set the [Temporality] of the exporter. | ||||||||||||||||||||
|
|
@@ -121,48 +122,34 @@ impl InMemoryMetricExporterBuilder { | |||||||||||||||||||
| self | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// Set the internal collection to store the metrics. | ||||||||||||||||||||
| pub fn with_metrics(mut self, metrics: Arc<Mutex<InMemoryMetrics>>) -> Self { | ||||||||||||||||||||
| self.metrics = Some(metrics); | ||||||||||||||||||||
| self | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// Creates a new instance of the `InMemoryMetricExporter`. | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| pub fn build(self) -> InMemoryMetricExporter { | ||||||||||||||||||||
| InMemoryMetricExporter { | ||||||||||||||||||||
| metrics: Arc::new(Mutex::new(VecDeque::new())), | ||||||||||||||||||||
| metrics: self.metrics.expect("Metrics must be provided"), | ||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should we return a |
||||||||||||||||||||
| temporality: self.temporality.unwrap_or_default(), | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| impl InMemoryMetricExporter { | ||||||||||||||||||||
| /// Returns the finished metrics as a vector of `ResourceMetrics`. | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// # Errors | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// Returns a `MetricError` if the internal lock cannot be acquired. | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// # Example | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| /// # use opentelemetry_sdk::metrics::InMemoryMetricExporter; | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporter::default(); | ||||||||||||||||||||
| /// let finished_metrics = exporter.get_finished_metrics().unwrap(); | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| pub fn get_finished_metrics(&self) -> Result<Vec<ResourceMetrics>, InMemoryExporterError> { | ||||||||||||||||||||
| let metrics = self | ||||||||||||||||||||
| .metrics | ||||||||||||||||||||
| .lock() | ||||||||||||||||||||
| .map(|metrics_guard| metrics_guard.iter().map(Self::clone_metrics).collect()) | ||||||||||||||||||||
| .map_err(InMemoryExporterError::from)?; | ||||||||||||||||||||
| Ok(metrics) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
| /// Clears the internal storage of finished metrics. | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// # Example | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| /// # use opentelemetry_sdk::metrics::InMemoryMetricExporter; | ||||||||||||||||||||
| /// use opentelemetry_sdk::metrics::InMemoryMetricExporter; | ||||||||||||||||||||
| /// use std::sync::{Arc, Mutex}; | ||||||||||||||||||||
| /// | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporter::default(); | ||||||||||||||||||||
| /// let metrics = Arc::new(Mutex::new(Vec::new())); | ||||||||||||||||||||
| /// let exporter = InMemoryMetricExporter::builder() | ||||||||||||||||||||
| /// .with_metrics(metrics.clone()).build(); | ||||||||||||||||||||
| /// exporter.reset(); | ||||||||||||||||||||
| /// ``` | ||||||||||||||||||||
| pub fn reset(&self) { | ||||||||||||||||||||
|
|
@@ -241,7 +228,7 @@ impl PushMetricExporter for InMemoryMetricExporter { | |||||||||||||||||||
| self.metrics | ||||||||||||||||||||
| .lock() | ||||||||||||||||||||
| .map(|mut metrics_guard| { | ||||||||||||||||||||
| metrics_guard.push_back(InMemoryMetricExporter::clone_metrics(metrics)) | ||||||||||||||||||||
| metrics_guard.push(InMemoryMetricExporter::clone_metrics(metrics)) | ||||||||||||||||||||
| }) | ||||||||||||||||||||
| .map_err(|_| OTelSdkError::InternalFailure("Failed to lock metrics".to_string())) | ||||||||||||||||||||
| } | ||||||||||||||||||||
|
|
||||||||||||||||||||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should phrase this so the user knows what the impact on them is. Something like this perhaps?: