From 635245f77529ffd6cf5f373f5b9e06914f2af03e Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Fri, 25 Aug 2023 01:10:44 +0100 Subject: [PATCH 01/24] replace `register_counter` attempt --- metrics-macros/src/lib.rs | 8 --- metrics/src/lib.rs | 46 +---------------- metrics/src/macros.rs | 104 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 53 deletions(-) create mode 100644 metrics/src/macros.rs diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 7d84926e..7d5946be 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -138,14 +138,6 @@ pub fn describe_histogram(input: TokenStream) -> TokenStream { get_describe_code("histogram", key, unit, description).into() } -#[proc_macro] -pub fn register_counter(input: TokenStream) -> TokenStream { - let WithoutExpression { target, level, key, labels } = - parse_macro_input!(input as WithoutExpression); - - get_register_and_op_code::(target, level, "counter", key, labels, None).into() -} - #[proc_macro] pub fn register_gauge(input: TokenStream) -> TokenStream { let WithoutExpression { target, level, key, labels } = diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 9d23df7c..a4fd3655 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -257,6 +257,7 @@ pub mod atomics; mod common; +mod macros; pub use self::common::*; mod cow; @@ -378,51 +379,6 @@ pub use metrics_macros::describe_gauge; /// ``` pub use metrics_macros::describe_histogram; -/// Registers a counter. -/// -/// Counters represent a single monotonic value, which means the value can only be incremented, not -/// decremented, and always starts out with an initial value of zero. -/// -/// Metrics can be registered, which provides a handle to directly update that metric. For -/// counters, [`Counter`] is provided which can be incremented or set to an absolute value. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::register_counter; -/// # fn main() { -/// // A basic counter: -/// let counter = register_counter!("some_metric_name"); -/// counter.increment(1); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// let counter = register_counter!("some_metric_name", "service" => "http"); -/// counter.absolute(42); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// let counter = register_counter!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); -/// counter.increment(123); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, -/// // a unit or description can still be passed in their respective positions: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// let counter = register_counter!("some_metric_name", &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// let counter = register_counter!(name); -/// -/// let counter = register_counter!(format!("{}_via_format", "name")); -/// # } -/// ``` -pub use metrics_macros::register_counter; - /// Registers a gauge. /// /// Gauges represent a single value that can go up or down over time, and always starts out with an diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs new file mode 100644 index 00000000..06e592df --- /dev/null +++ b/metrics/src/macros.rs @@ -0,0 +1,104 @@ +#[doc(hidden)] +#[macro_export] +macro_rules! metadata_var { + ($target:expr, $level:expr) => {{ + static METADATA: ::metrics::Metadata<'static> = + ::metrics::Metadata::new($target, $level, Some(module_path!())); + &METADATA + }}; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! default_target { + () => { + module_path!() + }; + ($target:expr) => { + $target + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! default_level { + () => { + $crate::Level::INFO + }; + ($level:expr) => { + $level + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! count { + () => { + 0usize + }; + ($head:tt $($tail:tt)*) => { + 1usize + $crate::count! { $($tail)* } + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! key_var { + ($name: literal) => { + static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_name($name); + &METRIC_KEY + }; + ($name:expr) => { + ::metrics::Key::from_static_name(&$name) + }; + ($name:literal, $($label_key:literal => $label_value:literal),*) => {{ + static LABELS: [::metrics::Label; $crate::count! { $($label_key)* }] = [ + $(::metrics::Label::from_static_parts(&$label_key, &$label_value)),* + ]; + static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_parts($name, &LABELS); + &METRIC_KEY + }}; + ($name:expr, $($label_key:literal => $label_value:literal),*) => {{ + static LABELS: [::metrics::Label; $crate::count! { $($label_key)* }] = [ + $(::metrics::Label::from_static_parts($label_key, $label_value)),* + ]; + let metric_key = ::metrics::Key::from_static_parts(&$name, &LABELS); + metric_key + }}; + ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ + let labels: [::metrics::Label; $crate::count! { $($label_key)* }] = [ + $(::metrics::Label::from_static_parts($label_key, $label_value)),* + ]; + ::metrics::Key::from_static_parts(&$name, &labels) + }}; + ($name:expr, $labels:expr) => { + ::metrics::Key::from_parts(&$name, $labels) + } +} + +/// TODO +#[macro_export] +macro_rules! register_counter { + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr => $label_value:expr)* $(,)?) => { + { + let metric_key = $crate::key_var! { $name, $($label_key => $label_value),* }; + let metadata = $crate::metadata_var! { + $crate::default_target! { $($target)? }, + $crate::default_level! { $($level)? } + }; + + ::metrics::recorder().register_counter(&metric_key, metadata) + } + }; + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $labels:expr)? $(,)?) => { + { + let metric_key = $crate::key_var! { $name, $($labels)? }; + let metadata = $crate::metadata_var! { + $crate::default_target! { $($target)? }, + $crate::default_level! { $($level)? } + }; + + ::metrics::recorder().register_counter(&metric_key, metadata) + } + }; +} From c356678f3bd0bab76ad6932a951374ca5a1e484d Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 17:32:33 +0100 Subject: [PATCH 02/24] address comments --- metrics/src/macros.rs | 58 +++++++++++++++++++++---------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 06e592df..e6a75bd7 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -2,8 +2,8 @@ #[macro_export] macro_rules! metadata_var { ($target:expr, $level:expr) => {{ - static METADATA: ::metrics::Metadata<'static> = - ::metrics::Metadata::new($target, $level, Some(module_path!())); + static METADATA: $crate::Metadata<'static> = + $crate::Metadata::new($target, $level, Some(module_path!())); &METADATA }}; } @@ -37,42 +37,42 @@ macro_rules! count { 0usize }; ($head:tt $($tail:tt)*) => { - 1usize + $crate::count! { $($tail)* } + 1usize + $crate::count!($($tail)*) }; } #[doc(hidden)] #[macro_export] macro_rules! key_var { - ($name: literal) => { - static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_name($name); + ($name: literal) => {{ + static METRIC_KEY: $crate::Key = $crate::Key::from_static_name($name); &METRIC_KEY - }; + }}; ($name:expr) => { - ::metrics::Key::from_static_name(&$name) + $crate::Key::from_static_name(&$name) }; ($name:literal, $($label_key:literal => $label_value:literal),*) => {{ - static LABELS: [::metrics::Label; $crate::count! { $($label_key)* }] = [ - $(::metrics::Label::from_static_parts(&$label_key, &$label_value)),* + static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ + $($crate::Label::from_static_parts(&$label_key, &$label_value)),* ]; - static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_parts($name, &LABELS); + static METRIC_KEY: $crate::Key = $crate::Key::from_static_parts($name, &LABELS); &METRIC_KEY }}; ($name:expr, $($label_key:literal => $label_value:literal),*) => {{ - static LABELS: [::metrics::Label; $crate::count! { $($label_key)* }] = [ - $(::metrics::Label::from_static_parts($label_key, $label_value)),* + static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ + $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - let metric_key = ::metrics::Key::from_static_parts(&$name, &LABELS); + let metric_key = $crate::Key::from_static_parts(&$name, &LABELS); metric_key }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ - let labels: [::metrics::Label; $crate::count! { $($label_key)* }] = [ - $(::metrics::Label::from_static_parts($label_key, $label_value)),* + let labels: [$crate::Label; $crate::count!($($label_key)*)] = [ + $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - ::metrics::Key::from_static_parts(&$name, &labels) + $crate::Key::from_static_parts(&$name, &labels) }}; ($name:expr, $labels:expr) => { - ::metrics::Key::from_parts(&$name, $labels) + $crate::Key::from_parts(&$name, $labels) } } @@ -81,24 +81,24 @@ macro_rules! key_var { macro_rules! register_counter { ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr => $label_value:expr)* $(,)?) => { { - let metric_key = $crate::key_var! { $name, $($label_key => $label_value),* }; - let metadata = $crate::metadata_var! { - $crate::default_target! { $($target)? }, - $crate::default_level! { $($level)? } - }; + let metric_key = $crate::key_var!($name, $($label_key => $label_value),*); + let metadata = $crate::metadata_var!( + $crate::default_target!($($target)?), + $crate::default_level!($($level)?) + ); - ::metrics::recorder().register_counter(&metric_key, metadata) + $crate::recorder().register_counter(&metric_key, metadata) } }; ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $labels:expr)? $(,)?) => { { - let metric_key = $crate::key_var! { $name, $($labels)? }; - let metadata = $crate::metadata_var! { - $crate::default_target! { $($target)? }, - $crate::default_level! { $($level)? } - }; + let metric_key = $crate::key_var!($name, $($labels)?); + let metadata = $crate::metadata_var!( + $crate::default_target!($($target)?), + $crate::default_level!($($level)?) + ); - ::metrics::recorder().register_counter(&metric_key, metadata) + $crate::recorder().register_counter(&metric_key, metadata) } }; } From b64e2f09af570958ccf45d9f54656e60970b7777 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 22:40:40 +0100 Subject: [PATCH 03/24] fix macro tests --- metrics/src/macros.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index e6a75bd7..c509cb9e 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -49,7 +49,7 @@ macro_rules! key_var { &METRIC_KEY }}; ($name:expr) => { - $crate::Key::from_static_name(&$name) + $crate::Key::from_name($name) }; ($name:literal, $($label_key:literal => $label_value:literal),*) => {{ static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ @@ -62,17 +62,16 @@ macro_rules! key_var { static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - let metric_key = $crate::Key::from_static_parts(&$name, &LABELS); - metric_key + $crate::Key::from_parts($name, LABELS.into_iter()) }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ let labels: [$crate::Label; $crate::count!($($label_key)*)] = [ $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - $crate::Key::from_static_parts(&$name, &labels) + $crate::Key::from_parts($name, labels.into_iter()) }}; ($name:expr, $labels:expr) => { - $crate::Key::from_parts(&$name, $labels) + $crate::Key::from_parts($name, $labels) } } From a0341ce68a75f7256620a15791bdba2cdef1c935 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 22:56:54 +0100 Subject: [PATCH 04/24] use `from_static_labels` when possible --- metrics/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index c509cb9e..fab3eb1f 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -62,7 +62,7 @@ macro_rules! key_var { static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - $crate::Key::from_parts($name, LABELS.into_iter()) + $crate::Key::from_static_labels($name, &LABELS) }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ let labels: [$crate::Label; $crate::count!($($label_key)*)] = [ From 5e82f3e41e5ad2034f03359286d2e1a01eb775cf Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 23:03:15 +0100 Subject: [PATCH 05/24] simplify `Key::from_parts` usage --- metrics/src/macros.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index fab3eb1f..a1f456d9 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -65,10 +65,10 @@ macro_rules! key_var { $crate::Key::from_static_labels($name, &LABELS) }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ - let labels: [$crate::Label; $crate::count!($($label_key)*)] = [ + let labels = vec![ $($crate::Label::from_static_parts($label_key, $label_value)),* ]; - $crate::Key::from_parts($name, labels.into_iter()) + $crate::Key::from_parts($name, labels) }}; ($name:expr, $labels:expr) => { $crate::Key::from_parts($name, $labels) From 4e1918da17014510c059d37c7d245e99154dfac5 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 23:11:05 +0100 Subject: [PATCH 06/24] replace `describe_counter` --- metrics-macros/src/lib.rs | 7 ------- metrics/src/lib.rs | 34 ---------------------------------- metrics/src/macros.rs | 23 +++++++++++++++++++++++ 3 files changed, 23 insertions(+), 41 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 7d5946be..d0aba4ed 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -117,13 +117,6 @@ impl Parse for Description { } } -#[proc_macro] -pub fn describe_counter(input: TokenStream) -> TokenStream { - let Description { key, unit, description } = parse_macro_input!(input as Description); - - get_describe_code("counter", key, unit, description).into() -} - #[proc_macro] pub fn describe_gauge(input: TokenStream) -> TokenStream { let Description { key, unit, description } = parse_macro_input!(input as Description); diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index a4fd3655..52af125a 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -277,40 +277,6 @@ pub use self::metadata::*; mod recorder; pub use self::recorder::*; -/// Describes a counter. -/// -/// Counters represent a single monotonic value, which means the value can only be incremented, not -/// decremented, and always starts out with an initial value of zero. -/// -/// Metrics can be described with a free-form string, and optionally, a unit can be provided to -/// describe the value and/or rate of the metric measurements. Whether or not the installed -/// recorder does anything with the description, or optional unit, is implementation defined. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::describe_counter; -/// # use metrics::Unit; -/// # fn main() { -/// // A basic counter: -/// describe_counter!("some_metric_name", "my favorite counter"); -/// -/// // Providing a unit for a counter: -/// describe_counter!("some_metric_name", Unit::Bytes, "my favorite counter"); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// describe_counter!(name, "my favorite counter"); -/// -/// describe_counter!(format!("{}_via_format", "name"), "my favorite counter"); -/// # } -/// ``` -pub use metrics_macros::describe_counter; - /// Describes a gauge. /// /// Gauges represent a single value that can go up or down over time, and always starts out with an diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index a1f456d9..ccd00297 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -101,3 +101,26 @@ macro_rules! register_counter { } }; } + +/// TODO +#[macro_export] +macro_rules! describe_counter { + ($name:expr, $unit:expr, $description:expr) => {{ + if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { + recorder.describe_counter( + $name.into(), + ::core::option::Option::Some($unit), + $description.into(), + ) + } + }}; + ($name:expr, $description:expr) => {{ + if let Some(recorder) = $crate::try_recorder() { + recorder.describe_counter( + $name.into(), + ::core::option::Option::None, + $description.into(), + ) + } + }}; +} From fbbe72ab00124210813a08cf1944fa89f55bf798 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Thu, 31 Aug 2023 23:36:53 +0100 Subject: [PATCH 07/24] simplify `register_counter` --- metrics/src/macros.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index ccd00297..73f31924 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -78,20 +78,9 @@ macro_rules! key_var { /// TODO #[macro_export] macro_rules! register_counter { - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr => $label_value:expr)* $(,)?) => { + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { { - let metric_key = $crate::key_var!($name, $($label_key => $label_value),*); - let metadata = $crate::metadata_var!( - $crate::default_target!($($target)?), - $crate::default_level!($($level)?) - ); - - $crate::recorder().register_counter(&metric_key, metadata) - } - }; - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $labels:expr)? $(,)?) => { - { - let metric_key = $crate::key_var!($name, $($labels)?); + let metric_key = $crate::key_var!($name, $($label_key $(=> $label_value)?),*); let metadata = $crate::metadata_var!( $crate::default_target!($($target)?), $crate::default_level!($($level)?) From d34515f7dbe457161b0b9b8f1626bcc26cf0520f Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 11:01:20 +0100 Subject: [PATCH 08/24] use `Label::new` on `$label_*:expr` --- metrics/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 73f31924..6e3da0e8 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -66,7 +66,7 @@ macro_rules! key_var { }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ let labels = vec![ - $($crate::Label::from_static_parts($label_key, $label_value)),* + $($crate::Label::new($label_key, $label_value)),* ]; $crate::Key::from_parts($name, labels) }}; From 4c3ce8e2c787ab408580212032f9f7cc67a19f91 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 11:07:13 +0100 Subject: [PATCH 09/24] replace `counter` --- metrics-macros/src/lib.rs | 9 --------- metrics/src/lib.rs | 41 --------------------------------------- metrics/src/macros.rs | 9 +++++++++ 3 files changed, 9 insertions(+), 50 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index d0aba4ed..2fdc953d 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -158,15 +158,6 @@ pub fn increment_counter(input: TokenStream) -> TokenStream { .into() } -#[proc_macro] -pub fn counter(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "counter", key, labels, Some(("increment", op_value))) - .into() -} - #[proc_macro] pub fn absolute_counter(input: TokenStream) -> TokenStream { let WithExpression { target, level, key, op_value, labels } = diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 52af125a..038a11b8 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -434,47 +434,6 @@ pub use metrics_macros::register_gauge; /// ``` pub use metrics_macros::register_histogram; -/// Increments a counter. -/// -/// Counters represent a single monotonic value, which means the value can only be incremented, not -/// decremented, and always starts out with an initial value of zero. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{counter, Level}; -/// # fn main() { -/// // A basic counter: -/// counter!("some_metric_name", 12); -/// -/// // A basic counter with level and target specified: -/// counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 12); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// counter!("some_metric_name", 12, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// counter!("some_metric_name", 12, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// counter!("some_metric_name", 12, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// counter!(name, 12); -/// -/// counter!(format!("{}_via_format", "name"), 12); -/// # } -/// ``` -pub use metrics_macros::counter; - /// Increments a counter by one. /// /// Counters represent a single monotonic value, which means the value can only be incremented, not diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 6e3da0e8..71d22209 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -113,3 +113,12 @@ macro_rules! describe_counter { } }}; } + +/// TODO +#[macro_export] +macro_rules! counter { + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + let handle = $crate::register_counter!($(target: $target,)? $(level: $level,)? $name $(, $label_key $(=> $label_value)?)*); + handle.increment($op_val); + }}; +} From 8be5fea91c783827acc4993daf3e644d2b9a46d4 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 11:12:06 +0100 Subject: [PATCH 10/24] replace `absolute_counter` --- metrics-macros/src/lib.rs | 9 -------- metrics/src/lib.rs | 48 --------------------------------------- metrics/src/macros.rs | 9 ++++++++ 3 files changed, 9 insertions(+), 57 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 2fdc953d..588e96f8 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -158,15 +158,6 @@ pub fn increment_counter(input: TokenStream) -> TokenStream { .into() } -#[proc_macro] -pub fn absolute_counter(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "counter", key, labels, Some(("absolute", op_value))) - .into() -} - #[proc_macro] pub fn increment_gauge(input: TokenStream) -> TokenStream { let WithExpression { target, level, key, op_value, labels } = diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 038a11b8..5d5a3540 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -475,54 +475,6 @@ pub use metrics_macros::register_histogram; /// ``` pub use metrics_macros::increment_counter; -/// Sets a counter to an absolute value. -/// -/// Counters represent a single monotonic value, which means the value can only be incremented, not -/// decremented, and will always start out with an initial value of zero. -/// -/// Using this macro, users can specify an absolute value for the counter instead of the typical -/// delta. This can be useful when dealing with forwarding metrics from an external system into the -/// normal application metrics, without having to track the delta of the metrics from the external -/// system. Users should beware, though, that implementations will enforce the monotonicity -/// property of counters by refusing to update the value unless it is greater than current value of -/// the counter. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{absolute_counter, Level}; -/// # fn main() { -/// // A basic counter: -/// absolute_counter!("some_metric_name", 12); -/// -/// // A basic counter with level and target specified: -/// absolute_counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 12); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// absolute_counter!("some_metric_name", 13, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// absolute_counter!("some_metric_name", 13, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// absolute_counter!("some_metric_name", 14, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// absolute_counter!(name, 15); -/// -/// absolute_counter!(format!("{}_via_format", "name"), 16); -/// # } -/// ``` -pub use metrics_macros::absolute_counter; - /// Updates a gauge. /// /// Gauges represent a single value that can go up or down over time, and always starts out with an diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 71d22209..2f3fc02e 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -122,3 +122,12 @@ macro_rules! counter { handle.increment($op_val); }}; } + +/// TODO +#[macro_export] +macro_rules! absolute_counter { + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + let handle = $crate::register_counter!($(target: $target,)? $(level: $level,)? $name $(, $label_key $(=> $label_value)?)*); + handle.absolute($op_val); + }}; +} From 724e78c83a6560c2a43cab3520d3d40f2e9b4a23 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 11:16:55 +0100 Subject: [PATCH 11/24] replace `increment_counter` --- metrics-macros/src/lib.rs | 11 ----------- metrics/src/lib.rs | 41 --------------------------------------- metrics/src/macros.rs | 8 ++++++++ 3 files changed, 8 insertions(+), 52 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 588e96f8..1fa00a0d 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -147,17 +147,6 @@ pub fn register_histogram(input: TokenStream) -> TokenStream { get_register_and_op_code::(target, level, "histogram", key, labels, None).into() } -#[proc_macro] -pub fn increment_counter(input: TokenStream) -> TokenStream { - let WithoutExpression { target, level, key, labels } = - parse_macro_input!(input as WithoutExpression); - - let op_value = quote! { 1 }; - - get_register_and_op_code(target, level, "counter", key, labels, Some(("increment", op_value))) - .into() -} - #[proc_macro] pub fn increment_gauge(input: TokenStream) -> TokenStream { let WithExpression { target, level, key, op_value, labels } = diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 5d5a3540..a6363881 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -434,47 +434,6 @@ pub use metrics_macros::register_gauge; /// ``` pub use metrics_macros::register_histogram; -/// Increments a counter by one. -/// -/// Counters represent a single monotonic value, which means the value can only be incremented, not -/// decremented, and always starts out with an initial value of zero. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{increment_counter, Level}; -/// # fn main() { -/// // A basic increment: -/// increment_counter!("some_metric_name"); -/// -/// // A basic increment with level and target specified: -/// increment_counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name"); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// increment_counter!("some_metric_name", "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// increment_counter!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// increment_counter!("some_metric_name", &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// increment_counter!(name); -/// -/// increment_counter!(format!("{}_via_format", "name")); -/// # } -/// ``` -pub use metrics_macros::increment_counter; - /// Updates a gauge. /// /// Gauges represent a single value that can go up or down over time, and always starts out with an diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 2f3fc02e..c8cae993 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -131,3 +131,11 @@ macro_rules! absolute_counter { handle.absolute($op_val); }}; } + +/// TODO +#[macro_export] +macro_rules! increment_counter { + ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + $crate::counter!($(target: $target,)? $(level: $level,)? $name, 1 $(, $label_key $(=> $label_value)?)*); + }}; +} From 8ad6a7030c00880741a7bd826818e6597315b161 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 22:26:51 +0100 Subject: [PATCH 12/24] restore documentation --- metrics/src/macros.rs | 204 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 199 insertions(+), 5 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index c8cae993..76071a02 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -75,7 +75,49 @@ macro_rules! key_var { } } -/// TODO +/// Registers a counter. +/// +/// Counters represent a single monotonic value, which means the value can only be incremented, not +/// decremented, and always starts out with an initial value of zero. +/// +/// Metrics can be registered, which provides a handle to directly update that metric. For +/// counters, [`Counter`] is provided which can be incremented or set to an absolute value. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::register_counter; +/// # fn main() { +/// // A basic counter: +/// let counter = register_counter!("some_metric_name"); +/// counter.increment(1); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// let counter = register_counter!("some_metric_name", "service" => "http"); +/// counter.absolute(42); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// let counter = register_counter!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); +/// counter.increment(123); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, +/// // a unit or description can still be passed in their respective positions: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// let counter = register_counter!("some_metric_name", &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// let counter = register_counter!(name); +/// +/// let counter = register_counter!(format!("{}_via_format", "name")); +/// # } +/// ``` #[macro_export] macro_rules! register_counter { ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -91,7 +133,38 @@ macro_rules! register_counter { }; } -/// TODO +/// Describes a counter. +/// +/// Counters represent a single monotonic value, which means the value can only be incremented, not +/// decremented, and always starts out with an initial value of zero. +/// +/// Metrics can be described with a free-form string, and optionally, a unit can be provided to +/// describe the value and/or rate of the metric measurements. Whether or not the installed +/// recorder does anything with the description, or optional unit, is implementation defined. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::describe_counter; +/// # use metrics::Unit; +/// # fn main() { +/// // A basic counter: +/// describe_counter!("some_metric_name", "my favorite counter"); +/// +/// // Providing a unit for a counter: +/// describe_counter!("some_metric_name", Unit::Bytes, "my favorite counter"); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// describe_counter!(name, "my favorite counter"); +/// +/// describe_counter!(format!("{}_via_format", "name"), "my favorite counter"); +/// # } +/// ``` #[macro_export] macro_rules! describe_counter { ($name:expr, $unit:expr, $description:expr) => {{ @@ -114,7 +187,45 @@ macro_rules! describe_counter { }}; } -/// TODO +/// Increments a counter. +/// +/// Counters represent a single monotonic value, which means the value can only be incremented, not +/// decremented, and always starts out with an initial value of zero. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{counter, Level}; +/// # fn main() { +/// // A basic counter: +/// counter!("some_metric_name", 12); +/// +/// // A basic counter with level and target specified: +/// counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 12); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// counter!("some_metric_name", 12, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// counter!("some_metric_name", 12, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// counter!("some_metric_name", 12, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// counter!(name, 12); +/// +/// counter!(format!("{}_via_format", "name"), 12); +/// # } +/// ``` #[macro_export] macro_rules! counter { ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ @@ -123,7 +234,52 @@ macro_rules! counter { }}; } -/// TODO +/// Sets a counter to an absolute value. +/// +/// Counters represent a single monotonic value, which means the value can only be incremented, not +/// decremented, and will always start out with an initial value of zero. +/// +/// Using this macro, users can specify an absolute value for the counter instead of the typical +/// delta. This can be useful when dealing with forwarding metrics from an external system into the +/// normal application metrics, without having to track the delta of the metrics from the external +/// system. Users should beware, though, that implementations will enforce the monotonicity +/// property of counters by refusing to update the value unless it is greater than current value of +/// the counter. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{absolute_counter, Level}; +/// # fn main() { +/// // A basic counter: +/// absolute_counter!("some_metric_name", 12); +/// +/// // A basic counter with level and target specified: +/// absolute_counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 12); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// absolute_counter!("some_metric_name", 13, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// absolute_counter!("some_metric_name", 13, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// absolute_counter!("some_metric_name", 14, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// absolute_counter!(name, 15); +/// +/// absolute_counter!(format!("{}_via_format", "name"), 16); +/// # } +/// ``` #[macro_export] macro_rules! absolute_counter { ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ @@ -132,7 +288,45 @@ macro_rules! absolute_counter { }}; } -/// TODO +/// Increments a counter. +/// +/// Counters represent a single monotonic value, which means the value can only be incremented, not +/// decremented, and always starts out with an initial value of zero. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{counter, Level}; +/// # fn main() { +/// // A basic counter: +/// counter!("some_metric_name", 12); +/// +/// // A basic counter with level and target specified: +/// counter!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 12); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// counter!("some_metric_name", 12, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// counter!("some_metric_name", 12, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// counter!("some_metric_name", 12, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// counter!(name, 12); +/// +/// counter!(format!("{}_via_format", "name"), 12); +/// # } +/// ``` #[macro_export] macro_rules! increment_counter { ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ From 0a32d83394342889f0a5bdb8192b3d2c3216186d Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sat, 2 Sep 2023 23:00:11 +0100 Subject: [PATCH 13/24] fix doc tests --- metrics/src/macros.rs | 93 ++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 36 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 76071a02..e8f60f70 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -8,28 +8,6 @@ macro_rules! metadata_var { }}; } -#[doc(hidden)] -#[macro_export] -macro_rules! default_target { - () => { - module_path!() - }; - ($target:expr) => { - $target - }; -} - -#[doc(hidden)] -#[macro_export] -macro_rules! default_level { - () => { - $crate::Level::INFO - }; - ($level:expr) => { - $level - }; -} - #[doc(hidden)] #[macro_export] macro_rules! count { @@ -120,17 +98,23 @@ macro_rules! key_var { /// ``` #[macro_export] macro_rules! register_counter { - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { { let metric_key = $crate::key_var!($name, $($label_key $(=> $label_value)?),*); - let metadata = $crate::metadata_var!( - $crate::default_target!($($target)?), - $crate::default_level!($($level)?) - ); + let metadata = $crate::metadata_var!($target, $level); $crate::recorder().register_counter(&metric_key, metadata) } }; + (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_counter!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + }; + ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_counter!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + }; } /// Describes a counter. @@ -228,10 +212,22 @@ macro_rules! describe_counter { /// ``` #[macro_export] macro_rules! counter { - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ - let handle = $crate::register_counter!($(target: $target,)? $(level: $level,)? $name $(, $label_key $(=> $label_value)?)*); + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); handle.increment($op_val); - }}; + }; + (target: $target:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); + handle.increment($op_val); + }; + (level: $level:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); + handle.increment($op_val); + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); + handle.increment($op_val); + }; } /// Sets a counter to an absolute value. @@ -282,10 +278,22 @@ macro_rules! counter { /// ``` #[macro_export] macro_rules! absolute_counter { - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ - let handle = $crate::register_counter!($(target: $target,)? $(level: $level,)? $name $(, $label_key $(=> $label_value)?)*); + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); handle.absolute($op_val); - }}; + }; + (target: $target:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); + handle.absolute($op_val); + }; + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); + handle.absolute($op_val); + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); + handle.absolute($op_val); + }; } /// Increments a counter. @@ -329,7 +337,20 @@ macro_rules! absolute_counter { /// ``` #[macro_export] macro_rules! increment_counter { - ($(target: $target:expr,)? $(level: $level:expr,)? $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ - $crate::counter!($(target: $target,)? $(level: $level,)? $name, 1 $(, $label_key $(=> $label_value)?)*); - }}; + (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); + handle.increment(1); + }; + (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); + handle.absolute(1); + }; + (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); + handle.absolute(1); + }; + ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); + handle.absolute(1); + }; } From 7cd2552c16797a3b2fede52fcfbd41a6e5aaff8b Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 3 Sep 2023 20:18:57 +0100 Subject: [PATCH 14/24] fix empty labels fast path --- metrics/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index e8f60f70..79dde035 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -100,7 +100,7 @@ macro_rules! key_var { macro_rules! register_counter { (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { { - let metric_key = $crate::key_var!($name, $($label_key $(=> $label_value)?),*); + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); let metadata = $crate::metadata_var!($target, $level); $crate::recorder().register_counter(&metric_key, metadata) From 94de32c12b49c9340ec3801c86b9ee9a0712012a Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 3 Sep 2023 21:45:51 +0100 Subject: [PATCH 15/24] operations use `try_recorder` --- metrics/src/macros.rs | 76 +++++++++++++++++++++++-------------------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 79dde035..cbc44b5c 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -98,14 +98,12 @@ macro_rules! key_var { /// ``` #[macro_export] macro_rules! register_counter { - (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - { - let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); - let metadata = $crate::metadata_var!($target, $level); + (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); - $crate::recorder().register_counter(&metric_key, metadata) - } - }; + $crate::recorder().register_counter(&metric_key, metadata) + }}; (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::register_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; @@ -212,21 +210,23 @@ macro_rules! describe_counter { /// ``` #[macro_export] macro_rules! counter { - (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.increment($op_val); + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + + if let Some(recorder) = $crate::try_recorder() { + let handle = recorder.register_counter(&metric_key, &metadata); + handle.increment($op_val); + } }; - (target: $target:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); - handle.increment($op_val); + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::counter!(target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; - (level: $level:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.increment($op_val); + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::counter!(target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); - handle.increment($op_val); + $crate::counter!(target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; } @@ -278,21 +278,23 @@ macro_rules! counter { /// ``` #[macro_export] macro_rules! absolute_counter { - (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.absolute($op_val); + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + + if let Some(recorder) = $crate::try_recorder() { + let handle = recorder.register_counter(&metric_key, &metadata); + handle.absolute($op_val); + } }; - (target: $target:expr, $name:expr $(, $label_key:expr, $op_val:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); - handle.absolute($op_val); + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::absolute_counter!(target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.absolute($op_val); + $crate::absolute_counter!(target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); - handle.absolute($op_val); + $crate::counter!(target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; } @@ -338,19 +340,21 @@ macro_rules! absolute_counter { #[macro_export] macro_rules! increment_counter { (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.increment(1); + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + + if let Some(recorder) = $crate::try_recorder() { + let handle = recorder.register_counter(&metric_key, &metadata); + handle.increment(1); + } }; (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(target: $target, $name $(, $label_key $(=> $label_value)?)*); - handle.absolute(1); + $crate::increment_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!(level: $level, $name $(, $label_key $(=> $label_value)?)*); - handle.absolute(1); + $crate::increment_counter!(target: module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let handle = $crate::register_counter!($name $(, $label_key $(=> $label_value)?)*); - handle.absolute(1); + $crate::increment_counter!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; } From a5c35dad026523fa3b58470335debe7b461aad3b Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Mon, 11 Sep 2023 07:53:50 +0100 Subject: [PATCH 16/24] replace all gauge macros --- metrics-macros/src/lib.rs | 41 ----- metrics/src/lib.rs | 203 --------------------- metrics/src/macros.rs | 366 +++++++++++++++++++++++++++++++++----- 3 files changed, 322 insertions(+), 288 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 1fa00a0d..9852739c 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -117,13 +117,6 @@ impl Parse for Description { } } -#[proc_macro] -pub fn describe_gauge(input: TokenStream) -> TokenStream { - let Description { key, unit, description } = parse_macro_input!(input as Description); - - get_describe_code("gauge", key, unit, description).into() -} - #[proc_macro] pub fn describe_histogram(input: TokenStream) -> TokenStream { let Description { key, unit, description } = parse_macro_input!(input as Description); @@ -131,14 +124,6 @@ pub fn describe_histogram(input: TokenStream) -> TokenStream { get_describe_code("histogram", key, unit, description).into() } -#[proc_macro] -pub fn register_gauge(input: TokenStream) -> TokenStream { - let WithoutExpression { target, level, key, labels } = - parse_macro_input!(input as WithoutExpression); - - get_register_and_op_code::(target, level, "gauge", key, labels, None).into() -} - #[proc_macro] pub fn register_histogram(input: TokenStream) -> TokenStream { let WithoutExpression { target, level, key, labels } = @@ -147,32 +132,6 @@ pub fn register_histogram(input: TokenStream) -> TokenStream { get_register_and_op_code::(target, level, "histogram", key, labels, None).into() } -#[proc_macro] -pub fn increment_gauge(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "gauge", key, labels, Some(("increment", op_value))) - .into() -} - -#[proc_macro] -pub fn decrement_gauge(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "gauge", key, labels, Some(("decrement", op_value))) - .into() -} - -#[proc_macro] -pub fn gauge(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "gauge", key, labels, Some(("set", op_value))).into() -} - #[proc_macro] pub fn histogram(input: TokenStream) -> TokenStream { let WithExpression { target, level, key, op_value, labels } = diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index a6363881..50620185 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -277,40 +277,6 @@ pub use self::metadata::*; mod recorder; pub use self::recorder::*; -/// Describes a gauge. -/// -/// Gauges represent a single value that can go up or down over time, and always starts out with an -/// initial value of zero. -/// -/// Metrics can be described with a free-form string, and optionally, a unit can be provided to -/// describe the value and/or rate of the metric measurements. Whether or not the installed -/// recorder does anything with the description, or optional unit, is implementation defined. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::describe_gauge; -/// # use metrics::Unit; -/// # fn main() { -/// // A basic gauge: -/// describe_gauge!("some_metric_name", "my favorite gauge"); -/// -/// // Providing a unit for a gauge: -/// describe_gauge!("some_metric_name", Unit::Bytes, "my favorite gauge"); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// describe_gauge!(name, "my favorite gauge"); -/// -/// describe_gauge!(format!("{}_via_format", "name"), "my favorite gauge"); -/// # } -/// ``` -pub use metrics_macros::describe_gauge; - /// Describes a histogram. /// /// Histograms measure the distribution of values for a given set of measurements, and start with no @@ -345,52 +311,6 @@ pub use metrics_macros::describe_gauge; /// ``` pub use metrics_macros::describe_histogram; -/// Registers a gauge. -/// -/// Gauges represent a single value that can go up or down over time, and always starts out with an -/// initial value of zero. -/// -/// Metrics can be registered, which provides a handle to directly update that metric. For gauges, -/// [`Gauge`] is provided which can be incremented, decrement, or set to an absolute value. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::register_gauge; -/// # fn main() { -/// // A basic gauge: -/// let gauge = register_gauge!("some_metric_name"); -/// gauge.increment(1.0); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// let gauge = register_gauge!("some_metric_name", "service" => "http"); -/// gauge.decrement(42.0); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// let gauge = register_gauge!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); -/// gauge.increment(3.14); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, -/// // a unit or description can still be passed in their respective positions: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// let gauge = register_gauge!("some_metric_name", &labels); -/// gauge.set(1337.0); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// let gauge = register_gauge!(name); -/// -/// let gauge = register_gauge!(format!("{}_via_format", "name")); -/// # } -/// ``` -pub use metrics_macros::register_gauge; - /// Registers a histogram. /// /// Histograms measure the distribution of values for a given set of measurements, and start with no @@ -434,129 +354,6 @@ pub use metrics_macros::register_gauge; /// ``` pub use metrics_macros::register_histogram; -/// Updates a gauge. -/// -/// Gauges represent a single value that can go up or down over time, and always starts out with an -/// initial value of zero. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{gauge, Level}; -/// # fn main() { -/// // A basic gauge: -/// gauge!("some_metric_name", 42.2222); -/// -/// // A basic gauge with level and target specified: -/// gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// gauge!("some_metric_name", 66.6666, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// gauge!("some_metric_name", 42.42, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// gauge!(name, 800.85); -/// -/// gauge!(format!("{}_via_format", "name"), 3.14); -/// # } -/// ``` -pub use metrics_macros::gauge; - -/// Increments a gauge. -/// -/// Gauges represent a single value that can go up or down over time, and always starts out with an -/// initial value of zero. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{increment_gauge, Level}; -/// # fn main() { -/// // A basic gauge: -/// increment_gauge!("some_metric_name", 42.2222); -/// -/// // A basic gauge with level and target specified: -/// increment_gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// increment_gauge!("some_metric_name", 66.6666, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// increment_gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// increment_gauge!("some_metric_name", 42.42, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// increment_gauge!(name, 800.85); -/// -/// increment_gauge!(format!("{}_via_format", "name"), 3.14); -/// # } -/// ``` -pub use metrics_macros::increment_gauge; - -/// Decrements a gauge. -/// -/// Gauges represent a single value that can go up or down over time, and always starts out with an -/// initial value of zero. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{decrement_gauge, Level}; -/// # fn main() { -/// // A basic gauge: -/// decrement_gauge!("some_metric_name", 42.2222); -/// -/// // A basic gauge with level and target specified: -/// decrement_gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// decrement_gauge!("some_metric_name", 66.6666, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// decrement_gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// decrement_gauge!("some_metric_name", 42.42, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// decrement_gauge!(name, 800.85); -/// -/// decrement_gauge!(format!("{}_via_format", "name"), 3.14); -/// # } -/// ``` -pub use metrics_macros::decrement_gauge; - /// Records a histogram. /// /// Histograms measure the distribution of values for a given set of measurements, and start with no diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index cbc44b5c..3971ef13 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -115,6 +115,84 @@ macro_rules! register_counter { }; } +/// Registers a gauge. +/// +/// Gauges represent a single value that can go up or down over time, and always starts out with an +/// initial value of zero. +/// +/// Metrics can be registered, which provides a handle to directly update that metric. For gauges, +/// [`Gauge`] is provided which can be incremented, decrement, or set to an absolute value. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::register_gauge; +/// # fn main() { +/// // A basic gauge: +/// let gauge = register_gauge!("some_metric_name"); +/// gauge.increment(1.0); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// let gauge = register_gauge!("some_metric_name", "service" => "http"); +/// gauge.decrement(42.0); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// let gauge = register_gauge!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); +/// gauge.increment(3.14); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, +/// // a unit or description can still be passed in their respective positions: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// let gauge = register_gauge!("some_metric_name", &labels); +/// gauge.set(1337.0); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// let gauge = register_gauge!(name); +/// +/// let gauge = register_gauge!(format!("{}_via_format", "name")); +/// # } +/// ``` +#[macro_export] +macro_rules! register_gauge { + (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + + $crate::recorder().register_gauge(&metric_key, metadata) + }}; + (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_gauge!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_gauge!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + }; + ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_gauge!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! describe { + ($method:ident, $name:expr, $unit:expr, $description:expr) => {{ + if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { + recorder.$method($name.into(), ::core::option::Option::Some($unit), $description.into()) + } + }}; + ($method:ident, $name:expr, $description:expr) => {{ + if let Some(recorder) = $crate::try_recorder() { + recorder.$method($name.into(), ::core::option::Option::None, $description.into()) + } + }}; +} + /// Describes a counter. /// /// Counters represent a single monotonic value, which means the value can only be incremented, not @@ -149,24 +227,77 @@ macro_rules! register_counter { /// ``` #[macro_export] macro_rules! describe_counter { - ($name:expr, $unit:expr, $description:expr) => {{ - if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { - recorder.describe_counter( - $name.into(), - ::core::option::Option::Some($unit), - $description.into(), - ) - } - }}; - ($name:expr, $description:expr) => {{ + ($name:expr, $unit:expr, $description:expr) => { + $crate::describe!(describe_counter, $name, $unit, $description) + }; + ($name:expr, $description:expr) => { + $crate::describe!(describe_counter, $name, $description) + }; +} + +/// Describes a gauge. +/// +/// Gauges represent a single value that can go up or down over time, and always starts out with an +/// initial value of zero. +/// +/// Metrics can be described with a free-form string, and optionally, a unit can be provided to +/// describe the value and/or rate of the metric measurements. Whether or not the installed +/// recorder does anything with the description, or optional unit, is implementation defined. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::describe_gauge; +/// # use metrics::Unit; +/// # fn main() { +/// // A basic gauge: +/// describe_gauge!("some_metric_name", "my favorite gauge"); +/// +/// // Providing a unit for a gauge: +/// describe_gauge!("some_metric_name", Unit::Bytes, "my favorite gauge"); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// describe_gauge!(name, "my favorite gauge"); +/// +/// describe_gauge!(format!("{}_via_format", "name"), "my favorite gauge"); +/// # } +/// ``` +#[macro_export] +macro_rules! describe_gauge { + ($name:expr, $unit:expr, $description:expr) => { + $crate::describe!(describe_gauge, $name, $unit, $description) + }; + ($name:expr, $description:expr) => { + $crate::describe!(describe_gauge, $name, $description) + }; +} + +#[doc(hidden)] +#[macro_export] +macro_rules! method { + ($register:ident, $method:ident, target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + if let Some(recorder) = $crate::try_recorder() { - recorder.describe_counter( - $name.into(), - ::core::option::Option::None, - $description.into(), - ) + let handle = recorder.$register(&metric_key, &metadata); + handle.$method($op_val); } - }}; + }; + ($register:ident, $method:ident, target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { + $crate::method!($register, $method, target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + ($register:ident, $method:ident, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { + $crate::method!($register, $method, target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + ($register:ident, $method:ident, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { + $crate::method!($register, $method, target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; } /// Increments a counter. @@ -211,22 +342,126 @@ macro_rules! describe_counter { #[macro_export] macro_rules! counter { (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); - let metadata = $crate::metadata_var!($target, $level); + $crate::method!(register_counter, increment, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, increment, target: $target, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, increment, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, increment, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; +} - if let Some(recorder) = $crate::try_recorder() { - let handle = recorder.register_counter(&metric_key, &metadata); - handle.increment($op_val); - } +/// Increments a gauge. +/// +/// Gauges represent a single value that can go up or down over time, and always starts out with an +/// initial value of zero. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{increment_gauge, Level}; +/// # fn main() { +/// // A basic gauge: +/// increment_gauge!("some_metric_name", 42.2222); +/// +/// // A basic gauge with level and target specified: +/// increment_gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// increment_gauge!("some_metric_name", 66.6666, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// increment_gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// increment_gauge!("some_metric_name", 42.42, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// increment_gauge!(name, 800.85); +/// +/// increment_gauge!(format!("{}_via_format", "name"), 3.14); +/// # } +/// ``` +#[macro_export] +macro_rules! increment_gauge { + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, increment, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, increment, target: $target, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, increment, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, increment, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; +} + +/// Decrements a gauge. +/// +/// Gauges represent a single value that can go up or down over time, and always starts out with an +/// initial value of zero. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{decrement_gauge, Level}; +/// # fn main() { +/// // A basic gauge: +/// decrement_gauge!("some_metric_name", 42.2222); +/// +/// // A basic gauge with level and target specified: +/// decrement_gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// decrement_gauge!("some_metric_name", 66.6666, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// decrement_gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// decrement_gauge!("some_metric_name", 42.42, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// decrement_gauge!(name, 800.85); +/// +/// decrement_gauge!(format!("{}_via_format", "name"), 3.14); +/// # } +/// ``` +#[macro_export] +macro_rules! decrement_gauge { + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, decrement, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::counter!(target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, decrement, target: $target, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::counter!(target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, decrement, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::counter!(target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, decrement, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; } @@ -279,22 +514,71 @@ macro_rules! counter { #[macro_export] macro_rules! absolute_counter { (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); - let metadata = $crate::metadata_var!($target, $level); + $crate::method!(register_counter, absolute, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, absolute, target: $target, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, absolute, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_counter, absolute, $name, $op_val $(, $label_key $(=> $label_value)?)*) + }; +} - if let Some(recorder) = $crate::try_recorder() { - let handle = recorder.register_counter(&metric_key, &metadata); - handle.absolute($op_val); - } +/// Updates a gauge. +/// +/// Gauges represent a single value that can go up or down over time, and always starts out with an +/// initial value of zero. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{gauge, Level}; +/// # fn main() { +/// // A basic gauge: +/// gauge!("some_metric_name", 42.2222); +/// +/// // A basic gauge with level and target specified: +/// gauge!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 42.2222); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// gauge!("some_metric_name", 66.6666, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// gauge!("some_metric_name", 66.6666, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// gauge!("some_metric_name", 42.42, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// gauge!(name, 800.85); +/// +/// gauge!(format!("{}_via_format", "name"), 3.14); +/// # } +/// ``` +#[macro_export] +macro_rules! gauge { + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_gauge, set, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::absolute_counter!(target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, set, target: $target, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::absolute_counter!(target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, set, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::counter!(target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_gauge, set, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; } @@ -340,21 +624,15 @@ macro_rules! absolute_counter { #[macro_export] macro_rules! increment_counter { (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); - let metadata = $crate::metadata_var!($target, $level); - - if let Some(recorder) = $crate::try_recorder() { - let handle = recorder.register_counter(&metric_key, &metadata); - handle.increment(1); - } + $crate::method!(register_counter, increment, target: $target, level: $level, $name, 1 $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::increment_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_counter, increment, target: $target, $name, 1 $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::increment_counter!(target: module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_counter, increment, level: $level, $name, 1 $(, $label_key $(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::increment_counter!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) + $crate::method!(register_counter, increment, $name, 1 $(, $label_key $(=> $label_value)?)*) }; } From e925f6c533f395f5e64ce6944c8ffa62dde0f209 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Mon, 11 Sep 2023 08:12:22 +0100 Subject: [PATCH 17/24] replace all histogram macros --- metrics-macros/src/lib.rs | 505 -------------------------------------- metrics/src/lib.rs | 132 ---------- metrics/src/macros.rs | 171 +++++++++++++ 3 files changed, 171 insertions(+), 637 deletions(-) diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs index 9852739c..8b137891 100644 --- a/metrics-macros/src/lib.rs +++ b/metrics-macros/src/lib.rs @@ -1,506 +1 @@ -extern crate proc_macro; -use self::proc_macro::TokenStream; - -use proc_macro2::TokenStream as TokenStream2; -use quote::{format_ident, quote, ToTokens}; -use syn::parse::{Error, Parse, ParseStream, Result}; -use syn::token::{Colon, Comma}; -use syn::{parse::discouraged::Speculative, Lit}; -use syn::{parse_macro_input, Expr, LitStr, Token}; - -#[cfg(test)] -mod tests; - -enum Labels { - Existing(Expr), - Inline(Vec<(Expr, Expr)>), -} - -struct WithoutExpression { - target: Option, - level: Option, - key: Expr, - labels: Option, -} - -struct WithExpression { - target: Option, - level: Option, - key: Expr, - op_value: Expr, - labels: Option, -} - -struct Description { - key: Expr, - unit: Option, - description: Expr, -} - -impl Parse for WithoutExpression { - fn parse(mut input: ParseStream) -> Result { - let target = parse_target(&mut input)?; - let level = parse_level(&mut input)?; - let key = input.parse::()?; - let labels = parse_labels(&mut input)?; - - Ok(WithoutExpression { target, level, key, labels }) - } -} - -impl Parse for WithExpression { - fn parse(mut input: ParseStream) -> Result { - let target = parse_target(&mut input)?; - let level = parse_level(&mut input)?; - let key = input.parse::()?; - - input.parse::()?; - let op_value = input.parse::()?; - - let labels = parse_labels(&mut input)?; - - Ok(WithExpression { target, level, key, op_value, labels }) - } -} - -impl Parse for Description { - fn parse(input: ParseStream) -> Result { - let key = input.parse::()?; - - // We accept two possible parameters: unit, and description. - // - // There is only one specific requirement that must be met, and that is that the || _must_ - // have a qualified path of either `metrics::Unit::...` or `Unit::..` for us to properly - // distinguish it amongst the macro parameters. - - // Now try to read out the components. We speculatively try to parse out a unit if it - // exists, and otherwise we just look for the description. - let unit = input - .call(|s| { - let forked = s.fork(); - forked.parse::()?; - - let output = if let Ok(Expr::Path(path)) = forked.parse::() { - let qname = path - .path - .segments - .iter() - .map(|x| x.ident.to_string()) - .collect::>() - .join("::"); - if qname.starts_with("::metrics::Unit") - || qname.starts_with("metrics::Unit") - || qname.starts_with("Unit") - { - Some(Expr::Path(path)) - } else { - None - } - } else { - None - }; - - if output.is_some() { - s.advance_to(&forked); - } - - Ok(output) - }) - .ok() - .flatten(); - - input.parse::()?; - let description = input.parse::()?; - - Ok(Description { key, unit, description }) - } -} - -#[proc_macro] -pub fn describe_histogram(input: TokenStream) -> TokenStream { - let Description { key, unit, description } = parse_macro_input!(input as Description); - - get_describe_code("histogram", key, unit, description).into() -} - -#[proc_macro] -pub fn register_histogram(input: TokenStream) -> TokenStream { - let WithoutExpression { target, level, key, labels } = - parse_macro_input!(input as WithoutExpression); - - get_register_and_op_code::(target, level, "histogram", key, labels, None).into() -} - -#[proc_macro] -pub fn histogram(input: TokenStream) -> TokenStream { - let WithExpression { target, level, key, op_value, labels } = - parse_macro_input!(input as WithExpression); - - get_register_and_op_code(target, level, "histogram", key, labels, Some(("record", op_value))) - .into() -} - -fn get_describe_code( - metric_type: &str, - name: Expr, - unit: Option, - description: Expr, -) -> TokenStream2 { - let describe_ident = format_ident!("describe_{}", metric_type); - - let unit = match unit { - Some(e) => quote! { Some(#e) }, - None => quote! { None }, - }; - - quote! { - { - // Only do this work if there's a recorder installed. - if let Some(recorder) = ::metrics::try_recorder() { - recorder.#describe_ident(#name.into(), #unit, #description.into()); - } - } - } -} - -fn get_register_and_op_code( - target: Option, - level: Option, - metric_type: &str, - name: Expr, - labels: Option, - op: Option<(&'static str, V)>, -) -> TokenStream2 -where - V: ToTokens, -{ - let register_ident = format_ident!("register_{}", metric_type); - let statics = generate_statics(&target, &level, &name, &labels); - let (locals, metric_key) = generate_metric_key(&name, &labels); - match op { - Some((op_type, op_value)) => { - let op_ident = format_ident!("{}", op_type); - let op_value = if metric_type == "histogram" { - quote! { ::metrics::__into_f64(#op_value) } - } else { - quote! { #op_value } - }; - - // We've been given values to actually use with the handle, so we actually check if a - // recorder is installed before bothering to create a handle and everything. - quote! { - { - #statics - // Only do this work if there's a recorder installed. - if let Some(recorder) = ::metrics::try_recorder() { - #locals - let handle = recorder.#register_ident(#metric_key, &METADATA); - handle.#op_ident(#op_value); - } - } - } - } - None => { - // If there's no values specified, we simply return the metric handle. - quote! { - { - #statics - #locals - ::metrics::recorder().#register_ident(#metric_key, &METADATA) - } - } - } - } -} - -fn name_is_fast_path(name: &Expr) -> bool { - if let Expr::Lit(lit) = name { - return matches!(lit.lit, Lit::Str(_)); - } - - false -} - -fn labels_are_fast_path(labels: &Labels) -> bool { - match labels { - Labels::Existing(_) => false, - Labels::Inline(pairs) => { - pairs.iter().all(|(k, v)| matches!((k, v), (Expr::Lit(_), Expr::Lit(_)))) - } - } -} - -fn generate_statics( - target: &Option, - level: &Option, - name: &Expr, - labels: &Option, -) -> TokenStream2 { - // Create the static for the name, if possible. - let use_name_static = name_is_fast_path(name); - let name_static = if use_name_static { - quote! { - static METRIC_NAME: &'static str = #name; - } - } else { - quote! {} - }; - - // Create the static for the labels, if possible. - let has_labels = labels.is_some(); - let use_labels_static = match labels.as_ref() { - Some(labels) => labels_are_fast_path(labels), - None => true, - }; - - let labels_static = match labels.as_ref() { - Some(labels) => { - if labels_are_fast_path(labels) { - if let Labels::Inline(pairs) = labels { - let labels = pairs - .iter() - .map( - |(key, val)| quote! { ::metrics::Label::from_static_parts(#key, #val) }, - ) - .collect::>(); - let labels_len = labels.len(); - let labels_len = quote! { #labels_len }; - - quote! { - static METRIC_LABELS: [::metrics::Label; #labels_len] = [#(#labels),*]; - } - } else { - quote! {} - } - } else { - quote! {} - } - } - None => quote! {}, - }; - - let key_static = if use_name_static && use_labels_static { - if has_labels { - quote! { - static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_parts(METRIC_NAME, &METRIC_LABELS); - } - } else { - quote! { - static METRIC_KEY: ::metrics::Key = ::metrics::Key::from_static_name(METRIC_NAME); - } - } - } else { - quote! {} - }; - - let target = if let Some(target) = target { - quote! { #target } - } else { - quote! { - module_path!() - } - }; - let level = if let Some(level) = level { - quote! { #level } - } else { - quote! { ::metrics::Level::INFO } - }; - - let metadata_static = quote! { - static METADATA: ::metrics::Metadata<'static> = ::metrics::Metadata::new( - #target, - #level, - Some(module_path!()), - ); - }; - - quote! { - #name_static - #labels_static - #key_static - #metadata_static - } -} - -fn generate_metric_key(name: &Expr, labels: &Option) -> (TokenStream2, TokenStream2) { - let use_name_static = name_is_fast_path(name); - - let has_labels = labels.is_some(); - let use_labels_static = match labels.as_ref() { - Some(labels) => labels_are_fast_path(labels), - None => true, - }; - - let mut key_name = quote! { &key }; - let locals = if use_name_static && use_labels_static { - // Key is entirely static, so we can simply reference our generated statics. They will be - // inclusive of whether or not labels were specified. - key_name = quote! { &METRIC_KEY }; - quote! {} - } else if use_name_static && !use_labels_static { - // The name is static, but we have labels which are not static. Since `use_labels_static` - // cannot be false unless labels _are_ specified, we know this unwrap is safe. - let labels = labels.as_ref().unwrap(); - let quoted_labels = labels_to_quoted(labels); - quote! { - let key = ::metrics::Key::from_parts(METRIC_NAME, #quoted_labels); - } - } else if !use_name_static && !use_labels_static { - // The name is not static, and neither are the labels. Since `use_labels_static` - // cannot be false unless labels _are_ specified, we know this unwrap is safe. - let labels = labels.as_ref().unwrap(); - let quoted_labels = labels_to_quoted(labels); - quote! { - let key = ::metrics::Key::from_parts(#name, #quoted_labels); - } - } else { - // The name is not static, but the labels are. This could technically mean that there - // simply are no labels, so we have to discriminate in a slightly different way - // to figure out the correct key. - if has_labels { - quote! { - let key = ::metrics::Key::from_static_labels(#name, &METRIC_LABELS); - } - } else { - quote! { - let key = ::metrics::Key::from_name(#name); - } - } - }; - - (locals, key_name) -} - -fn labels_to_quoted(labels: &Labels) -> proc_macro2::TokenStream { - match labels { - Labels::Inline(pairs) => { - let labels = - pairs.iter().map(|(key, val)| quote! { ::metrics::Label::new(#key, #val) }); - quote! { vec![#(#labels),*] } - } - Labels::Existing(e) => quote! { #e }, - } -} - -mod kw { - syn::custom_keyword!(target); - syn::custom_keyword!(level); -} - -struct Target { - _target_key: kw::target, - _colon: Colon, - target_value: LitStr, -} - -impl Parse for Target { - fn parse(input: ParseStream) -> Result { - Ok(Target { - _target_key: input.parse()?, - _colon: input.parse()?, - target_value: input.parse()?, - }) - } -} - -fn parse_target(input: &mut ParseStream) -> Result> { - let lookahead = input.lookahead1(); - let opt_target = if lookahead.peek(kw::target) { - let target = input.parse::()?.target_value; - let _colon: Comma = input.parse()?; - Some(target) - } else { - None - }; - Ok(opt_target) -} - -struct Level { - _level_key: kw::level, - _colon: Colon, - target_value: Expr, -} - -impl Parse for Level { - fn parse(input: ParseStream) -> Result { - Ok(Self { - _level_key: input.parse()?, - _colon: input.parse()?, - target_value: input.parse()?, - }) - } -} - -fn parse_level(input: &mut ParseStream) -> Result> { - let lookahead = input.lookahead1(); - let opt_level = if lookahead.peek(kw::level) { - let level = input.parse::()?.target_value; - let _colon: Comma = input.parse()?; - Some(level) - } else { - None - }; - Ok(opt_level) -} - -fn parse_labels(input: &mut ParseStream) -> Result> { - if input.is_empty() { - return Ok(None); - } - - if !input.peek(Token![,]) { - // This is a hack to generate the proper error message for parsing the comma next without - // actually parsing it and thus removing it from the parse stream. Just makes the following - // code a bit cleaner. - input - .parse::() - .map_err(|e| Error::new(e.span(), "expected labels, but comma not found"))?; - } - - // Two possible states for labels: references to a label iterator, or key/value pairs. - // - // We check to see if we have the ", key =>" part, which tells us that we're taking in key/value - // pairs. If we don't have that, we check to see if we have a "`, ]) { - let mut labels = Vec::new(); - loop { - if input.is_empty() { - break; - } - input.parse::()?; - if input.is_empty() { - break; - } - - let k = input.parse::()?; - input.parse::]>()?; - let v = input.parse::()?; - - labels.push((k, v)); - } - - return Ok(Some(Labels::Inline(labels))); - } - - // Has to be an expression otherwise, or a trailing comma. - input.parse::()?; - - // Unless it was an expression - clear the trailing comma. - if input.is_empty() { - return Ok(None); - } - - let existing = input.parse::().map_err(|e| { - Error::new(e.span(), "expected labels expression, but expression not found") - })?; - - // Expression can end with a trailing comma, handle it. - if input.peek(Token![,]) { - input.parse::()?; - } - - Ok(Some(Labels::Existing(existing))) -} diff --git a/metrics/src/lib.rs b/metrics/src/lib.rs index 50620185..71ca26ea 100644 --- a/metrics/src/lib.rs +++ b/metrics/src/lib.rs @@ -276,135 +276,3 @@ pub use self::metadata::*; mod recorder; pub use self::recorder::*; - -/// Describes a histogram. -/// -/// Histograms measure the distribution of values for a given set of measurements, and start with no -/// initial values. -/// -/// Metrics can be described with a free-form string, and optionally, a unit can be provided to -/// describe the value and/or rate of the metric measurements. Whether or not the installed -/// recorder does anything with the description, or optional unit, is implementation defined. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::describe_histogram; -/// # use metrics::Unit; -/// # fn main() { -/// // A basic histogram: -/// describe_histogram!("some_metric_name", "my favorite histogram"); -/// -/// // Providing a unit for a histogram: -/// describe_histogram!("some_metric_name", Unit::Bytes, "my favorite histogram"); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// describe_histogram!(name, "my favorite histogram"); -/// -/// describe_histogram!(format!("{}_via_format", "name"), "my favorite histogram"); -/// # } -/// ``` -pub use metrics_macros::describe_histogram; - -/// Registers a histogram. -/// -/// Histograms measure the distribution of values for a given set of measurements, and start with no -/// initial values. -/// -/// Metrics can be registered, which provides a handle to directly update that metric. For -/// histograms, [`Histogram`] is provided which can record values. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::register_histogram; -/// # fn main() { -/// // A basic histogram: -/// let histogram = register_histogram!("some_metric_name"); -/// histogram.record(1.0); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// let histogram = register_histogram!("some_metric_name", "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// let histogram = register_histogram!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, -/// // a unit or description can still be passed in their respective positions: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// let histogram = register_histogram!("some_metric_name", &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// let histogram = register_histogram!(name); -/// -/// let histogram = register_histogram!(format!("{}_via_format", "name")); -/// # } -/// ``` -pub use metrics_macros::register_histogram; - -/// Records a histogram. -/// -/// Histograms measure the distribution of values for a given set of measurements, and start with no -/// initial values. -/// -/// # Implicit conversions -/// Histograms are represented as `f64` values, but often come from another source, such as a time -/// measurement. By default, `histogram!` will accept a `f64` directly or a -/// [`Duration`](std::time::Duration), which uses the floating-point number of seconds represents by -/// the duration. -/// -/// External libraries and applications can create their own conversions by implementing the -/// [`IntoF64`] trait for their types, which is required for the value being passed to `histogram!`. -/// -/// Metric names are shown below using string literals, but they can also be owned `String` values, -/// which includes using macros such as `format!` directly at the callsite. String literals are -/// preferred for performance where possible. -/// -/// # Example -/// ``` -/// # use metrics::{histogram, Level}; -/// # use std::time::Duration; -/// # fn main() { -/// // A basic histogram: -/// histogram!("some_metric_name", 34.3); -/// -/// // A basic histogram with level and target specified: -/// histogram!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 34.3); -/// -/// // An implicit conversion from `Duration`: -/// let d = Duration::from_millis(17); -/// histogram!("some_metric_name", d); -/// -/// // Specifying labels inline, including using constants for either the key or value: -/// histogram!("some_metric_name", 38.0, "service" => "http"); -/// -/// const SERVICE_LABEL: &'static str = "service"; -/// const SERVICE_HTTP: &'static str = "http"; -/// histogram!("some_metric_name", 38.0, SERVICE_LABEL => SERVICE_HTTP); -/// -/// // We can also pass labels by giving a vector or slice of key/value pairs: -/// let dynamic_val = "woo"; -/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; -/// histogram!("some_metric_name", 1337.5, &labels); -/// -/// // As mentioned in the documentation, metric names also can be owned strings, including ones -/// // generated at the callsite via things like `format!`: -/// let name = String::from("some_owned_metric_name"); -/// histogram!(name, 800.85); -/// -/// histogram!(format!("{}_via_format", "name"), 3.14); -/// # } -/// ``` -pub use metrics_macros::histogram; diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 3971ef13..23c1e734 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -178,6 +178,66 @@ macro_rules! register_gauge { }; } +/// Registers a histogram. +/// +/// Histograms measure the distribution of values for a given set of measurements, and start with no +/// initial values. +/// +/// Metrics can be registered, which provides a handle to directly update that metric. For +/// histograms, [`Histogram`] is provided which can record values. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::register_histogram; +/// # fn main() { +/// // A basic histogram: +/// let histogram = register_histogram!("some_metric_name"); +/// histogram.record(1.0); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// let histogram = register_histogram!("some_metric_name", "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// let histogram = register_histogram!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs. In this scenario, +/// // a unit or description can still be passed in their respective positions: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// let histogram = register_histogram!("some_metric_name", &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// let histogram = register_histogram!(name); +/// +/// let histogram = register_histogram!(format!("{}_via_format", "name")); +/// # } +/// ``` +#[macro_export] +macro_rules! register_histogram { + (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{ + let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); + let metadata = $crate::metadata_var!($target, $level); + + $crate::recorder().register_histogram(&metric_key, metadata) + }}; + (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_histogram!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_histogram!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + }; + ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::register_histogram!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + }; +} + #[doc(hidden)] #[macro_export] macro_rules! describe { @@ -277,6 +337,48 @@ macro_rules! describe_gauge { }; } +/// Describes a histogram. +/// +/// Histograms measure the distribution of values for a given set of measurements, and start with no +/// initial values. +/// +/// Metrics can be described with a free-form string, and optionally, a unit can be provided to +/// describe the value and/or rate of the metric measurements. Whether or not the installed +/// recorder does anything with the description, or optional unit, is implementation defined. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::describe_histogram; +/// # use metrics::Unit; +/// # fn main() { +/// // A basic histogram: +/// describe_histogram!("some_metric_name", "my favorite histogram"); +/// +/// // Providing a unit for a histogram: +/// describe_histogram!("some_metric_name", Unit::Bytes, "my favorite histogram"); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// describe_histogram!(name, "my favorite histogram"); +/// +/// describe_histogram!(format!("{}_via_format", "name"), "my favorite histogram"); +/// # } +/// ``` +#[macro_export] +macro_rules! describe_histogram { + ($name:expr, $unit:expr, $description:expr) => { + $crate::describe!(describe_histogram, $name, $unit, $description) + }; + ($name:expr, $description:expr) => { + $crate::describe!(describe_histogram, $name, $description) + }; +} + #[doc(hidden)] #[macro_export] macro_rules! method { @@ -582,6 +684,75 @@ macro_rules! gauge { }; } +/// Records a histogram. +/// +/// Histograms measure the distribution of values for a given set of measurements, and start with no +/// initial values. +/// +/// # Implicit conversions +/// Histograms are represented as `f64` values, but often come from another source, such as a time +/// measurement. By default, `histogram!` will accept a `f64` directly or a +/// [`Duration`](std::time::Duration), which uses the floating-point number of seconds represents by +/// the duration. +/// +/// External libraries and applications can create their own conversions by implementing the +/// [`IntoF64`] trait for their types, which is required for the value being passed to `histogram!`. +/// +/// Metric names are shown below using string literals, but they can also be owned `String` values, +/// which includes using macros such as `format!` directly at the callsite. String literals are +/// preferred for performance where possible. +/// +/// # Example +/// ``` +/// # use metrics::{histogram, Level}; +/// # use std::time::Duration; +/// # fn main() { +/// // A basic histogram: +/// histogram!("some_metric_name", 34.3); +/// +/// // A basic histogram with level and target specified: +/// histogram!(target: "specific_target", level: Level::DEBUG, "some_metric_name", 34.3); +/// +/// // An implicit conversion from `Duration`: +/// let d = Duration::from_millis(17); +/// histogram!("some_metric_name", d); +/// +/// // Specifying labels inline, including using constants for either the key or value: +/// histogram!("some_metric_name", 38.0, "service" => "http"); +/// +/// const SERVICE_LABEL: &'static str = "service"; +/// const SERVICE_HTTP: &'static str = "http"; +/// histogram!("some_metric_name", 38.0, SERVICE_LABEL => SERVICE_HTTP); +/// +/// // We can also pass labels by giving a vector or slice of key/value pairs: +/// let dynamic_val = "woo"; +/// let labels = [("dynamic_key", format!("{}!", dynamic_val))]; +/// histogram!("some_metric_name", 1337.5, &labels); +/// +/// // As mentioned in the documentation, metric names also can be owned strings, including ones +/// // generated at the callsite via things like `format!`: +/// let name = String::from("some_owned_metric_name"); +/// histogram!(name, 800.85); +/// +/// histogram!(format!("{}_via_format", "name"), 3.14); +/// # } +/// ``` +#[macro_export] +macro_rules! histogram { + (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_histogram, record, target: $target, level: $level, $name, $crate::__into_f64($op_val) $(, $label_key $(=> $label_value)?)*) + }; + (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_histogram, record, target: $target, $name, $crate::__into_f64($op_val) $(, $label_key $(=> $label_value)?)*) + }; + (level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_histogram, record, level: $level, $name, $crate::__into_f64($op_val) $(, $label_key $(=> $label_value)?)*) + }; + ($name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + $crate::method!(register_histogram, record, $name, $crate::__into_f64($op_val) $(, $label_key $(=> $label_value)?)*) + }; +} + /// Increments a counter. /// /// Counters represent a single monotonic value, which means the value can only be incremented, not From fc43531ee80176ebd4ed9ca3bf942fac73097f8b Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Tue, 12 Sep 2023 00:45:48 +0100 Subject: [PATCH 18/24] delete `metrics-macros` --- Cargo.toml | 1 - README.md | 2 - metrics-macros/CHANGELOG.md | 78 ----- metrics-macros/Cargo.toml | 25 -- metrics-macros/LICENSE | 1 - metrics-macros/README.md | 4 - metrics-macros/src/lib.rs | 1 - metrics-macros/src/tests.rs | 678 ------------------------------------ metrics/Cargo.toml | 5 +- 9 files changed, 3 insertions(+), 792 deletions(-) delete mode 100644 metrics-macros/CHANGELOG.md delete mode 100644 metrics-macros/Cargo.toml delete mode 120000 metrics-macros/LICENSE delete mode 100644 metrics-macros/README.md delete mode 100644 metrics-macros/src/lib.rs delete mode 100644 metrics-macros/src/tests.rs diff --git a/Cargo.toml b/Cargo.toml index 7911ccd4..66041294 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,6 @@ [workspace] members = [ "metrics", - "metrics-macros", "metrics-util", "metrics-exporter-tcp", "metrics-exporter-prometheus", diff --git a/README.md b/README.md index 12b2daa5..fafdce31 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ If you're a library author, you'll only care about using [`metrics`][metrics] to Overall, this repository is home to the following crates: * [`metrics`][metrics]: A lightweight metrics facade, similar to [`log`][log]. -* [`metrics-macros`][metrics-macros]: Procedural macros that power `metrics`. * [`metrics-tracing-context`][metrics-tracing-context]: Allow capturing [`tracing`][tracing] span fields as metric labels. * [`metrics-exporter-tcp`][metrics-exporter-tcp]: A `metrics`-compatible exporter for serving metrics over TCP. @@ -83,7 +82,6 @@ To everyone else that we haven't had the pleasure of interacting with: we're alw We'd love to chat about any of the above, or anything else related to metrics. Don't hesitate to file an issue on the repository, or come and chat with us over on [Discord](https://discord.gg/eTwKyY9). [metrics]: https://github.com/metrics-rs/metrics/tree/main/metrics -[metrics-macros]: https://github.com/metrics-rs/metrics/tree/main/metrics-macros [metrics-tracing-context]: https://github.com/metrics-rs/metrics/tree/main/metrics-tracing-context [metrics-exporter-tcp]: https://github.com/metrics-rs/metrics/tree/main/metrics-exporter-tcp [metrics-exporter-prometheus]: https://github.com/metrics-rs/metrics/tree/main/metrics-exporter-prometheus diff --git a/metrics-macros/CHANGELOG.md b/metrics-macros/CHANGELOG.md deleted file mode 100644 index 9169e206..00000000 --- a/metrics-macros/CHANGELOG.md +++ /dev/null @@ -1,78 +0,0 @@ -# Changelog -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - - - -## [Unreleased] - ReleaseDate - -## [0.7.0] - 2023-04-16 - -### Changed - -- Bump MSRV to 1.61.0. - -### Fixed - -- Type paths are now fully qualified in all macros to avoid issues with local import scopes having a - pre-existing `metrics` module. - -## [0.6.0] - 2022-07-22 - -### Changed - -- Updated the describe macros to support the recent change to taking `metrics::SharedString` instead - of `&'static str` for description strings. - -## [0.5.1] - 2022-02-06 - -Maintenance release. - -## [0.5.0] - 2022-01-14 - -### Added -- When describing a metric, a constant can now be used for the description itself. -- Label keys can now be general expressions i.e. constants or variables. Due to limitations in - how procedural macros work, and the facilities available in stable Rust for const traits, even - `&'static str` constants will cause allocations when used for emitting a metric. - -### Changed -- Correctly scoped the required features of various dependencies to reduce build times/transitive dependencies. -- Updated macros to coincide with the update to `metrics` for metric handles. This includes - renaming `register_*` macros to `describe_*`, which are purely for providing data that describes a - metric but does not initialize it in any way, and providing new `register_*` macros which do - initialize a metric. -- Updated the `describe_*` macros -- née `register_*` -- to require a description, and an optional - unit. As describing a metric does not register it in the sense of ensuring that it is present on - the output of an exporter, having the description be optional no longer makes sense. -- Additionally, the describe macros no longer take labels. In practice, varying the description of - a specific metric based on label values would be counter-intuitive, and to support this corner - case requires adds significant complexity to the macro parsing logic. - -### Removed -- Two unecessary dependencies, `lazy_static` and `regex`. - -## [0.4.1] - 2021-12-16 - -### Changed -- Removed unnecessary `proc-macro-hack` dependency. - -## [0.4.0] - 2021-05-18 - -### Changed -- Updates to macros to support the removal of `NameParts` and related machinery. - -## [0.3.0] - 2021-05-03 - -### Changed -- Updates to macros to support changes in `Recorder` around how keys are taken. - -## [0.2.0] - 2021-02-02 -### Changed -- Added support for owned strings as metric names. [#170](https://github.com/metrics-rs/metrics/pull/170) - -## [0.1.0] - 2021-01-22 -### Added -- Effective birth of the crate. diff --git a/metrics-macros/Cargo.toml b/metrics-macros/Cargo.toml deleted file mode 100644 index c5843fc4..00000000 --- a/metrics-macros/Cargo.toml +++ /dev/null @@ -1,25 +0,0 @@ -[package] -name = "metrics-macros" -version = "0.7.0" -authors = ["Toby Lawrence "] -edition = "2018" -rust-version = "1.61.0" - -license = "MIT" - -description = "Macros for the metrics crate." -homepage = "https://github.com/metrics-rs/metrics" -repository = "https://github.com/metrics-rs/metrics" -documentation = "https://docs.rs/metrics" -readme = "README.md" - -categories = ["development-tools::debugging"] -keywords = ["metrics", "facade", "macros"] - -[lib] -proc-macro = true - -[dependencies] -syn = { version = "2", default-features = false, features = ["derive", "full", "parsing", "printing", "proc-macro"] } -quote = { version = "1", default-features = false } -proc-macro2 = { version = "1", default-features = false, features = ["proc-macro"] } diff --git a/metrics-macros/LICENSE b/metrics-macros/LICENSE deleted file mode 120000 index ea5b6064..00000000 --- a/metrics-macros/LICENSE +++ /dev/null @@ -1 +0,0 @@ -../LICENSE \ No newline at end of file diff --git a/metrics-macros/README.md b/metrics-macros/README.md deleted file mode 100644 index bd6c1b7b..00000000 --- a/metrics-macros/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# metrics-macros - -This crate houses all of the procedural macros that are re-exported by `metrics`. Refer to the -documentation for `metrics` to find examples and more information on the available macros. \ No newline at end of file diff --git a/metrics-macros/src/lib.rs b/metrics-macros/src/lib.rs deleted file mode 100644 index 8b137891..00000000 --- a/metrics-macros/src/lib.rs +++ /dev/null @@ -1 +0,0 @@ - diff --git a/metrics-macros/src/tests.rs b/metrics-macros/src/tests.rs deleted file mode 100644 index f682ad68..00000000 --- a/metrics-macros/src/tests.rs +++ /dev/null @@ -1,678 +0,0 @@ -use syn::parse_quote; -use syn::{Expr, ExprPath}; - -use super::*; - -#[test] -fn test_get_describe_code() { - // Basic registration. - let stream = get_describe_code( - "mytype", - parse_quote! { "mykeyname" }, - None, - parse_quote! { "a counter" }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (\"mykeyname\" . into () , None , \"a counter\" . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_qualified_unit_rooted() { - // Now with unit. - let units: ExprPath = parse_quote! { ::metrics::Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { "mykeyname" }, - Some(Expr::Path(units)), - parse_quote! { "a counter" }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (\"mykeyname\" . into () , Some (:: metrics :: Unit :: Nanoseconds) , \"a counter\" . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_qualified_unit() { - // Now with unit. - let units: ExprPath = parse_quote! { metrics::Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { "mykeyname" }, - Some(Expr::Path(units)), - parse_quote! { "a counter" }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (\"mykeyname\" . into () , Some (metrics :: Unit :: Nanoseconds) , \"a counter\" . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_relative_unit() { - // Now with unit. - let units: ExprPath = parse_quote! { Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { "mykeyname" }, - Some(Expr::Path(units)), - parse_quote! { "a counter" }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (\"mykeyname\" . into () , Some (Unit :: Nanoseconds) , \"a counter\" . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_constants() { - // Basic registration. - let stream = - get_describe_code("mytype", parse_quote! { KEY_NAME }, None, parse_quote! { COUNTER_DESC }); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (KEY_NAME . into () , None , COUNTER_DESC . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_constants_and_with_qualified_unit() { - // Now with unit. - let units: ExprPath = parse_quote! { metrics::Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { KEY_NAME }, - Some(Expr::Path(units)), - parse_quote! { COUNTER_DESC }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (KEY_NAME . into () , Some (metrics :: Unit :: Nanoseconds) , COUNTER_DESC . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_constants_and_with_qualified_unit_rooted() { - // Now with unit. - let units: ExprPath = parse_quote! { ::metrics::Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { KEY_NAME }, - Some(Expr::Path(units)), - parse_quote! { COUNTER_DESC }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (KEY_NAME . into () , Some (:: metrics :: Unit :: Nanoseconds) , COUNTER_DESC . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_describe_code_with_constants_and_with_relative_unit() { - // Now with unit. - let units: ExprPath = parse_quote! { Unit::Nanoseconds }; - let stream = get_describe_code( - "mytype", - parse_quote! { KEY_NAME }, - Some(Expr::Path(units)), - parse_quote! { COUNTER_DESC }, - ); - - let expected = concat!( - "{ ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "recorder . describe_mytype (KEY_NAME . into () , Some (Unit :: Nanoseconds) , COUNTER_DESC . into ()) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_static_name_no_labels() { - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - None, - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_name (METRIC_NAME) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - ":: metrics :: recorder () . register_mytype (& METRIC_KEY , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_static_name_no_labels_target() { - let stream = get_register_and_op_code::( - Some(parse_quote! { "foo" }), - None, - "mytype", - parse_quote! {"mykeyname"}, - None, - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_name (METRIC_NAME) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (\"foo\" , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - ":: metrics :: recorder () . register_mytype (& METRIC_KEY , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_static_name_no_labels_level() { - let stream = get_register_and_op_code::( - None, - Some(parse_quote! { metrics::Level::TRACE }), - "mytype", - parse_quote! {"mykeyname"}, - None, - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_name (METRIC_NAME) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , metrics :: Level :: TRACE , Some (module_path ! ()) ,) ; ", - ":: metrics :: recorder () . register_mytype (& METRIC_KEY , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_static_name_static_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { "value1" })]); - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(labels), - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - - "static METRIC_LABELS : [:: metrics :: Label ; 1usize] = [:: metrics :: Label :: from_static_parts (\"key1\" , \"value1\")] ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_parts (METRIC_NAME , & METRIC_LABELS) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - ":: metrics :: recorder () . register_mytype (& METRIC_KEY , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_static_name_dynamic_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { &value1 })]); - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(labels), - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_parts (METRIC_NAME , vec ! [:: metrics :: Label :: new (\"key1\" , & value1)]) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -/// If there are dynamic labels - generate a direct invocation. -#[test] -fn test_get_register_and_op_code_register_static_name_existing_labels() { - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(Labels::Existing(parse_quote! { mylabels })), - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_parts (METRIC_NAME , mylabels) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_owned_name_no_labels() { - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - None, - None, - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_name (String :: from (\"owned\")) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_owned_name_static_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { "value1" })]); - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(labels), - None, - ); - - let expected = concat!( - "{ ", - "static METRIC_LABELS : [:: metrics :: Label ; 1usize] = [:: metrics :: Label :: from_static_parts (\"key1\" , \"value1\")] ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_static_labels (String :: from (\"owned\") , & METRIC_LABELS) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_register_owned_name_dynamic_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { &value1 })]); - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(labels), - None, - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_parts (String :: from (\"owned\") , vec ! [:: metrics :: Label :: new (\"key1\" , & value1)]) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -/// If there are dynamic labels - generate a direct invocation. -#[test] -fn test_get_register_and_op_code_register_owned_name_existing_labels() { - let stream = get_register_and_op_code::( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(Labels::Existing(parse_quote! { mylabels })), - None, - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "let key = :: metrics :: Key :: from_parts (String :: from (\"owned\") , mylabels) ; ", - ":: metrics :: recorder () . register_mytype (& key , & METADATA) ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_static_name_no_labels() { - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - None, - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_name (METRIC_NAME) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let handle = recorder . register_mytype (& METRIC_KEY , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_static_name_static_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { "value1" })]); - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(labels), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METRIC_LABELS : [:: metrics :: Label ; 1usize] = [:: metrics :: Label :: from_static_parts (\"key1\" , \"value1\")] ; ", - "static METRIC_KEY : :: metrics :: Key = :: metrics :: Key :: from_static_parts (METRIC_NAME , & METRIC_LABELS) ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let handle = recorder . register_mytype (& METRIC_KEY , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_static_name_dynamic_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { &value1 })]); - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(labels), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_parts (METRIC_NAME , vec ! [:: metrics :: Label :: new (\"key1\" , & value1)]) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -/// If there are dynamic labels - generate a direct invocation. -#[test] -fn test_get_register_and_op_code_op_static_name_existing_labels() { - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! {"mykeyname"}, - Some(Labels::Existing(parse_quote! { mylabels })), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METRIC_NAME : & 'static str = \"mykeyname\" ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_parts (METRIC_NAME , mylabels) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_owned_name_no_labels() { - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - None, - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_name (String :: from (\"owned\")) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_owned_name_static_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { "value1" })]); - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(labels), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METRIC_LABELS : [:: metrics :: Label ; 1usize] = [:: metrics :: Label :: from_static_parts (\"key1\" , \"value1\")] ; ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_static_labels (String :: from (\"owned\") , & METRIC_LABELS) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_owned_name_dynamic_inline_labels() { - let labels = Labels::Inline(vec![(parse_quote! { "key1" }, parse_quote! { &value1 })]); - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(labels), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_parts (String :: from (\"owned\") , vec ! [:: metrics :: Label :: new (\"key1\" , & value1)]) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -/// If there are dynamic labels - generate a direct invocation. -#[test] -fn test_get_register_and_op_code_op_owned_name_existing_labels() { - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(Labels::Existing(parse_quote! { mylabels })), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_parts (String :: from (\"owned\") , mylabels) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_get_register_and_op_code_op_owned_name_constant_key_labels() { - let stream = get_register_and_op_code( - None, - None, - "mytype", - parse_quote! { String::from("owned") }, - Some(Labels::Inline(vec![(parse_quote! { LABEL_KEY }, parse_quote! { "some_val" })])), - Some(("myop", quote! { 1 })), - ); - - let expected = concat!( - "{ ", - "static METADATA : :: metrics :: Metadata < 'static > = :: metrics :: Metadata :: new (module_path ! () , :: metrics :: Level :: INFO , Some (module_path ! ()) ,) ; ", - "if let Some (recorder) = :: metrics :: try_recorder () { ", - "let key = :: metrics :: Key :: from_parts (String :: from (\"owned\") , vec ! [:: metrics :: Label :: new (LABEL_KEY , \"some_val\")]) ; ", - "let handle = recorder . register_mytype (& key , & METADATA) ; ", - "handle . myop (1) ; ", - "} ", - "}", - ); - - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_labels_to_quoted_existing_labels() { - let labels = Labels::Existing(Expr::Path(parse_quote! { mylabels })); - let stream = labels_to_quoted(&labels); - let expected = "mylabels"; - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_labels_to_quoted_inline_labels() { - let labels = Labels::Inline(vec![ - (parse_quote! {"mylabel1"}, parse_quote! { mylabel1 }), - (parse_quote! {"mylabel2"}, parse_quote! { "mylabel2" }), - ]); - let stream = labels_to_quoted(&labels); - let expected = concat!( - "vec ! [", - ":: metrics :: Label :: new (\"mylabel1\" , mylabel1) , ", - ":: metrics :: Label :: new (\"mylabel2\" , \"mylabel2\")", - "]" - ); - assert_eq!(stream.to_string(), expected); -} - -#[test] -fn test_labels_to_quoted_inline_labels_empty() { - let labels = Labels::Inline(vec![]); - let stream = labels_to_quoted(&labels); - let expected = "vec ! []"; - assert_eq!(stream.to_string(), expected); -} diff --git a/metrics/Cargo.toml b/metrics/Cargo.toml index 50c213be..e16cabc3 100644 --- a/metrics/Cargo.toml +++ b/metrics/Cargo.toml @@ -24,11 +24,12 @@ name = "macros" harness = false [dependencies] -metrics-macros = { version = "^0.7", path = "../metrics-macros" } ahash = { version = "0.8", default-features = false } [target.'cfg(target_pointer_width = "32")'.dependencies] -portable-atomic = { version = "1", default-features = false, features = ["fallback"] } +portable-atomic = { version = "1", default-features = false, features = [ + "fallback", +] } [dev-dependencies] log = "0.4" From 8f57b8d3a9e32a016c0ad6b2721a3d885bfbbfc2 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Tue, 12 Sep 2023 00:52:27 +0100 Subject: [PATCH 19/24] fix broken documentation links --- metrics/src/macros.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 23c1e734..64592ce8 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -59,7 +59,7 @@ macro_rules! key_var { /// decremented, and always starts out with an initial value of zero. /// /// Metrics can be registered, which provides a handle to directly update that metric. For -/// counters, [`Counter`] is provided which can be incremented or set to an absolute value. +/// counters, [`Counter`](crate:Counter) is provided which can be incremented or set to an absolute value. /// /// Metric names are shown below using string literals, but they can also be owned `String` values, /// which includes using macros such as `format!` directly at the callsite. String literals are @@ -121,7 +121,7 @@ macro_rules! register_counter { /// initial value of zero. /// /// Metrics can be registered, which provides a handle to directly update that metric. For gauges, -/// [`Gauge`] is provided which can be incremented, decrement, or set to an absolute value. +/// [`Gauge`](crate::Gauge) is provided which can be incremented, decrement, or set to an absolute value. /// /// Metric names are shown below using string literals, but they can also be owned `String` values, /// which includes using macros such as `format!` directly at the callsite. String literals are @@ -184,7 +184,7 @@ macro_rules! register_gauge { /// initial values. /// /// Metrics can be registered, which provides a handle to directly update that metric. For -/// histograms, [`Histogram`] is provided which can record values. +/// histograms, [`Histogram`](crate::Histogram) is provided which can record values. /// /// Metric names are shown below using string literals, but they can also be owned `String` values, /// which includes using macros such as `format!` directly at the callsite. String literals are @@ -696,7 +696,7 @@ macro_rules! gauge { /// the duration. /// /// External libraries and applications can create their own conversions by implementing the -/// [`IntoF64`] trait for their types, which is required for the value being passed to `histogram!`. +/// [`IntoF64`](crate::IntoF64) trait for their types, which is required for the value being passed to `histogram!`. /// /// Metric names are shown below using string literals, but they can also be owned `String` values, /// which includes using macros such as `format!` directly at the callsite. String literals are From a901339b4c122d0c2486ba7e44031b80e097c786 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Tue, 12 Sep 2023 08:45:40 +0100 Subject: [PATCH 20/24] use `no_implicit_prelude` in doc tests --- metrics/src/macros.rs | 87 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 13 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 64592ce8..00b0d2c2 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -3,7 +3,7 @@ macro_rules! metadata_var { ($target:expr, $level:expr) => {{ static METADATA: $crate::Metadata<'static> = - $crate::Metadata::new($target, $level, Some(module_path!())); + $crate::Metadata::new($target, $level, ::core::option::Option::Some(module_path!())); &METADATA }}; } @@ -43,7 +43,7 @@ macro_rules! key_var { $crate::Key::from_static_labels($name, &LABELS) }}; ($name:expr, $($label_key:expr => $label_value:expr),*) => {{ - let labels = vec![ + let labels = ::std::vec![ $($crate::Label::new($label_key, $label_value)),* ]; $crate::Key::from_parts($name, labels) @@ -67,6 +67,10 @@ macro_rules! key_var { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::register_counter; /// # fn main() { /// // A basic counter: @@ -129,6 +133,10 @@ macro_rules! register_counter { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::string::String; +/// # use ::std::format; +/// # use ::std::convert::From; /// # use metrics::register_gauge; /// # fn main() { /// // A basic gauge: @@ -192,6 +200,10 @@ macro_rules! register_gauge { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::string::String; +/// # use ::std::format; +/// # use ::std::convert::From; /// # use metrics::register_histogram; /// # fn main() { /// // A basic histogram: @@ -243,12 +255,20 @@ macro_rules! register_histogram { macro_rules! describe { ($method:ident, $name:expr, $unit:expr, $description:expr) => {{ if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { - recorder.$method($name.into(), ::core::option::Option::Some($unit), $description.into()) + recorder.$method( + ::core::convert::Into::into($name), + ::core::option::Option::Some($unit), + ::core::convert::Into::into($description), + ) } }}; ($method:ident, $name:expr, $description:expr) => {{ - if let Some(recorder) = $crate::try_recorder() { - recorder.$method($name.into(), ::core::option::Option::None, $description.into()) + if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { + recorder.$method( + ::core::convert::Into::into($name), + ::core::option::Option::None, + ::core::convert::Into::into($description), + ) } }}; } @@ -268,6 +288,10 @@ macro_rules! describe { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::describe_counter; /// # use metrics::Unit; /// # fn main() { @@ -310,6 +334,10 @@ macro_rules! describe_counter { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::describe_gauge; /// # use metrics::Unit; /// # fn main() { @@ -352,6 +380,10 @@ macro_rules! describe_gauge { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::describe_histogram; /// # use metrics::Unit; /// # fn main() { @@ -382,11 +414,11 @@ macro_rules! describe_histogram { #[doc(hidden)] #[macro_export] macro_rules! method { - ($register:ident, $method:ident, target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { + ($register:ident, $method:ident, target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*); let metadata = $crate::metadata_var!($target, $level); - if let Some(recorder) = $crate::try_recorder() { + if let ::core::option::Option::Some(recorder) = $crate::try_recorder() { let handle = recorder.$register(&metric_key, &metadata); handle.$method($op_val); } @@ -413,6 +445,10 @@ macro_rules! method { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::{counter, Level}; /// # fn main() { /// // A basic counter: @@ -443,7 +479,7 @@ macro_rules! method { /// ``` #[macro_export] macro_rules! counter { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_counter, increment, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -468,6 +504,10 @@ macro_rules! counter { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::string::String; +/// # use ::std::format; /// # use metrics::{increment_gauge, Level}; /// # fn main() { /// // A basic gauge: @@ -498,7 +538,7 @@ macro_rules! counter { /// ``` #[macro_export] macro_rules! increment_gauge { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_gauge, increment, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -523,6 +563,10 @@ macro_rules! increment_gauge { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::{decrement_gauge, Level}; /// # fn main() { /// // A basic gauge: @@ -553,7 +597,7 @@ macro_rules! increment_gauge { /// ``` #[macro_export] macro_rules! decrement_gauge { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_gauge, decrement, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -585,6 +629,10 @@ macro_rules! decrement_gauge { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::{absolute_counter, Level}; /// # fn main() { /// // A basic counter: @@ -615,7 +663,7 @@ macro_rules! decrement_gauge { /// ``` #[macro_export] macro_rules! absolute_counter { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_counter, absolute, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -640,6 +688,10 @@ macro_rules! absolute_counter { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::{gauge, Level}; /// # fn main() { /// // A basic gauge: @@ -670,7 +722,7 @@ macro_rules! absolute_counter { /// ``` #[macro_export] macro_rules! gauge { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_gauge, set, target: $target, level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -704,6 +756,11 @@ macro_rules! gauge { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; +/// # use ::std as std; /// # use metrics::{histogram, Level}; /// # use std::time::Duration; /// # fn main() { @@ -739,7 +796,7 @@ macro_rules! gauge { /// ``` #[macro_export] macro_rules! histogram { - (target: $target:expr, level: $level:expr, $name:expr, $op_val: expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { + (target: $target:expr, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { $crate::method!(register_histogram, record, target: $target, level: $level, $name, $crate::__into_f64($op_val) $(, $label_key $(=> $label_value)?)*) }; (target: $target:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { @@ -764,6 +821,10 @@ macro_rules! histogram { /// /// # Example /// ``` +/// # #![no_implicit_prelude] +/// # use ::std::convert::From; +/// # use ::std::format; +/// # use ::std::string::String; /// # use metrics::{counter, Level}; /// # fn main() { /// // A basic counter: From 11b36bc8c00c91d8b15db9a4bcda67ebe74d6549 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 17 Sep 2023 17:25:07 +0100 Subject: [PATCH 21/24] replace `module_path` with `::std::module_path` --- metrics/src/macros.rs | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 00b0d2c2..54a94467 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -2,8 +2,11 @@ #[macro_export] macro_rules! metadata_var { ($target:expr, $level:expr) => {{ - static METADATA: $crate::Metadata<'static> = - $crate::Metadata::new($target, $level, ::core::option::Option::Some(module_path!())); + static METADATA: $crate::Metadata<'static> = $crate::Metadata::new( + $target, + $level, + ::core::option::Option::Some(::std::module_path!()), + ); &METADATA }}; } @@ -112,10 +115,10 @@ macro_rules! register_counter { $crate::register_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_counter!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_counter!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_counter!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_counter!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) }; } @@ -179,10 +182,10 @@ macro_rules! register_gauge { $crate::register_gauge!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_gauge!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_gauge!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_gauge!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_gauge!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) }; } @@ -243,10 +246,10 @@ macro_rules! register_histogram { $crate::register_histogram!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_histogram!(target: module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_histogram!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_histogram!(target: module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_histogram!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) }; } @@ -427,10 +430,10 @@ macro_rules! method { $crate::method!($register, $method, target: $target, level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($register:ident, $method:ident, level: $level:expr, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { - $crate::method!($register, $method, target: module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!($register, $method, target: ::std::module_path!(), level: $level, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; ($register:ident, $method:ident, $name:expr, $op_val:expr $(, $label_key:expr $(=> $label_value:expr)?)*) => { - $crate::method!($register, $method, target: module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) + $crate::method!($register, $method, target: ::std::module_path!(), level: $crate::Level::INFO, $name, $op_val $(, $label_key $(=> $label_value)?)*) }; } From 02f230f25d4b6b3ee0074fd8ee0fbd60a075dd26 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 17 Sep 2023 17:26:10 +0100 Subject: [PATCH 22/24] Fix `crate::Counter` doc link --- metrics/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 54a94467..67fc2c7e 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -62,7 +62,7 @@ macro_rules! key_var { /// decremented, and always starts out with an initial value of zero. /// /// Metrics can be registered, which provides a handle to directly update that metric. For -/// counters, [`Counter`](crate:Counter) is provided which can be incremented or set to an absolute value. +/// counters, [`Counter`](crate::Counter) is provided which can be incremented or set to an absolute value. /// /// Metric names are shown below using string literals, but they can also be owned `String` values, /// which includes using macros such as `format!` directly at the callsite. String literals are From d70bb0e6e58f01f8c5b224a98b511000db182261 Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 17 Sep 2023 17:28:41 +0100 Subject: [PATCH 23/24] improve consistency of spacing --- metrics/src/macros.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 67fc2c7e..6fc5ed81 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -115,10 +115,10 @@ macro_rules! register_counter { $crate::register_counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_counter!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_counter!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_counter!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_counter!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; } @@ -182,10 +182,10 @@ macro_rules! register_gauge { $crate::register_gauge!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_gauge!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_gauge!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_gauge!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_gauge!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; } @@ -246,10 +246,10 @@ macro_rules! register_histogram { $crate::register_histogram!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_histogram!(target: ::std::module_path!(), level: $level, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_histogram!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*) }; ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => { - $crate::register_histogram!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key$(=> $label_value)?)*) + $crate::register_histogram!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*) }; } From 28194901f7a6ed6e995248f87e8577536adc504a Mon Sep 17 00:00:00 2001 From: Harry Barber Date: Sun, 17 Sep 2023 17:30:18 +0100 Subject: [PATCH 24/24] remove redundant `&` --- metrics/src/macros.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics/src/macros.rs b/metrics/src/macros.rs index 6fc5ed81..ab1c0248 100644 --- a/metrics/src/macros.rs +++ b/metrics/src/macros.rs @@ -34,7 +34,7 @@ macro_rules! key_var { }; ($name:literal, $($label_key:literal => $label_value:literal),*) => {{ static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [ - $($crate::Label::from_static_parts(&$label_key, &$label_value)),* + $($crate::Label::from_static_parts($label_key, $label_value)),* ]; static METRIC_KEY: $crate::Key = $crate::Key::from_static_parts($name, &LABELS); &METRIC_KEY