11use crate :: error:: { OTelSdkError , OTelSdkResult } ;
2- use crate :: metrics:: data:: ResourceMetrics ;
2+ use crate :: metrics:: data:: {
3+ ExponentialHistogram , Gauge , Histogram , MetricData , ResourceMetrics , Sum ,
4+ } ;
35use crate :: metrics:: exporter:: PushMetricExporter ;
46use crate :: metrics:: Temporality ;
57use crate :: InMemoryExporterError ;
68use std:: collections:: VecDeque ;
79use std:: fmt;
810use std:: sync:: { Arc , Mutex } ;
911
12+ use super :: data:: { AggregatedMetrics , Metric , ScopeMetrics } ;
13+
1014/// An in-memory metrics exporter that stores metrics data in memory.
1115///
1216/// This exporter is useful for testing and debugging purposes. It stores
@@ -145,7 +149,7 @@ impl InMemoryMetricExporter {
145149 let metrics = self
146150 . metrics
147151 . lock ( )
148- . map ( |metrics_guard| metrics_guard. iter ( ) . cloned ( ) . collect ( ) )
152+ . map ( |metrics_guard| metrics_guard. iter ( ) . map ( Self :: clone_metrics ) . collect ( ) )
149153 . map_err ( InMemoryExporterError :: from) ?;
150154 Ok ( metrics)
151155 }
@@ -166,13 +170,78 @@ impl InMemoryMetricExporter {
166170 . lock ( )
167171 . map ( |mut metrics_guard| metrics_guard. clear ( ) ) ;
168172 }
173+
174+ fn clone_metrics ( metric : & ResourceMetrics ) -> ResourceMetrics {
175+ ResourceMetrics {
176+ resource : metric. resource . clone ( ) ,
177+ scope_metrics : metric
178+ . scope_metrics
179+ . iter ( )
180+ . map ( |scope_metric| ScopeMetrics {
181+ scope : scope_metric. scope . clone ( ) ,
182+ metrics : scope_metric
183+ . metrics
184+ . iter ( )
185+ . map ( |metric| Metric {
186+ name : metric. name . clone ( ) ,
187+ description : metric. description . clone ( ) ,
188+ unit : metric. unit . clone ( ) ,
189+ data : Self :: clone_data ( & metric. data ) ,
190+ } )
191+ . collect ( ) ,
192+ } )
193+ . collect ( ) ,
194+ }
195+ }
196+
197+ fn clone_data ( data : & AggregatedMetrics ) -> AggregatedMetrics {
198+ fn clone_inner < T : Clone > ( data : & MetricData < T > ) -> MetricData < T > {
199+ match data {
200+ MetricData :: Gauge ( gauge) => Gauge {
201+ data_points : gauge. data_points . clone ( ) ,
202+ start_time : gauge. start_time ,
203+ time : gauge. time ,
204+ }
205+ . into ( ) ,
206+ MetricData :: Sum ( sum) => Sum {
207+ data_points : sum. data_points . clone ( ) ,
208+ start_time : sum. start_time ,
209+ time : sum. time ,
210+ temporality : sum. temporality ,
211+ is_monotonic : sum. is_monotonic ,
212+ }
213+ . into ( ) ,
214+ MetricData :: Histogram ( histogram) => Histogram {
215+ data_points : histogram. data_points . clone ( ) ,
216+ start_time : histogram. start_time ,
217+ time : histogram. time ,
218+ temporality : histogram. temporality ,
219+ }
220+ . into ( ) ,
221+ MetricData :: ExponentialHistogram ( exponential_histogram) => ExponentialHistogram {
222+ data_points : exponential_histogram. data_points . clone ( ) ,
223+ start_time : exponential_histogram. start_time ,
224+ time : exponential_histogram. time ,
225+ temporality : exponential_histogram. temporality ,
226+ }
227+ . into ( ) ,
228+ }
229+ }
230+ match data {
231+ AggregatedMetrics :: F64 ( metric_data) => AggregatedMetrics :: F64 ( clone_inner ( metric_data) ) ,
232+ AggregatedMetrics :: U64 ( metric_data) => AggregatedMetrics :: U64 ( clone_inner ( metric_data) ) ,
233+ AggregatedMetrics :: I64 ( metric_data) => AggregatedMetrics :: I64 ( clone_inner ( metric_data) ) ,
234+ }
235+ }
169236}
170237
171238impl PushMetricExporter for InMemoryMetricExporter {
172239 async fn export ( & self , metrics : & mut ResourceMetrics ) -> OTelSdkResult {
173240 self . metrics
174241 . lock ( )
175- . map ( |mut metrics_guard| metrics_guard. push_back ( metrics. clone ( ) ) )
242+ . map ( |mut metrics_guard| {
243+ metrics_guard. push_back ( InMemoryMetricExporter :: clone_metrics ( metrics) )
244+ } )
176245 . map_err ( |_| OTelSdkError :: InternalFailure ( "Failed to lock metrics" . to_string ( ) ) )
177246 }
178247
0 commit comments