chore(metrics): support and default to . separator (#1018)

This commit is contained in:
Roman Krasiuk
2023-01-24 22:03:06 +02:00
committed by GitHub
parent a1ad688c52
commit d2f92f630f
4 changed files with 29 additions and 19 deletions

View File

@ -13,6 +13,9 @@ use crate::{metric::Metric, with_attrs::WithAttrs};
static METRIC_NAME_RE: Lazy<Regex> = static METRIC_NAME_RE: Lazy<Regex> =
Lazy::new(|| Regex::new(r"^[a-zA-Z_:][a-zA-Z0-9_:]*$").unwrap()); Lazy::new(|| Regex::new(r"^[a-zA-Z_:][a-zA-Z0-9_:]*$").unwrap());
/// Supported metrics separators
const SUPPORTED_SEPARATORS: &[&str] = &[".", "_", ":"];
pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> { pub(crate) fn derive(node: &DeriveInput) -> Result<proc_macro2::TokenStream> {
let ty = &node.ident; let ty = &node.ident;
let vis = &node.vis; let vis = &node.vis;
@ -160,7 +163,7 @@ pub(crate) struct MetricsAttr {
} }
impl MetricsAttr { impl MetricsAttr {
const DEFAULT_SEPARATOR: &str = "_"; const DEFAULT_SEPARATOR: &str = ".";
fn separator(&self) -> String { fn separator(&self) -> String {
match &self.separator { match &self.separator {
@ -193,10 +196,17 @@ fn parse_metrics_attr(node: &DeriveInput) -> Result<MetricsAttr> {
return Err(Error::new_spanned(kv, "Duplicate `separator` value provided.")) return Err(Error::new_spanned(kv, "Duplicate `separator` value provided."))
} }
let separator_lit = parse_str_lit(&kv.lit)?; let separator_lit = parse_str_lit(&kv.lit)?;
if separator_lit.value() != ":" && separator_lit.value() != "_" { if !SUPPORTED_SEPARATORS.contains(&&*separator_lit.value()) {
return Err(Error::new_spanned( return Err(Error::new_spanned(
kv, kv,
"Unsupported `separator` value. Supported: `:` and `_`.", format!(
"Unsupported `separator` value. Supported: {}.",
SUPPORTED_SEPARATORS
.iter()
.map(|sep| format!("`{sep}`"))
.collect::<Vec<_>>()
.join(", ")
),
)) ))
} }
separator = Some(separator_lit); separator = Some(separator_lit);

View File

@ -40,7 +40,7 @@ struct CustomMetrics8;
struct CustomMetrics9; struct CustomMetrics9;
#[derive(Metrics)] #[derive(Metrics)]
#[metrics(separator = ".")] #[metrics(separator = "x")]
struct CustomMetrics10; struct CustomMetrics10;
#[derive(Metrics)] #[derive(Metrics)]

View File

@ -53,10 +53,10 @@ error: Value **must** be a string literal.
39 | #[metrics(separator = 123)] 39 | #[metrics(separator = 123)]
| ^^^ | ^^^
error: Unsupported `separator` value. Supported: `:` and `_`. error: Unsupported `separator` value. Supported: `.`, `_`, `:`.
--> tests/compile-fail/metrics_attr.rs:43:11 --> tests/compile-fail/metrics_attr.rs:43:11
| |
43 | #[metrics(separator = ".")] 43 | #[metrics(separator = "x")]
| ^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^
error: Duplicate `separator` value provided. error: Duplicate `separator` value provided.

View File

@ -43,7 +43,7 @@ static RECORDER: Lazy<TestRecorder> = Lazy::new(TestRecorder::new);
fn test_describe(scope: &str) { fn test_describe(scope: &str) {
assert_eq!(RECORDER.metrics_len(), 4); assert_eq!(RECORDER.metrics_len(), 4);
let gauge = RECORDER.get_metric(&format!("{scope}_gauge")); let gauge = RECORDER.get_metric(&format!("{scope}.gauge"));
assert!(gauge.is_some()); assert!(gauge.is_some());
assert_eq!( assert_eq!(
gauge.unwrap(), gauge.unwrap(),
@ -54,7 +54,7 @@ fn test_describe(scope: &str) {
} }
); );
let second_gauge = RECORDER.get_metric(&format!("{scope}_second_gauge")); let second_gauge = RECORDER.get_metric(&format!("{scope}.second_gauge"));
assert!(second_gauge.is_some()); assert!(second_gauge.is_some());
assert_eq!( assert_eq!(
second_gauge.unwrap(), second_gauge.unwrap(),
@ -65,7 +65,7 @@ fn test_describe(scope: &str) {
} }
); );
let counter = RECORDER.get_metric(&format!("{scope}_counter")); let counter = RECORDER.get_metric(&format!("{scope}.counter"));
assert!(counter.is_some()); assert!(counter.is_some());
assert_eq!( assert_eq!(
counter.unwrap(), counter.unwrap(),
@ -78,7 +78,7 @@ fn test_describe(scope: &str) {
} }
); );
let histogram = RECORDER.get_metric(&format!("{scope}_histogram")); let histogram = RECORDER.get_metric(&format!("{scope}.histogram"));
assert!(histogram.is_some()); assert!(histogram.is_some());
assert_eq!( assert_eq!(
histogram.unwrap(), histogram.unwrap(),
@ -119,28 +119,28 @@ fn describe_dynamic_metrics() {
fn test_register(scope: &str) { fn test_register(scope: &str) {
assert_eq!(RECORDER.metrics_len(), 4); assert_eq!(RECORDER.metrics_len(), 4);
let gauge = RECORDER.get_metric(&format!("{scope}_gauge")); let gauge = RECORDER.get_metric(&format!("{scope}.gauge"));
assert!(gauge.is_some()); assert!(gauge.is_some());
assert_eq!( assert_eq!(
gauge.unwrap(), gauge.unwrap(),
TestMetric { ty: TestMetricTy::Gauge, description: None, labels: None } TestMetric { ty: TestMetricTy::Gauge, description: None, labels: None }
); );
let second_gauge = RECORDER.get_metric(&format!("{scope}_second_gauge")); let second_gauge = RECORDER.get_metric(&format!("{scope}.second_gauge"));
assert!(second_gauge.is_some()); assert!(second_gauge.is_some());
assert_eq!( assert_eq!(
second_gauge.unwrap(), second_gauge.unwrap(),
TestMetric { ty: TestMetricTy::Gauge, description: None, labels: None } TestMetric { ty: TestMetricTy::Gauge, description: None, labels: None }
); );
let counter = RECORDER.get_metric(&format!("{scope}_counter")); let counter = RECORDER.get_metric(&format!("{scope}.counter"));
assert!(counter.is_some()); assert!(counter.is_some());
assert_eq!( assert_eq!(
counter.unwrap(), counter.unwrap(),
TestMetric { ty: TestMetricTy::Counter, description: None, labels: None } TestMetric { ty: TestMetricTy::Counter, description: None, labels: None }
); );
let histogram = RECORDER.get_metric(&format!("{scope}_histogram")); let histogram = RECORDER.get_metric(&format!("{scope}.histogram"));
assert!(histogram.is_some()); assert!(histogram.is_some());
assert_eq!( assert_eq!(
histogram.unwrap(), histogram.unwrap(),
@ -177,25 +177,25 @@ fn register_dynamic_metrics() {
fn test_labels(scope: &str) { fn test_labels(scope: &str) {
let test_labels = vec![Label::new("key", "value")]; let test_labels = vec![Label::new("key", "value")];
let gauge = RECORDER.get_metric(&format!("{scope}_gauge")); let gauge = RECORDER.get_metric(&format!("{scope}.gauge"));
assert!(gauge.is_some()); assert!(gauge.is_some());
let labels = gauge.unwrap().labels; let labels = gauge.unwrap().labels;
assert!(labels.is_some()); assert!(labels.is_some());
assert_eq!(labels.unwrap(), test_labels.clone(),); assert_eq!(labels.unwrap(), test_labels.clone(),);
let second_gauge = RECORDER.get_metric(&format!("{scope}_second_gauge")); let second_gauge = RECORDER.get_metric(&format!("{scope}.second_gauge"));
assert!(second_gauge.is_some()); assert!(second_gauge.is_some());
let labels = second_gauge.unwrap().labels; let labels = second_gauge.unwrap().labels;
assert!(labels.is_some()); assert!(labels.is_some());
assert_eq!(labels.unwrap(), test_labels.clone(),); assert_eq!(labels.unwrap(), test_labels.clone());
let counter = RECORDER.get_metric(&format!("{scope}_counter")); let counter = RECORDER.get_metric(&format!("{scope}.counter"));
assert!(counter.is_some()); assert!(counter.is_some());
let labels = counter.unwrap().labels; let labels = counter.unwrap().labels;
assert!(labels.is_some()); assert!(labels.is_some());
assert_eq!(labels.unwrap(), test_labels.clone(),); assert_eq!(labels.unwrap(), test_labels.clone(),);
let histogram = RECORDER.get_metric(&format!("{scope}_histogram")); let histogram = RECORDER.get_metric(&format!("{scope}.histogram"));
assert!(histogram.is_some()); assert!(histogram.is_some());
let labels = histogram.unwrap().labels; let labels = histogram.unwrap().labels;
assert!(labels.is_some()); assert!(labels.is_some());