Skip to main content

reifydb_core/metrics/
sample.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4use std::borrow::Cow;
5
6use reifydb_value::{byte_size::ByteSize, count::Count, value::duration::Duration};
7
8#[derive(Clone, Debug, PartialEq)]
9pub struct MetricsSample {
10	pub scope: Cow<'static, str>,
11	pub metric: &'static str,
12	pub reading: Reading,
13	pub kind: MetricKind,
14}
15
16#[derive(Clone, Copy, Debug, PartialEq, Eq)]
17pub enum MetricKind {
18	Dimension,
19	Level,
20	Delta,
21	Counter,
22	Cumulative,
23	Distribution,
24}
25
26impl MetricKind {
27	pub fn name(&self) -> &'static str {
28		match self {
29			MetricKind::Dimension => "dimension",
30			MetricKind::Level => "level",
31			MetricKind::Delta => "delta",
32			MetricKind::Counter => "counter",
33			MetricKind::Cumulative => "cumulative",
34			MetricKind::Distribution => "distribution",
35		}
36	}
37}
38
39#[derive(Clone, Copy, Debug, PartialEq)]
40pub enum Reading {
41	Heap(ByteSize),
42	Bytes(ByteSize),
43	Count(Count),
44	Ratio(f64),
45	Version(u64),
46	Duration(Duration),
47}
48
49#[derive(Clone, Copy, Debug, PartialEq, Eq)]
50pub enum ReadingKind {
51	Bytes,
52	Count,
53	Ratio,
54	Duration,
55}
56
57impl ReadingKind {
58	pub fn reading(self, value: f64) -> Reading {
59		match self {
60			ReadingKind::Bytes => Reading::Bytes(ByteSize::from_bytes(value as u64)),
61			ReadingKind::Count => Reading::Count(Count::new(value as u64)),
62			ReadingKind::Ratio => Reading::Ratio(value),
63			ReadingKind::Duration => {
64				if !(0.0..=u64::MAX as f64).contains(&value) {
65					panic!("a duration reading of {value} microseconds is not representable");
66				}
67				Reading::Duration(Duration::from_micros_infallible(value as u64))
68			}
69		}
70	}
71}
72
73impl MetricsSample {
74	pub fn heap(scope: impl Into<Cow<'static, str>>, metric: &'static str, bytes: ByteSize) -> Self {
75		Self {
76			scope: scope.into(),
77			metric,
78			reading: Reading::Heap(bytes),
79			kind: MetricKind::Level,
80		}
81	}
82
83	pub fn bytes(scope: impl Into<Cow<'static, str>>, metric: &'static str, bytes: ByteSize) -> Self {
84		Self {
85			scope: scope.into(),
86			metric,
87			reading: Reading::Bytes(bytes),
88			kind: MetricKind::Level,
89		}
90	}
91
92	pub fn count(scope: impl Into<Cow<'static, str>>, metric: &'static str, count: u64) -> Self {
93		Self {
94			scope: scope.into(),
95			metric,
96			reading: Reading::Count(Count::new(count)),
97			kind: MetricKind::Level,
98		}
99	}
100
101	pub fn counter(scope: impl Into<Cow<'static, str>>, metric: &'static str, count: u64) -> Self {
102		Self {
103			scope: scope.into(),
104			metric,
105			reading: Reading::Count(Count::new(count)),
106			kind: MetricKind::Counter,
107		}
108	}
109
110	pub fn ratio(scope: impl Into<Cow<'static, str>>, metric: &'static str, ratio: f64) -> Self {
111		Self {
112			scope: scope.into(),
113			metric,
114			reading: Reading::Ratio(ratio),
115			kind: MetricKind::Level,
116		}
117	}
118
119	pub fn version(scope: impl Into<Cow<'static, str>>, metric: &'static str, version: u64) -> Self {
120		Self {
121			scope: scope.into(),
122			metric,
123			reading: Reading::Version(version),
124			kind: MetricKind::Level,
125		}
126	}
127
128	pub fn duration(scope: impl Into<Cow<'static, str>>, metric: &'static str, duration: Duration) -> Self {
129		Self {
130			scope: scope.into(),
131			metric,
132			reading: Reading::Duration(duration),
133			kind: MetricKind::Level,
134		}
135	}
136
137	pub fn level(scope: impl Into<Cow<'static, str>>, metric: &'static str, reading: Reading) -> Self {
138		Self {
139			scope: scope.into(),
140			metric,
141			reading,
142			kind: MetricKind::Level,
143		}
144	}
145
146	pub fn cumulative(scope: impl Into<Cow<'static, str>>, metric: &'static str, reading: Reading) -> Self {
147		Self {
148			scope: scope.into(),
149			metric,
150			reading,
151			kind: MetricKind::Counter,
152		}
153	}
154
155	pub fn distribution(scope: impl Into<Cow<'static, str>>, metric: &'static str, reading: Reading) -> Self {
156		Self {
157			scope: scope.into(),
158			metric,
159			reading,
160			kind: MetricKind::Distribution,
161		}
162	}
163}
164
165impl Reading {
166	pub fn as_f64(&self) -> f64 {
167		match self {
168			Reading::Heap(bytes) | Reading::Bytes(bytes) => bytes.as_bytes() as f64,
169			Reading::Count(count) => count.as_u64() as f64,
170			Reading::Ratio(ratio) => *ratio,
171			Reading::Version(version) => *version as f64,
172			Reading::Duration(duration) => duration.to_std().as_micros() as f64,
173		}
174	}
175
176	pub fn unit(&self) -> &'static str {
177		match self {
178			Reading::Heap(_) | Reading::Bytes(_) => "bytes",
179			Reading::Count(_) => "count",
180			Reading::Ratio(_) => "ratio",
181			Reading::Version(_) => "versions",
182			Reading::Duration(_) => "us",
183		}
184	}
185
186	pub fn heap_bytes(&self) -> Option<u64> {
187		match self {
188			Reading::Heap(bytes) => Some(bytes.as_bytes()),
189			_ => None,
190		}
191	}
192}