diff --git a/Cargo.lock b/Cargo.lock index 352771e71c..f860e6c144 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5257,7 +5257,9 @@ checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" name = "infra_utils" version = "0.0.0" dependencies = [ + "num-traits 0.2.19", "pretty_assertions", + "regex", "rstest", "tokio", "tracing", diff --git a/crates/infra_utils/Cargo.toml b/crates/infra_utils/Cargo.toml index c4cb9be5c9..4f086f55a0 100644 --- a/crates/infra_utils/Cargo.toml +++ b/crates/infra_utils/Cargo.toml @@ -10,6 +10,8 @@ description = "Infrastructure utility." workspace = true [dependencies] +num-traits.workspace = true +regex.workspace = true tokio = { workspace = true, features = ["process", "time"] } tracing.workspace = true diff --git a/crates/infra_utils/src/lib.rs b/crates/infra_utils/src/lib.rs index 129c5be816..2a6f8ed8e6 100644 --- a/crates/infra_utils/src/lib.rs +++ b/crates/infra_utils/src/lib.rs @@ -1,4 +1,5 @@ pub mod command; +pub mod metrics; pub mod path; pub mod run_until; pub mod tracing; diff --git a/crates/infra_utils/src/metrics.rs b/crates/infra_utils/src/metrics.rs new file mode 100644 index 0000000000..38a114979c --- /dev/null +++ b/crates/infra_utils/src/metrics.rs @@ -0,0 +1,41 @@ +use std::str::FromStr; + +use num_traits::Num; +use regex::{escape, Regex}; + +/// Parses a specific numeric metric value from a metrics string. +/// +/// # Arguments +/// +/// - `metrics_as_string`: A string containing the renders metrics data. +/// - `metric_name`: The name of the metric to search for. +/// +/// # Type Parameters +/// +/// - `T`: The numeric type to which the metric value will be parsed. The type must implement the +/// `Num` and `FromStr` traits, allowing it to represent numeric values and be parsed from a +/// string. Common types include `i32`, `u64`, and `f64`. +/// +/// # Returns +/// +/// - `Option`: Returns `Some(T)` if the metric is found and successfully parsed into the +/// specified numeric type `T`. Returns `None` if the metric is not found or if parsing fails. +pub fn parse_numeric_metric( + metrics_as_string: &str, + metric_name: &str, +) -> Option { + // Create a regex to match "metric_name ". + let pattern = format!(r"{}\s+(\d+)", escape(metric_name)); + let re = Regex::new(&pattern).expect("Invalid regex"); + + // Search for the pattern in the output. + if let Some(captures) = re.captures(metrics_as_string) { + // Extract the numeric value. + if let Some(value) = captures.get(1) { + // Parse the string into a number. + return value.as_str().parse().ok(); + } + } + // If no match is found, return None. + None +}