Skip to content

Commit 2f855f0

Browse files
committed
feat(metrics/family): add get method to Family
Signed-off-by: Wenbo Zhang <wenbo.zhang@iomesh.com>
1 parent ad05f0f commit 2f855f0

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

src/metrics/family.rs

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,23 @@ impl<S: Clone + std::hash::Hash + Eq, M, C: MetricConstructor<M>> Family<S, M, C
247247
})
248248
}
249249

250+
/// Access a metric with the given label set, returning None if one
251+
/// does not yet exist.
252+
///
253+
/// ```
254+
/// # use prometheus_client::metrics::counter::{Atomic, Counter};
255+
/// # use prometheus_client::metrics::family::Family;
256+
/// #
257+
/// let family = Family::<Vec<(String, String)>, Counter>::default();
258+
///
259+
/// if let Some(metric) = family.get(&vec![("method".to_owned(), "GET".to_owned())]) {
260+
/// metric.inc();
261+
/// };
262+
/// ```
263+
pub fn get(&self, label_set: &S) -> Option<MappedRwLockReadGuard<M>> {
264+
RwLockReadGuard::try_map(self.metrics.read(), |metrics| metrics.get(label_set)).ok()
265+
}
266+
250267
/// Remove a label set from the metric family.
251268
///
252269
/// Returns a bool indicating if a label set was removed or not.
@@ -452,4 +469,47 @@ mod tests {
452469
.get()
453470
);
454471
}
472+
473+
#[test]
474+
fn test_get() {
475+
let family = Family::<Vec<(String, String)>, Counter>::default();
476+
477+
// Test getting a non-existent metric
478+
let non_existent = family.get(&vec![("method".to_string(), "GET".to_string())]);
479+
assert!(non_existent.is_none());
480+
481+
// Create a metric
482+
family
483+
.get_or_create(&vec![("method".to_string(), "GET".to_string())])
484+
.inc();
485+
486+
// Test getting an existing metric
487+
let existing = family.get(&vec![("method".to_string(), "GET".to_string())]);
488+
assert!(existing.is_some());
489+
assert_eq!(existing.unwrap().get(), 1);
490+
491+
// Test getting a different non-existent metric
492+
let another_non_existent = family.get(&vec![("method".to_string(), "POST".to_string())]);
493+
assert!(another_non_existent.is_none());
494+
495+
// Test modifying the metric through the returned reference
496+
if let Some(metric) = family.get(&vec![("method".to_string(), "GET".to_string())]) {
497+
metric.inc();
498+
}
499+
500+
// Verify the modification
501+
let modified = family.get(&vec![("method".to_string(), "GET".to_string())]);
502+
assert_eq!(modified.unwrap().get(), 2);
503+
504+
// Test with a different label set type
505+
let string_family = Family::<String, Counter>::default();
506+
string_family.get_or_create(&"test".to_string()).inc();
507+
508+
let string_metric = string_family.get(&"test".to_string());
509+
assert!(string_metric.is_some());
510+
assert_eq!(string_metric.unwrap().get(), 1);
511+
512+
let non_existent_string = string_family.get(&"non_existent".to_string());
513+
assert!(non_existent_string.is_none());
514+
}
455515
}

0 commit comments

Comments
 (0)