Skip to content

Commit 93c63db

Browse files
authored
feat(metrics/family): add get method to Family (#234)
Signed-off-by: Wenbo Zhang <[email protected]>
1 parent 7413b61 commit 93c63db

File tree

2 files changed

+65
-3
lines changed

2 files changed

+65
-3
lines changed

Diff for: CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3434
- Supoort `Arc<String>` for `EncodeLabelValue`.
3535
See [PR 217].
3636

37+
- Added `get` method to `Family`.
38+
See [PR 234].
39+
3740
[PR 173]: https://github.com/prometheus/client_rust/pull/173
3841
[PR 216]: https://github.com/prometheus/client_rust/pull/216
3942
[PR 217]: https://github.com/prometheus/client_rust/pull/217
43+
[PR 234]: https://github.com/prometheus/client_rust/pull/234
4044

4145
### Fixed
4246

Diff for: src/metrics/family.rs

+61-3
Original file line numberDiff line numberDiff line change
@@ -226,9 +226,7 @@ impl<S: Clone + std::hash::Hash + Eq, M, C: MetricConstructor<M>> Family<S, M, C
226226
/// family.get_or_create(&vec![("method".to_owned(), "GET".to_owned())]).inc();
227227
/// ```
228228
pub fn get_or_create(&self, label_set: &S) -> MappedRwLockReadGuard<M> {
229-
if let Ok(metric) =
230-
RwLockReadGuard::try_map(self.metrics.read(), |metrics| metrics.get(label_set))
231-
{
229+
if let Some(metric) = self.get(label_set) {
232230
return metric;
233231
}
234232

@@ -247,6 +245,23 @@ impl<S: Clone + std::hash::Hash + Eq, M, C: MetricConstructor<M>> Family<S, M, C
247245
})
248246
}
249247

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

0 commit comments

Comments
 (0)