From cdd36e4b18a522702e4c1c7ec8443e5279098256 Mon Sep 17 00:00:00 2001 From: Jan Michael Auer Date: Mon, 11 Dec 2023 19:30:04 +0100 Subject: [PATCH] fix: Move statsd parsing to metrics module --- sentry-core/src/cadence.rs | 37 +--------------------------- sentry-core/src/metrics.rs | 50 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 36 deletions(-) diff --git a/sentry-core/src/cadence.rs b/sentry-core/src/cadence.rs index 07742d96..0cf89cf0 100644 --- a/sentry-core/src/cadence.rs +++ b/sentry-core/src/cadence.rs @@ -31,7 +31,7 @@ where S: MetricSink, { fn emit(&self, string: &str) -> std::io::Result { - if let Some(metric) = parse_metric(string) { + if let Ok(metric) = Metric::parse_statsd(string) { self.client.add_metric(metric); } @@ -50,41 +50,6 @@ where } } -fn parse_metric(string: &str) -> Option { - let mut components = string.split('|'); - - let (mri_str, value_str) = components.next()?.split_once(':')?; - let (name, unit) = match mri_str.split_once('@') { - Some((name, unit_str)) => (name, unit_str.parse().ok()?), - None => (mri_str, MetricUnit::None), - }; - - let ty = components.next().and_then(|s| s.parse().ok())?; - let value = match ty { - MetricType::Counter => MetricValue::Counter(value_str.parse().ok()?), - MetricType::Distribution => MetricValue::Distribution(value_str.parse().ok()?), - MetricType::Set => MetricValue::Set(value_str.parse().ok()?), - MetricType::Gauge => MetricValue::Gauge(value_str.parse().ok()?), - }; - - let mut builder = Metric::build(name.to_owned(), value).with_unit(unit); - - for component in components { - if let Some('#') = component.chars().next() { - for pair in component.get(1..)?.split(',') { - let mut key_value = pair.splitn(2, ':'); - - let key = key_value.next()?.to_owned(); - let value = key_value.next().unwrap_or_default().to_owned(); - - builder = builder.with_tag(key, value); - } - } - } - - Some(builder.finish()) -} - #[cfg(test)] mod tests { use cadence::{Counted, Distributed}; diff --git a/sentry-core/src/metrics.rs b/sentry-core/src/metrics.rs index 3949c13d..1875613f 100644 --- a/sentry-core/src/metrics.rs +++ b/sentry-core/src/metrics.rs @@ -299,6 +299,10 @@ impl Metric { MetricBuilder { metric } } + pub fn parse_statsd(string: &str) -> Result { + parse_metric_opt(string).ok_or(ParseMetricError(())) + } + pub fn incr(name: impl Into) -> MetricBuilder { Self::build(name, MetricValue::Counter(1.0)) } @@ -353,6 +357,52 @@ impl MetricBuilder { } } +#[derive(Debug)] +pub struct ParseMetricError(()); + +impl std::error::Error for ParseMetricError {} + +impl fmt::Display for ParseMetricError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str("invalid metric string") + } +} + +fn parse_metric_opt(string: &str) -> Option { + let mut components = string.split('|'); + + let (mri_str, value_str) = components.next()?.split_once(':')?; + let (name, unit) = match mri_str.split_once('@') { + Some((name, unit_str)) => (name, unit_str.parse().ok()?), + None => (mri_str, MetricUnit::None), + }; + + let ty = components.next().and_then(|s| s.parse().ok())?; + let value = match ty { + MetricType::Counter => MetricValue::Counter(value_str.parse().ok()?), + MetricType::Distribution => MetricValue::Distribution(value_str.parse().ok()?), + MetricType::Set => MetricValue::Set(value_str.parse().ok()?), + MetricType::Gauge => MetricValue::Gauge(value_str.parse().ok()?), + }; + + let mut builder = Metric::build(name.to_owned(), value).with_unit(unit); + + for component in components { + if let Some('#') = component.chars().next() { + for pair in component.get(1..)?.split(',') { + let mut key_value = pair.splitn(2, ':'); + + let key = key_value.next()?.to_owned(); + let value = key_value.next().unwrap_or_default().to_owned(); + + builder = builder.with_tag(key, value); + } + } + } + + Some(builder.finish()) +} + pub struct MetricAggregator { inner: Arc>, handle: Option>,