From 2b735e8b6ef0e03a322625a05fe51f8c419a6275 Mon Sep 17 00:00:00 2001 From: John Howard Date: Mon, 12 Dec 2022 15:12:01 -0800 Subject: [PATCH 1/6] Introduce attribute for derive Signed-off-by: John Howard --- derive-encode/src/lib.rs | 45 ++++++++++++++++++++++++-------------- derive-encode/tests/lib.rs | 38 ++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 16 deletions(-) diff --git a/derive-encode/src/lib.rs b/derive-encode/src/lib.rs index 381c5bf7..2ed3f062 100644 --- a/derive-encode/src/lib.rs +++ b/derive-encode/src/lib.rs @@ -12,7 +12,7 @@ use quote::quote; use syn::DeriveInput; /// Derive `prometheus_client::encoding::EncodeLabelSet`. -#[proc_macro_derive(EncodeLabelSet)] +#[proc_macro_derive(EncodeLabelSet, attributes(prometheus))] pub fn derive_encode_label_set(input: TokenStream) -> TokenStream { let ast: DeriveInput = syn::parse(input).unwrap(); let name = &ast.ident; @@ -22,22 +22,35 @@ pub fn derive_encode_label_set(input: TokenStream) -> TokenStream { syn::Fields::Named(syn::FieldsNamed { named, .. }) => named .into_iter() .map(|f| { - let ident = f.ident.unwrap(); - let ident_string = KEYWORD_IDENTIFIERS + let flatten = f + .attrs .iter() - .find(|pair| ident == pair.1) - .map(|pair| pair.0.to_string()) - .unwrap_or_else(|| ident.to_string()); - - quote! { - let mut label_encoder = encoder.encode_label(); - let mut label_key_encoder = label_encoder.encode_label_key()?; - EncodeLabelKey::encode(&#ident_string, &mut label_key_encoder)?; - - let mut label_value_encoder = label_key_encoder.encode_label_value()?; - EncodeLabelValue::encode(&self.#ident, &mut label_value_encoder)?; - - label_value_encoder.finish()?; + .find(|a| a.path.is_ident("prometheus")) + .map(|a| a.parse_args::().unwrap().to_string() == "flatten") + .unwrap_or(false); + if flatten { + let ident = f.ident.unwrap(); + quote! { + self.#ident.encode(encoder)?; + } + } else { + let ident = f.ident.unwrap(); + let ident_string = KEYWORD_IDENTIFIERS + .iter() + .find(|pair| ident == pair.1) + .map(|pair| pair.0.to_string()) + .unwrap_or_else(|| ident.to_string()); + + quote! { + let mut label_encoder = encoder.encode_label(); + let mut label_key_encoder = label_encoder.encode_label_key()?; + EncodeLabelKey::encode(&#ident_string, &mut label_key_encoder)?; + + let mut label_value_encoder = label_key_encoder.encode_label_value()?; + EncodeLabelValue::encode(&self.#ident, &mut label_value_encoder)?; + + label_value_encoder.finish()?; + } } }) .collect(), diff --git a/derive-encode/tests/lib.rs b/derive-encode/tests/lib.rs index 446af0ba..8cd4df7a 100644 --- a/derive-encode/tests/lib.rs +++ b/derive-encode/tests/lib.rs @@ -136,3 +136,41 @@ fn remap_keyword_identifiers() { + "# EOF\n"; assert_eq!(expected, buffer); } + +#[test] +fn flatten() { + #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] + struct CommonLabels { + a: u64, + b: u64, + } + #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] + struct Labels { + unique: u64, + #[prometheus(flatten)] + common: CommonLabels, + } + + let mut registry = Registry::default(); + let family = Family::::default(); + registry.register("my_counter", "This is my counter", family.clone()); + + // Record a single HTTP GET request. + family.get_or_create(&Labels { + unique: 1, + common: CommonLabels{ + a: 2, + b: 3, + }, + }).inc(); + + // Encode all metrics in the registry in the text format. + let mut buffer = String::new(); + encode(&mut buffer, ®istry).unwrap(); + + let expected = "# HELP my_counter This is my counter.\n".to_owned() + + "# TYPE my_counter counter\n" + + "my_counter_total{unique=\"1\",a=\"2\",b=\"3\"} 1\n" + + "# EOF\n"; + assert_eq!(expected, buffer); +} From 82fb2b309aa4a07bf1eb5a1bfc8a2ef0f631b6ee Mon Sep 17 00:00:00 2001 From: John Howard Date: Tue, 3 Jan 2023 11:44:01 -0800 Subject: [PATCH 2/6] Address comments Signed-off-by: John Howard --- derive-encode/src/lib.rs | 17 +++++++++++------ derive-encode/tests/lib.rs | 13 ++++++------- 2 files changed, 17 insertions(+), 13 deletions(-) diff --git a/derive-encode/src/lib.rs b/derive-encode/src/lib.rs index 2ed3f062..e126889e 100644 --- a/derive-encode/src/lib.rs +++ b/derive-encode/src/lib.rs @@ -22,19 +22,24 @@ pub fn derive_encode_label_set(input: TokenStream) -> TokenStream { syn::Fields::Named(syn::FieldsNamed { named, .. }) => named .into_iter() .map(|f| { - let flatten = f + let attribute = f .attrs .iter() .find(|a| a.path.is_ident("prometheus")) - .map(|a| a.parse_args::().unwrap().to_string() == "flatten") - .unwrap_or(false); + .map(|a| a.parse_args::().unwrap().to_string()); + let flatten = match attribute.as_deref() { + Some("flatten") => true, + Some(other) => { + panic!("Provided attribute '{other}', but only 'flatten' is supported") + } + None => false, + }; + let ident = f.ident.unwrap(); if flatten { - let ident = f.ident.unwrap(); quote! { - self.#ident.encode(encoder)?; + EncodeLabelSet::encode(&self.#ident, encoder)?; } } else { - let ident = f.ident.unwrap(); let ident_string = KEYWORD_IDENTIFIERS .iter() .find(|pair| ident == pair.1) diff --git a/derive-encode/tests/lib.rs b/derive-encode/tests/lib.rs index 8cd4df7a..fba8412d 100644 --- a/derive-encode/tests/lib.rs +++ b/derive-encode/tests/lib.rs @@ -156,13 +156,12 @@ fn flatten() { registry.register("my_counter", "This is my counter", family.clone()); // Record a single HTTP GET request. - family.get_or_create(&Labels { - unique: 1, - common: CommonLabels{ - a: 2, - b: 3, - }, - }).inc(); + family + .get_or_create(&Labels { + unique: 1, + common: CommonLabels { a: 2, b: 3 }, + }) + .inc(); // Encode all metrics in the registry in the text format. let mut buffer = String::new(); From 563459a19c2b44c5462a5bc9478fc6bffb6c4237 Mon Sep 17 00:00:00 2001 From: John Howard Date: Tue, 3 Jan 2023 12:39:59 -0800 Subject: [PATCH 3/6] Add changelog Signed-off-by: John Howard --- CHANGELOG.md | 3 +++ derive-encode/Cargo.toml | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index edf54b0c..45b5a414 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,8 +10,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Introduce `Collector` abstraction allowing users to provide additional metrics and their description on each scrape. See [PR 82]. +- Introduce a `#[prometheus(flatten)]` attribute which can be used when deriving `EncodeLabelSet`, allowing + a nested struct the be flattened during encoding. See [PR 118]. [PR 82]: https://github.com/prometheus/client_rust/pull/82 +[PR 118]: https://github.com/prometheus/client_rust/pull/118 ## [0.19.0] diff --git a/derive-encode/Cargo.toml b/derive-encode/Cargo.toml index 61559910..e24e1933 100644 --- a/derive-encode/Cargo.toml +++ b/derive-encode/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "prometheus-client-derive-encode" -version = "0.4.0" +version = "0.4.1" authors = ["Max Inden "] edition = "2021" description = "Auxiliary crate to derive Encode trait from prometheus-client." From f49e40ad8ab3f21c2d3dbc257ac19a7feb6cc001 Mon Sep 17 00:00:00 2001 From: John Howard Date: Wed, 4 Jan 2023 09:33:05 -0800 Subject: [PATCH 4/6] ADd changelog example Signed-off-by: John Howard --- CHANGELOG.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 45b5a414..fcc12b8c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,7 +11,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Introduce `Collector` abstraction allowing users to provide additional metrics and their description on each scrape. See [PR 82]. - Introduce a `#[prometheus(flatten)]` attribute which can be used when deriving `EncodeLabelSet`, allowing - a nested struct the be flattened during encoding. See [PR 118]. + a nested struct to be flattened during encoding. See [PR 118]. + For example: + ```rust + #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] + struct CommonLabels { + a: u64, + b: u64, + } + #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] + struct Labels { + unique: u64, + #[prometheus(flatten)] + common: CommonLabels, + } + + // Would result in `my_metric{a="42",b="42",unique="42"} 42 + ``` [PR 82]: https://github.com/prometheus/client_rust/pull/82 [PR 118]: https://github.com/prometheus/client_rust/pull/118 From 3fe8c7f20af3058206f33aa87d0c9b4e3803480c Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Jan 2023 19:07:36 +0100 Subject: [PATCH 5/6] Cargo.toml: Bump derive version Signed-off-by: Max Inden --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index e93ffe5b..9d4cf941 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ members = ["derive-encode"] dtoa = "1.0" itoa = "1.0" parking_lot = "0.12" -prometheus-client-derive-encode = { version = "0.4.0", path = "derive-encode" } +prometheus-client-derive-encode = { version = "0.4.1", path = "derive-encode" } prost = { version = "0.11.0", optional = true } prost-types = { version = "0.11.0", optional = true } From e5e7f9b689b1cd4ad205bb8b8c12f27a9077df7d Mon Sep 17 00:00:00 2001 From: Max Inden Date: Wed, 4 Jan 2023 19:09:23 +0100 Subject: [PATCH 6/6] CHANGELOG: Small rephrasing Signed-off-by: Max Inden --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fcc12b8c..be05900d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,9 +10,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Introduce `Collector` abstraction allowing users to provide additional metrics and their description on each scrape. See [PR 82]. + - Introduce a `#[prometheus(flatten)]` attribute which can be used when deriving `EncodeLabelSet`, allowing a nested struct to be flattened during encoding. See [PR 118]. + For example: + ```rust #[derive(EncodeLabelSet, Hash, Clone, Eq, PartialEq, Debug)] struct CommonLabels { @@ -25,8 +28,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 #[prometheus(flatten)] common: CommonLabels, } + ``` + + Would be encoded as: - // Would result in `my_metric{a="42",b="42",unique="42"} 42 + ``` + my_metric{a="42",b="42",unique="42"} 42 ``` [PR 82]: https://github.com/prometheus/client_rust/pull/82