From 4c1d8bc70c0e9679a5179d03c9c509beaaa8b335 Mon Sep 17 00:00:00 2001 From: Wenbo Zhang Date: Mon, 28 Oct 2024 20:52:40 +0800 Subject: [PATCH 1/2] feat(metrics/family): add `get` method to Family Signed-off-by: Wenbo Zhang --- src/metrics/family.rs | 60 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/metrics/family.rs b/src/metrics/family.rs index 2f23b198..5e2c4e53 100644 --- a/src/metrics/family.rs +++ b/src/metrics/family.rs @@ -247,6 +247,23 @@ impl> Family, Counter>::default(); + /// + /// if let Some(metric) = family.get(&vec![("method".to_owned(), "GET".to_owned())]) { + /// metric.inc(); + /// }; + /// ``` + pub fn get(&self, label_set: &S) -> Option> { + RwLockReadGuard::try_map(self.metrics.read(), |metrics| metrics.get(label_set)).ok() + } + /// Remove a label set from the metric family. /// /// Returns a bool indicating if a label set was removed or not. @@ -452,4 +469,47 @@ mod tests { .get() ); } + + #[test] + fn test_get() { + let family = Family::, Counter>::default(); + + // Test getting a non-existent metric + let non_existent = family.get(&vec![("method".to_string(), "GET".to_string())]); + assert!(non_existent.is_none()); + + // Create a metric + family + .get_or_create(&vec![("method".to_string(), "GET".to_string())]) + .inc(); + + // Test getting an existing metric + let existing = family.get(&vec![("method".to_string(), "GET".to_string())]); + assert!(existing.is_some()); + assert_eq!(existing.unwrap().get(), 1); + + // Test getting a different non-existent metric + let another_non_existent = family.get(&vec![("method".to_string(), "POST".to_string())]); + assert!(another_non_existent.is_none()); + + // Test modifying the metric through the returned reference + if let Some(metric) = family.get(&vec![("method".to_string(), "GET".to_string())]) { + metric.inc(); + } + + // Verify the modification + let modified = family.get(&vec![("method".to_string(), "GET".to_string())]); + assert_eq!(modified.unwrap().get(), 2); + + // Test with a different label set type + let string_family = Family::::default(); + string_family.get_or_create(&"test".to_string()).inc(); + + let string_metric = string_family.get(&"test".to_string()); + assert!(string_metric.is_some()); + assert_eq!(string_metric.unwrap().get(), 1); + + let non_existent_string = string_family.get(&"non_existent".to_string()); + assert!(non_existent_string.is_none()); + } } From cf500d6a4142f7c7cd47530027a7f6ff77b07bd4 Mon Sep 17 00:00:00 2001 From: Wenbo Zhang Date: Tue, 3 Dec 2024 12:17:58 +0800 Subject: [PATCH 2/2] refactor codes and add a changelog entry Signed-off-by: Wenbo Zhang --- CHANGELOG.md | 4 ++++ src/metrics/family.rs | 18 ++++++++---------- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 945d128f..685c8b66 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,9 +34,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Supoort `Arc` for `EncodeLabelValue`. See [PR 217]. +- Added `get` method to `Family`. + See [PR 234]. + [PR 173]: https://github.com/prometheus/client_rust/pull/173 [PR 216]: https://github.com/prometheus/client_rust/pull/216 [PR 217]: https://github.com/prometheus/client_rust/pull/217 +[PR 234]: https://github.com/prometheus/client_rust/pull/234 ### Fixed diff --git a/src/metrics/family.rs b/src/metrics/family.rs index 5e2c4e53..1a76cf8f 100644 --- a/src/metrics/family.rs +++ b/src/metrics/family.rs @@ -226,9 +226,7 @@ impl> Family MappedRwLockReadGuard { - if let Ok(metric) = - RwLockReadGuard::try_map(self.metrics.read(), |metrics| metrics.get(label_set)) - { + if let Some(metric) = self.get(label_set) { return metric; } @@ -474,34 +472,34 @@ mod tests { fn test_get() { let family = Family::, Counter>::default(); - // Test getting a non-existent metric + // Test getting a non-existent metric. let non_existent = family.get(&vec![("method".to_string(), "GET".to_string())]); assert!(non_existent.is_none()); - // Create a metric + // Create a metric. family .get_or_create(&vec![("method".to_string(), "GET".to_string())]) .inc(); - // Test getting an existing metric + // Test getting an existing metric. let existing = family.get(&vec![("method".to_string(), "GET".to_string())]); assert!(existing.is_some()); assert_eq!(existing.unwrap().get(), 1); - // Test getting a different non-existent metric + // Test getting a different non-existent metric. let another_non_existent = family.get(&vec![("method".to_string(), "POST".to_string())]); assert!(another_non_existent.is_none()); - // Test modifying the metric through the returned reference + // Test modifying the metric through the returned reference. if let Some(metric) = family.get(&vec![("method".to_string(), "GET".to_string())]) { metric.inc(); } - // Verify the modification + // Verify the modification. let modified = family.get(&vec![("method".to_string(), "GET".to_string())]); assert_eq!(modified.unwrap().get(), 2); - // Test with a different label set type + // Test with a different label set type. let string_family = Family::::default(); string_family.get_or_create(&"test".to_string()).inc();