Skip to content

Commit 6573a02

Browse files
committed
fix: insert metric automatically if it does not exist
1 parent 4fc8fa1 commit 6573a02

File tree

1 file changed

+64
-8
lines changed

1 file changed

+64
-8
lines changed

packages/primitives/src/metrics/metric_collection.rs

Lines changed: 64 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use super::counter::Counter;
77
use super::gauge::Gauge;
88
use super::label_set::LabelSet;
99
use super::metric::Metric;
10+
use super::sample::Sample;
1011
use super::MetricName;
1112
use crate::metrics::sample_collection::SampleCollection;
1213
use crate::DurationSinceUnixEpoch;
@@ -42,7 +43,15 @@ impl MetricCollection {
4243
self.counters.get_value(name, labels)
4344
}
4445

46+
/// # Panics
47+
///
48+
/// Panics if a gauge with the same name already exists.
4549
pub fn increase_counter(&mut self, name: &MetricName, labels: &LabelSet, time: DurationSinceUnixEpoch) {
50+
assert!(
51+
!self.gauges.metrics.contains_key(name),
52+
"Cannot create counter with name '{name}': a gauge with this name already exists",
53+
);
54+
4655
self.counters.increment(name, labels, time);
4756
}
4857

@@ -53,7 +62,15 @@ impl MetricCollection {
5362
self.gauges.get_value(name, labels)
5463
}
5564

65+
/// # Panics
66+
///
67+
/// Panics if a counter with the same name already exists.
5668
pub fn set_gauge(&mut self, name: &MetricName, labels: &LabelSet, value: f64, time: DurationSinceUnixEpoch) {
69+
assert!(
70+
!self.counters.metrics.contains_key(name),
71+
"Cannot create gauge with name '{name}': a counter with this name already exists"
72+
);
73+
5774
self.gauges.set(name, labels, value, time);
5875
}
5976

@@ -182,13 +199,30 @@ impl<T> MetricKindCollection<T> {
182199
}
183200

184201
impl MetricKindCollection<Counter> {
202+
/// # Panics
203+
///
204+
/// Panics if the metric name already exists in the collection.
185205
pub fn increment(&mut self, name: &MetricName, labels: &LabelSet, time: DurationSinceUnixEpoch) {
186-
if let Some(metric) = self.metrics.get_mut(name) {
187-
if let Some(sample) = metric.samples.get_mut(labels) {
188-
sample.value.increment(1);
189-
sample.update_at = time;
190-
}
206+
// Create the metric if it doesn't exist
207+
if !self.metrics.contains_key(name) {
208+
let new_metric = Metric {
209+
name: name.clone(),
210+
samples: SampleCollection { samples: HashMap::new() },
211+
};
212+
self.metrics.insert(name.clone(), new_metric);
191213
}
214+
215+
let metric = self.metrics.get_mut(name).unwrap();
216+
217+
// Use entry API to handle existing or new sample
218+
let sample = metric.samples.samples.entry(labels.clone()).or_insert_with(|| Sample {
219+
value: Counter::new(0),
220+
update_at: time,
221+
labels: labels.clone(),
222+
});
223+
224+
sample.value.increment(1);
225+
sample.update_at = time;
192226
}
193227

194228
#[must_use]
@@ -201,13 +235,35 @@ impl MetricKindCollection<Counter> {
201235
}
202236

203237
impl MetricKindCollection<Gauge> {
238+
/// # Panics
239+
///
240+
/// Panics if the metric name already exists in the collection.
204241
pub fn set(&mut self, name: &MetricName, labels: &LabelSet, value: f64, time: DurationSinceUnixEpoch) {
205-
if let Some(metric) = self.metrics.get_mut(name) {
206-
// Direct hashmap lookup
207-
if let Some(sample) = metric.samples.get_mut(labels) {
242+
// Create the metric if it doesn't exist
243+
if !self.metrics.contains_key(name) {
244+
let new_metric = Metric {
245+
name: name.clone(),
246+
samples: SampleCollection { samples: HashMap::new() },
247+
};
248+
self.metrics.insert(name.clone(), new_metric);
249+
}
250+
251+
let metric = self.metrics.get_mut(name).unwrap();
252+
253+
// Use entry API to handle existing or new sample
254+
match metric.samples.samples.entry(labels.clone()) {
255+
std::collections::hash_map::Entry::Occupied(mut entry) => {
256+
let sample = entry.get_mut();
208257
sample.value.set(value);
209258
sample.update_at = time;
210259
}
260+
std::collections::hash_map::Entry::Vacant(entry) => {
261+
entry.insert(Sample {
262+
value: Gauge::new(value),
263+
update_at: time,
264+
labels: labels.clone(),
265+
});
266+
}
211267
}
212268
}
213269

0 commit comments

Comments
 (0)