Skip to content

Commit e2280f7

Browse files
committed
Make Metric borrowable
1 parent ffa7d74 commit e2280f7

File tree

9 files changed

+98
-82
lines changed

9 files changed

+98
-82
lines changed

opentelemetry-proto/src/transform/metrics.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ pub mod tonic {
1111
use opentelemetry_sdk::metrics::data::{
1212
AggregatedMetrics, Exemplar as SdkExemplar,
1313
ExponentialHistogram as SdkExponentialHistogram, Gauge as SdkGauge,
14-
Histogram as SdkHistogram, Metric as SdkMetric, MetricData, Sum as SdkSum,
14+
Histogram as SdkHistogram, MetricData, Sum as SdkSum,
1515
};
16-
use opentelemetry_sdk::metrics::exporter::{ResourceMetrics, ScopeMetrics};
16+
use opentelemetry_sdk::metrics::exporter::{Metric, ResourceMetrics, ScopeMetrics};
1717
use opentelemetry_sdk::metrics::Temporality;
1818
use opentelemetry_sdk::Resource as SdkResource;
1919

@@ -153,12 +153,12 @@ pub mod tonic {
153153
}
154154
}
155155

156-
impl From<&SdkMetric> for TonicMetric {
157-
fn from(metric: &SdkMetric) -> Self {
156+
impl From<Metric<'_>> for TonicMetric {
157+
fn from(metric: Metric<'_>) -> Self {
158158
TonicMetric {
159-
name: metric.name.to_string(),
160-
description: metric.description.to_string(),
161-
unit: metric.unit.to_string(),
159+
name: metric.instrument.name.to_string(),
160+
description: metric.instrument.description.to_string(),
161+
unit: metric.instrument.unit.to_string(),
162162
metadata: vec![], // internal and currently unused
163163
data: Some(match &metric.data {
164164
AggregatedMetrics::F64(data) => data.into(),

opentelemetry-sdk/src/metrics/data/mod.rs

+1-16
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,11 @@
11
//! Types for delivery of pre-aggregated metric time series data.
22
3-
use std::{borrow::Cow, time::SystemTime};
3+
use std::time::SystemTime;
44

55
use opentelemetry::KeyValue;
66

77
use super::Temporality;
88

9-
/// A collection of one or more aggregated time series from an [Instrument].
10-
///
11-
/// [Instrument]: crate::metrics::Instrument
12-
#[derive(Debug)]
13-
pub struct Metric {
14-
/// The name of the instrument that created this data.
15-
pub name: Cow<'static, str>,
16-
/// The description of the instrument, which can be used in documentation.
17-
pub description: Cow<'static, str>,
18-
/// The unit in which the instrument reports.
19-
pub unit: Cow<'static, str>,
20-
/// The aggregated data from an instrument.
21-
pub data: AggregatedMetrics,
22-
}
23-
249
/// Aggregated metrics data from an instrument
2510
#[derive(Debug)]
2611
pub enum AggregatedMetrics {

opentelemetry-sdk/src/metrics/exporter.rs

+20-6
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ use crate::{error::OTelSdkResult, Resource};
66
use std::{fmt::Debug, slice::Iter, time::Duration};
77

88
use super::{
9-
data::Metric,
10-
reader::{ResourceMetricsData, ScopeMetricsData},
11-
Temporality,
9+
data::AggregatedMetrics,
10+
reader::{MetricsData, ResourceMetricsData, ScopeMetricsData},
11+
InstrumentInfo, Temporality,
1212
};
1313

1414
/// A collection of [`BatchScopeMetrics`] and the associated [Resource] that created them.
@@ -38,7 +38,18 @@ pub struct ScopeMetrics<'a> {
3838
/// Iterator over aggregations created by the meter.
3939
/// Doesn't implement standard [`Iterator`], because it returns borrowed items. AKA "LendingIterator".
4040
pub struct MetricsLendingIter<'a> {
41-
iter: Iter<'a, Metric>,
41+
iter: Iter<'a, MetricsData>,
42+
}
43+
44+
/// A collection of one or more aggregated time series from an [Instrument].
45+
///
46+
/// [Instrument]: crate::metrics::Instrument
47+
#[derive(Debug)]
48+
pub struct Metric<'a> {
49+
/// The name of the instrument that created this data.
50+
pub instrument: &'a InstrumentInfo,
51+
/// The aggregated data from an instrument.
52+
pub data: &'a AggregatedMetrics,
4253
}
4354

4455
impl<'a> ResourceMetrics<'a> {
@@ -78,8 +89,11 @@ impl ScopeMetricsLendingIter<'_> {
7889

7990
impl MetricsLendingIter<'_> {
8091
/// Advances the iterator and returns the next value.
81-
pub fn next(&mut self) -> Option<&Metric> {
82-
self.iter.next()
92+
pub fn next(&mut self) -> Option<Metric<'_>> {
93+
self.iter.next().map(|metric| Metric {
94+
instrument: &metric.instrument,
95+
data: &metric.data,
96+
})
8397
}
8498
}
8599

opentelemetry-sdk/src/metrics/in_memory_exporter.rs

+6-10
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ use std::fmt;
88
use std::sync::{Arc, Mutex};
99
use std::time::Duration;
1010

11-
use super::data::{AggregatedMetrics, Metric};
11+
use super::data::AggregatedMetrics;
1212
use super::exporter::ResourceMetrics;
13-
use super::reader::{ResourceMetricsData, ScopeMetricsData};
13+
use super::reader::{MetricsData, ResourceMetricsData, ScopeMetricsData};
1414

1515
/// An in-memory metrics exporter that stores metrics data in memory.
1616
///
@@ -163,10 +163,8 @@ impl InMemoryMetricExporter {
163163
metrics: data
164164
.metrics
165165
.iter()
166-
.map(|data| Metric {
167-
name: data.name.clone(),
168-
description: data.description.clone(),
169-
unit: data.unit.clone(),
166+
.map(|data| MetricsData {
167+
instrument: data.instrument.clone(),
170168
data: Self::clone_data(&data.data),
171169
})
172170
.collect(),
@@ -201,10 +199,8 @@ impl InMemoryMetricExporter {
201199
while let Some(mut scope_metric) = metric.scope_metrics.next() {
202200
let mut metrics = Vec::new();
203201
while let Some(metric) = scope_metric.metrics.next() {
204-
metrics.push(Metric {
205-
name: metric.name.clone(),
206-
description: metric.description.clone(),
207-
unit: metric.unit.clone(),
202+
metrics.push(MetricsData {
203+
instrument: metric.instrument.clone(),
208204
data: Self::clone_data(&metric.data),
209205
});
210206
}

opentelemetry-sdk/src/metrics/instrument.rs

+13
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,19 @@ impl InstrumentKind {
6565
}
6666
}
6767

68+
/// Describes properties an instrument is created with
69+
#[derive(Debug, Clone)]
70+
pub struct InstrumentInfo {
71+
/// The human-readable identifier of the instrument.
72+
pub name: Cow<'static, str>,
73+
/// describes the purpose of the instrument.
74+
pub description: Cow<'static, str>,
75+
/// The functional group of the instrument.
76+
pub kind: InstrumentKind,
77+
/// Unit is the unit of measurement recorded by the instrument.
78+
pub unit: Cow<'static, str>,
79+
}
80+
6881
/// Describes properties an instrument is created with, also used for filtering
6982
/// in [View](crate::metrics::View)s.
7083
///

opentelemetry-sdk/src/metrics/mod.rs

+19-19
Original file line numberDiff line numberDiff line change
@@ -690,8 +690,8 @@ mod tests {
690690
"There should be single metric merging duplicate instruments"
691691
);
692692
let metric = &resource_metrics[0].scope_metrics[0].metrics[0];
693-
assert_eq!(metric.name, "my_counter");
694-
assert_eq!(metric.unit, "my_unit");
693+
assert_eq!(metric.instrument.name, "my_counter");
694+
assert_eq!(metric.instrument.unit, "my_unit");
695695
let MetricData::Sum(sum) = u64::extract_metrics_data_ref(&metric.data)
696696
.expect("Sum aggregation expected for Counter instruments by default")
697697
else {
@@ -756,9 +756,9 @@ mod tests {
756756

757757
if let Some(scope1) = scope1 {
758758
let metric1 = &scope1.metrics[0];
759-
assert_eq!(metric1.name, "my_counter");
760-
assert_eq!(metric1.unit, "my_unit");
761-
assert_eq!(metric1.description, "my_description");
759+
assert_eq!(metric1.instrument.name, "my_counter");
760+
assert_eq!(metric1.instrument.unit, "my_unit");
761+
assert_eq!(metric1.instrument.description, "my_description");
762762
let MetricData::Sum(sum1) = u64::extract_metrics_data_ref(&metric1.data)
763763
.expect("Sum aggregation expected for Counter instruments by default")
764764
else {
@@ -776,9 +776,9 @@ mod tests {
776776

777777
if let Some(scope2) = scope2 {
778778
let metric2 = &scope2.metrics[0];
779-
assert_eq!(metric2.name, "my_counter");
780-
assert_eq!(metric2.unit, "my_unit");
781-
assert_eq!(metric2.description, "my_description");
779+
assert_eq!(metric2.instrument.name, "my_counter");
780+
assert_eq!(metric2.instrument.unit, "my_unit");
781+
assert_eq!(metric2.instrument.description, "my_description");
782782

783783
let MetricData::Sum(sum2) = u64::extract_metrics_data_ref(&metric2.data)
784784
.expect("Sum aggregation expected for Counter instruments by default")
@@ -862,9 +862,9 @@ mod tests {
862862
assert!(scope.attributes().eq(&[KeyValue::new("key", "value1")]));
863863

864864
let metric = &resource_metrics[0].scope_metrics[0].metrics[0];
865-
assert_eq!(metric.name, "my_counter");
866-
assert_eq!(metric.unit, "my_unit");
867-
assert_eq!(metric.description, "my_description");
865+
assert_eq!(metric.instrument.name, "my_counter");
866+
assert_eq!(metric.instrument.unit, "my_unit");
867+
assert_eq!(metric.instrument.description, "my_description");
868868

869869
let MetricData::Sum(sum) = u64::extract_metrics_data_ref(&metric.data)
870870
.expect("Sum aggregation expected for Counter instruments by default")
@@ -919,11 +919,11 @@ mod tests {
919919
assert!(!resource_metrics.is_empty());
920920
let metric = &resource_metrics[0].scope_metrics[0].metrics[0];
921921
assert_eq!(
922-
metric.name, "test_histogram",
922+
metric.instrument.name, "test_histogram",
923923
"View rename should be ignored and original name retained."
924924
);
925925
assert_eq!(
926-
metric.unit, "test_unit",
926+
metric.instrument.unit, "test_unit",
927927
"View rename of unit should be ignored and original unit retained."
928928
);
929929
}
@@ -985,7 +985,7 @@ mod tests {
985985
.expect("metrics are expected to be exported.");
986986
assert!(!resource_metrics.is_empty());
987987
let metric = &resource_metrics[0].scope_metrics[0].metrics[0];
988-
assert_eq!(metric.name, "my_observable_counter",);
988+
assert_eq!(metric.instrument.name, "my_observable_counter",);
989989

990990
let MetricData::Sum(sum) = u64::extract_metrics_data_ref(&metric.data)
991991
.expect("Sum aggregation expected for ObservableCounter instruments by default")
@@ -1061,7 +1061,7 @@ mod tests {
10611061
.expect("metrics are expected to be exported.");
10621062
assert!(!resource_metrics.is_empty());
10631063
let metric = &resource_metrics[0].scope_metrics[0].metrics[0];
1064-
assert_eq!(metric.name, "my_counter",);
1064+
assert_eq!(metric.instrument.name, "my_counter",);
10651065

10661066
let MetricData::Sum(sum) = u64::extract_metrics_data_ref(&metric.data)
10671067
.expect("Sum aggregation expected for Counter instruments by default")
@@ -3029,9 +3029,9 @@ mod tests {
30293029
assert!(!resource_metric.scope_metrics[0].metrics.is_empty());
30303030

30313031
let metric = &resource_metric.scope_metrics[0].metrics[0];
3032-
assert_eq!(metric.name, counter_name);
3032+
assert_eq!(metric.instrument.name, counter_name);
30333033
if let Some(expected_unit) = unit_name {
3034-
assert_eq!(metric.unit, expected_unit);
3034+
assert_eq!(metric.instrument.unit, expected_unit);
30353035
}
30363036

30373037
T::extract_metrics_data_ref(&metric.data)
@@ -3073,10 +3073,10 @@ mod tests {
30733073
assert!(!resource_metric.scope_metrics[0].metrics.is_empty());
30743074

30753075
let metric = &resource_metric.scope_metrics[0].metrics[0];
3076-
assert_eq!(metric.name, counter_name);
3076+
assert_eq!(metric.instrument.name, counter_name);
30773077

30783078
if let Some(expected_unit) = unit_name {
3079-
assert_eq!(metric.unit, expected_unit);
3079+
assert_eq!(metric.instrument.unit, expected_unit);
30803080
}
30813081

30823082
let aggregation = T::extract_metrics_data_ref(&metric.data)

opentelemetry-sdk/src/metrics/pipeline.rs

+15-19
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,11 @@ use crate::{
1111
error::{OTelSdkError, OTelSdkResult},
1212
metrics::{
1313
aggregation,
14-
data::Metric,
1514
error::{MetricError, MetricResult},
1615
instrument::{Instrument, InstrumentId, InstrumentKind, Stream},
1716
internal::{self, AggregateBuilder, Number},
18-
reader::{MetricReader, ScopeMetricsData, SdkProducer},
19-
view::View,
17+
reader::{MetricReader, MetricsData, ScopeMetricsData, SdkProducer},
18+
view::View, InstrumentInfo,
2019
},
2120
Resource,
2221
};
@@ -138,10 +137,8 @@ impl SdkProducer for Pipeline {
138137
let mut m = sm.metrics.get_mut(j);
139138
match (inst.comp_agg.call(m.as_mut().map(|m| &mut m.data)), m) {
140139
// No metric to re-use, expect agg to create new metric data
141-
((len, Some(initial_agg)), None) if len > 0 => sm.metrics.push(Metric {
142-
name: inst.name.clone(),
143-
description: inst.description.clone(),
144-
unit: inst.unit.clone(),
140+
((len, Some(initial_agg)), None) if len > 0 => sm.metrics.push(MetricsData {
141+
instrument: inst.info.clone(),
145142
data: initial_agg,
146143
}),
147144
// Existing metric can be re-used, update its values
@@ -150,9 +147,7 @@ impl SdkProducer for Pipeline {
150147
// previous aggregation was of a different type
151148
prev_agg.data = data;
152149
}
153-
prev_agg.name.clone_from(&inst.name);
154-
prev_agg.description.clone_from(&inst.description);
155-
prev_agg.unit.clone_from(&inst.unit);
150+
prev_agg.instrument.clone_from(&inst.info);
156151
}
157152
_ => continue,
158153
}
@@ -175,18 +170,16 @@ impl SdkProducer for Pipeline {
175170

176171
/// A synchronization point between a [Pipeline] and an instrument's aggregate function.
177172
struct InstrumentSync {
178-
name: Cow<'static, str>,
179-
description: Cow<'static, str>,
180-
unit: Cow<'static, str>,
173+
info: InstrumentInfo,
181174
comp_agg: Arc<dyn internal::ComputeAggregation>,
182175
}
183176

184177
impl fmt::Debug for InstrumentSync {
185178
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
186179
f.debug_struct("InstrumentSync")
187-
.field("name", &self.name)
188-
.field("description", &self.description)
189-
.field("unit", &self.unit)
180+
.field("name", &self.info.name)
181+
.field("description", &self.info.description)
182+
.field("unit", &self.info.unit)
190183
.finish()
191184
}
192185
}
@@ -410,9 +403,12 @@ where
410403
self.pipeline.add_sync(
411404
scope.clone(),
412405
InstrumentSync {
413-
name: stream.name,
414-
description: stream.description,
415-
unit: stream.unit,
406+
info: InstrumentInfo {
407+
name: stream.name,
408+
description: stream.description,
409+
unit: stream.unit,
410+
kind,
411+
},
416412
comp_agg: collect,
417413
},
418414
);

opentelemetry-sdk/src/metrics/reader.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::Resource;
66
use std::time::Duration;
77
use std::{fmt, sync::Weak};
88

9-
use super::data::Metric;
9+
use super::data::AggregatedMetrics;
10+
use super::InstrumentInfo;
1011
use super::{pipeline::Pipeline, InstrumentKind, Temporality};
1112

1213
/// A collection of [ScopeMetricsData] and the associated [Resource] that created them.
@@ -24,7 +25,18 @@ pub struct ScopeMetricsData {
2425
/// The [InstrumentationScope] that the meter was created with.
2526
pub scope: InstrumentationScope,
2627
/// The list of aggregations created by the meter.
27-
pub metrics: Vec<Metric>,
28+
pub metrics: Vec<MetricsData>,
29+
}
30+
31+
/// A collection of one or more aggregated time series from an [Instrument].
32+
///
33+
/// [Instrument]: crate::metrics::Instrument
34+
#[derive(Debug)]
35+
pub struct MetricsData {
36+
/// The name of the instrument that created this data.
37+
pub instrument: InstrumentInfo,
38+
/// The aggregated data from an instrument.
39+
pub data: AggregatedMetrics,
2840
}
2941

3042
/// The interface used between the SDK and an exporter.

opentelemetry-stdout/src/metrics/exporter.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,9 @@ fn print_metrics(mut metrics: MetricsLendingIter<'_>) {
111111
iter += 1;
112112

113113
println!("Metric #{}", iter);
114-
println!("\t\tName : {}", &metric.name);
115-
println!("\t\tDescription : {}", &metric.description);
116-
println!("\t\tUnit : {}", &metric.unit);
114+
println!("\t\tName : {}", &metric.instrument.name);
115+
println!("\t\tDescription : {}", &metric.instrument.description);
116+
println!("\t\tUnit : {}", &metric.instrument.unit);
117117

118118
fn print_info<T>(data: &MetricData<T>)
119119
where

0 commit comments

Comments
 (0)