opentelemetry_sdk/metrics/data/mod.rs
1//! Types for delivery of pre-aggregated metric time series data.
2
3use std::{any, borrow::Cow, fmt, time::SystemTime};
4
5use opentelemetry::KeyValue;
6
7use crate::{instrumentation::Scope, Resource};
8
9pub use self::temporality::Temporality;
10
11mod temporality;
12
13/// A collection of [ScopeMetrics] and the associated [Resource] that created them.
14#[derive(Debug)]
15pub struct ResourceMetrics {
16 /// The entity that collected the metrics.
17 pub resource: Resource,
18 /// The collection of metrics with unique [Scope]s.
19 pub scope_metrics: Vec<ScopeMetrics>,
20}
21
22/// A collection of metrics produced by a meter.
23#[derive(Default, Debug)]
24pub struct ScopeMetrics {
25 /// The [Scope] that the meter was created with.
26 pub scope: Scope,
27 /// The list of aggregations created by the meter.
28 pub metrics: Vec<Metric>,
29}
30
31/// A collection of one or more aggregated time series from an [Instrument].
32///
33/// [Instrument]: crate::metrics::Instrument
34#[derive(Debug)]
35pub struct Metric {
36 /// The name of the instrument that created this data.
37 pub name: Cow<'static, str>,
38 /// The description of the instrument, which can be used in documentation.
39 pub description: Cow<'static, str>,
40 /// The unit in which the instrument reports.
41 pub unit: Cow<'static, str>,
42 /// The aggregated data from an instrument.
43 pub data: Box<dyn Aggregation>,
44}
45
46/// The store of data reported by an [Instrument].
47///
48/// It will be one of: [Gauge], [Sum], or [Histogram].
49///
50/// [Instrument]: crate::metrics::Instrument
51pub trait Aggregation: fmt::Debug + any::Any + Send + Sync {
52 /// Support downcasting
53 fn as_any(&self) -> &dyn any::Any;
54 /// Support downcasting during aggregation
55 fn as_mut(&mut self) -> &mut dyn any::Any;
56}
57
58/// A measurement of the current value of an instrument.
59#[derive(Debug)]
60pub struct Gauge<T> {
61 /// Represents individual aggregated measurements with unique attributes.
62 pub data_points: Vec<DataPoint<T>>,
63}
64
65impl<T: fmt::Debug + Send + Sync + 'static> Aggregation for Gauge<T> {
66 fn as_any(&self) -> &dyn any::Any {
67 self
68 }
69 fn as_mut(&mut self) -> &mut dyn any::Any {
70 self
71 }
72}
73
74/// Represents the sum of all measurements of values from an instrument.
75#[derive(Debug)]
76pub struct Sum<T> {
77 /// Represents individual aggregated measurements with unique attributes.
78 pub data_points: Vec<DataPoint<T>>,
79 /// Describes if the aggregation is reported as the change from the last report
80 /// time, or the cumulative changes since a fixed start time.
81 pub temporality: Temporality,
82 /// Whether this aggregation only increases or decreases.
83 pub is_monotonic: bool,
84}
85
86impl<T: fmt::Debug + Send + Sync + 'static> Aggregation for Sum<T> {
87 fn as_any(&self) -> &dyn any::Any {
88 self
89 }
90 fn as_mut(&mut self) -> &mut dyn any::Any {
91 self
92 }
93}
94
95/// DataPoint is a single data point in a time series.
96#[derive(Debug)]
97pub struct DataPoint<T> {
98 /// Attributes is the set of key value pairs that uniquely identify the
99 /// time series.
100 pub attributes: Vec<KeyValue>,
101 /// The time when the time series was started.
102 pub start_time: Option<SystemTime>,
103 /// The time when the time series was recorded.
104 pub time: Option<SystemTime>,
105 /// The value of this data point.
106 pub value: T,
107 /// The sampled [Exemplar]s collected during the time series.
108 pub exemplars: Vec<Exemplar<T>>,
109}
110
111impl<T: Copy> Clone for DataPoint<T> {
112 fn clone(&self) -> Self {
113 Self {
114 attributes: self.attributes.clone(),
115 start_time: self.start_time,
116 time: self.time,
117 value: self.value,
118 exemplars: self.exemplars.clone(),
119 }
120 }
121}
122
123/// Represents the histogram of all measurements of values from an instrument.
124#[derive(Debug)]
125pub struct Histogram<T> {
126 /// Individual aggregated measurements with unique attributes.
127 pub data_points: Vec<HistogramDataPoint<T>>,
128 /// Describes if the aggregation is reported as the change from the last report
129 /// time, or the cumulative changes since a fixed start time.
130 pub temporality: Temporality,
131}
132
133impl<T: fmt::Debug + Send + Sync + 'static> Aggregation for Histogram<T> {
134 fn as_any(&self) -> &dyn any::Any {
135 self
136 }
137 fn as_mut(&mut self) -> &mut dyn any::Any {
138 self
139 }
140}
141
142/// A single histogram data point in a time series.
143#[derive(Debug)]
144pub struct HistogramDataPoint<T> {
145 /// The set of key value pairs that uniquely identify the time series.
146 pub attributes: Vec<KeyValue>,
147 /// The time when the time series was started.
148 pub start_time: SystemTime,
149 /// The time when the time series was recorded.
150 pub time: SystemTime,
151
152 /// The number of updates this histogram has been calculated with.
153 pub count: u64,
154 /// The upper bounds of the buckets of the histogram.
155 ///
156 /// Because the last boundary is +infinity this one is implied.
157 pub bounds: Vec<f64>,
158 /// The count of each of the buckets.
159 pub bucket_counts: Vec<u64>,
160
161 /// The minimum value recorded.
162 pub min: Option<T>,
163 /// The maximum value recorded.
164 pub max: Option<T>,
165 /// The sum of the values recorded.
166 pub sum: T,
167
168 /// The sampled [Exemplar]s collected during the time series.
169 pub exemplars: Vec<Exemplar<T>>,
170}
171
172impl<T: Copy> Clone for HistogramDataPoint<T> {
173 fn clone(&self) -> Self {
174 Self {
175 attributes: self.attributes.clone(),
176 start_time: self.start_time,
177 time: self.time,
178 count: self.count,
179 bounds: self.bounds.clone(),
180 bucket_counts: self.bucket_counts.clone(),
181 min: self.min,
182 max: self.max,
183 sum: self.sum,
184 exemplars: self.exemplars.clone(),
185 }
186 }
187}
188
189/// The histogram of all measurements of values from an instrument.
190#[derive(Debug)]
191pub struct ExponentialHistogram<T> {
192 /// The individual aggregated measurements with unique attributes.
193 pub data_points: Vec<ExponentialHistogramDataPoint<T>>,
194
195 /// Describes if the aggregation is reported as the change from the last report
196 /// time, or the cumulative changes since a fixed start time.
197 pub temporality: Temporality,
198}
199
200impl<T: fmt::Debug + Send + Sync + 'static> Aggregation for ExponentialHistogram<T> {
201 fn as_any(&self) -> &dyn any::Any {
202 self
203 }
204 fn as_mut(&mut self) -> &mut dyn any::Any {
205 self
206 }
207}
208
209/// A single exponential histogram data point in a time series.
210#[derive(Debug)]
211pub struct ExponentialHistogramDataPoint<T> {
212 /// The set of key value pairs that uniquely identify the time series.
213 pub attributes: Vec<KeyValue>,
214 /// When the time series was started.
215 pub start_time: SystemTime,
216 /// The time when the time series was recorded.
217 pub time: SystemTime,
218
219 /// The number of updates this histogram has been calculated with.
220 pub count: usize,
221 /// The minimum value recorded.
222 pub min: Option<T>,
223 /// The maximum value recorded.
224 pub max: Option<T>,
225 /// The sum of the values recorded.
226 pub sum: T,
227
228 /// Describes the resolution of the histogram.
229 ///
230 /// Boundaries are located at powers of the base, where:
231 ///
232 /// base = 2 ^ (2 ^ -scale)
233 pub scale: i8,
234
235 /// The number of values whose absolute value is less than or equal to
236 /// `zero_threshold`.
237 ///
238 /// When `zero_threshold` is `0`, this is the number of values that cannot be
239 /// expressed using the standard exponential formula as well as values that have
240 /// been rounded to zero.
241 pub zero_count: u64,
242
243 /// The range of positive value bucket counts.
244 pub positive_bucket: ExponentialBucket,
245 /// The range of negative value bucket counts.
246 pub negative_bucket: ExponentialBucket,
247
248 /// The width of the zero region.
249 ///
250 /// Where the zero region is defined as the closed interval
251 /// [-zero_threshold, zero_threshold].
252 pub zero_threshold: f64,
253
254 /// The sampled exemplars collected during the time series.
255 pub exemplars: Vec<Exemplar<T>>,
256}
257
258/// A set of bucket counts, encoded in a contiguous array of counts.
259#[derive(Debug, PartialEq)]
260pub struct ExponentialBucket {
261 /// The bucket index of the first entry in the `counts` vec.
262 pub offset: i32,
263
264 /// A vec where `counts[i]` carries the count of the bucket at index `offset + i`.
265 ///
266 /// `counts[i]` is the count of values greater than base^(offset+i) and less than
267 /// or equal to base^(offset+i+1).
268 pub counts: Vec<u64>,
269}
270
271/// A measurement sampled from a time series providing a typical example.
272#[derive(Debug)]
273pub struct Exemplar<T> {
274 /// The attributes recorded with the measurement but filtered out of the
275 /// time series' aggregated data.
276 pub filtered_attributes: Vec<KeyValue>,
277 /// The time when the measurement was recorded.
278 pub time: SystemTime,
279 /// The measured value.
280 pub value: T,
281 /// The ID of the span that was active during the measurement.
282 ///
283 /// If no span was active or the span was not sampled this will be empty.
284 pub span_id: [u8; 8],
285 /// The ID of the trace the active span belonged to during the measurement.
286 ///
287 /// If no span was active or the span was not sampled this will be empty.
288 pub trace_id: [u8; 16],
289}
290
291impl<T: Copy> Clone for Exemplar<T> {
292 fn clone(&self) -> Self {
293 Self {
294 filtered_attributes: self.filtered_attributes.clone(),
295 time: self.time,
296 value: self.value,
297 span_id: self.span_id,
298 trace_id: self.trace_id,
299 }
300 }
301}