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