1use 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}