metrics/
macros.rs

1#[doc(hidden)]
2#[macro_export]
3macro_rules! metadata_var {
4    ($target:expr, $level:expr) => {{
5        static METADATA: $crate::Metadata<'static> = $crate::Metadata::new(
6            $target,
7            $level,
8            ::core::option::Option::Some(::std::module_path!()),
9        );
10        &METADATA
11    }};
12}
13
14#[doc(hidden)]
15#[macro_export]
16macro_rules! count {
17    () => {
18        0usize
19    };
20    ($head:tt $($tail:tt)*) => {
21        1usize + $crate::count!($($tail)*)
22    };
23}
24
25#[doc(hidden)]
26#[macro_export]
27macro_rules! key_var {
28    ($name: literal) => {{
29        static METRIC_KEY: $crate::Key = $crate::Key::from_static_name($name);
30        &METRIC_KEY
31    }};
32    ($name:expr) => {
33        $crate::Key::from_name($name)
34    };
35    ($name:literal, $($label_key:literal => $label_value:literal),*) => {{
36        static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [
37            $($crate::Label::from_static_parts($label_key, $label_value)),*
38        ];
39        static METRIC_KEY: $crate::Key = $crate::Key::from_static_parts($name, &LABELS);
40        &METRIC_KEY
41    }};
42    ($name:expr, $($label_key:literal => $label_value:literal),*) => {{
43        static LABELS: [$crate::Label; $crate::count!($($label_key)*)] = [
44            $($crate::Label::from_static_parts($label_key, $label_value)),*
45        ];
46        $crate::Key::from_static_labels($name, &LABELS)
47    }};
48    ($name:expr, $($label_key:expr => $label_value:expr),*) => {{
49        let labels = ::std::vec![
50            $($crate::Label::new($label_key, $label_value)),*
51        ];
52        $crate::Key::from_parts($name, labels)
53    }};
54    ($name:expr, $labels:expr) => {
55        $crate::Key::from_parts($name, $labels)
56    }
57}
58
59/// Registers a counter.
60///
61/// Counters represent a single monotonic value, which means the value can only be incremented, not
62/// decremented, and always starts out with an initial value of zero.
63///
64/// Metrics can be registered, which provides a handle to directly update that metric.  For
65/// counters, [`Counter`](crate::Counter) is provided which can be incremented or set to an absolute value.
66///
67/// Metric names are shown below using string literals, but they can also be owned `String` values,
68/// which includes using macros such as `format!` directly at the callsite. String literals are
69/// preferred for performance where possible.
70///
71/// # Example
72/// ```
73/// # #![no_implicit_prelude]
74/// # use ::std::convert::From;
75/// # use ::std::format;
76/// # use ::std::string::String;
77/// # use metrics::counter;
78/// # fn main() {
79/// // A basic counter:
80/// let counter = counter!("some_metric_name");
81/// counter.increment(1);
82///
83/// // Specifying labels inline, including using constants for either the key or value:
84/// let counter = counter!("some_metric_name", "service" => "http");
85/// counter.absolute(42);
86///
87/// const SERVICE_LABEL: &'static str = "service";
88/// const SERVICE_HTTP: &'static str = "http";
89/// let counter = counter!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP);
90/// counter.increment(123);
91///
92/// // We can also pass labels by giving a vector or slice of key/value pairs.  In this scenario,
93/// // a unit or description can still be passed in their respective positions:
94/// let dynamic_val = "woo";
95/// let labels = [("dynamic_key", format!("{}!", dynamic_val))];
96/// let counter = counter!("some_metric_name", &labels);
97///
98/// // As mentioned in the documentation, metric names also can be owned strings, including ones
99/// // generated at the callsite via things like `format!`:
100/// let name = String::from("some_owned_metric_name");
101/// let counter = counter!(name);
102///
103/// let counter = counter!(format!("{}_via_format", "name"));
104/// # }
105/// ```
106#[macro_export]
107macro_rules! counter {
108    (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{
109        let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*);
110        let metadata = $crate::metadata_var!($target, $level);
111
112        $crate::with_recorder(|recorder| recorder.register_counter(&metric_key, metadata))
113    }};
114    (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
115        $crate::counter!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
116    };
117    (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
118        $crate::counter!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*)
119    };
120    ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
121        $crate::counter!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
122    };
123}
124
125/// Registers a gauge.
126///
127/// Gauges represent a single value that can go up or down over time, and always starts out with an
128/// initial value of zero.
129///
130/// Metrics can be registered, which provides a handle to directly update that metric.  For gauges,
131/// [`Gauge`](crate::Gauge) is provided which can be incremented, decrement, or set to an absolute value.
132///
133/// Metric names are shown below using string literals, but they can also be owned `String` values,
134/// which includes using macros such as `format!` directly at the callsite. String literals are
135/// preferred for performance where possible.
136///
137/// # Example
138/// ```
139/// # #![no_implicit_prelude]
140/// # use ::std::string::String;
141/// # use ::std::format;
142/// # use ::std::convert::From;
143/// # use metrics::gauge;
144/// # fn main() {
145/// // A basic gauge:
146/// let gauge = gauge!("some_metric_name");
147/// gauge.increment(1.0);
148///
149/// // Specifying labels inline, including using constants for either the key or value:
150/// let gauge = gauge!("some_metric_name", "service" => "http");
151/// gauge.decrement(42.0);
152///
153/// const SERVICE_LABEL: &'static str = "service";
154/// const SERVICE_HTTP: &'static str = "http";
155/// let gauge = gauge!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP);
156/// gauge.increment(3.14);
157///
158/// // We can also pass labels by giving a vector or slice of key/value pairs.  In this scenario,
159/// // a unit or description can still be passed in their respective positions:
160/// let dynamic_val = "woo";
161/// let labels = [("dynamic_key", format!("{}!", dynamic_val))];
162/// let gauge = gauge!("some_metric_name", &labels);
163/// gauge.set(1337.0);
164///
165/// // As mentioned in the documentation, metric names also can be owned strings, including ones
166/// // generated at the callsite via things like `format!`:
167/// let name = String::from("some_owned_metric_name");
168/// let gauge = gauge!(name);
169///
170/// let gauge = gauge!(format!("{}_via_format", "name"));
171/// # }
172/// ```
173#[macro_export]
174macro_rules! gauge {
175    (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{
176        let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*);
177        let metadata = $crate::metadata_var!($target, $level);
178
179        $crate::with_recorder(|recorder| recorder.register_gauge(&metric_key, metadata))
180    }};
181    (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
182        $crate::gauge!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
183    };
184    (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
185        $crate::gauge!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*)
186    };
187    ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
188        $crate::gauge!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
189    };
190}
191
192/// Registers a histogram.
193///
194/// Histograms measure the distribution of values for a given set of measurements, and start with no
195/// initial values.
196///
197/// Metrics can be registered, which provides a handle to directly update that metric.  For
198/// histograms, [`Histogram`](crate::Histogram) is provided which can record values.
199///
200/// Metric names are shown below using string literals, but they can also be owned `String` values,
201/// which includes using macros such as `format!` directly at the callsite. String literals are
202/// preferred for performance where possible.
203///
204/// # Example
205/// ```
206/// # #![no_implicit_prelude]
207/// # use ::std::string::String;
208/// # use ::std::format;
209/// # use ::std::convert::From;
210/// # use metrics::histogram;
211/// # fn main() {
212/// // A basic histogram:
213/// let histogram = histogram!("some_metric_name");
214/// histogram.record(1.0);
215///
216/// // Specifying labels inline, including using constants for either the key or value:
217/// let histogram = histogram!("some_metric_name", "service" => "http");
218///
219/// const SERVICE_LABEL: &'static str = "service";
220/// const SERVICE_HTTP: &'static str = "http";
221/// let histogram = histogram!("some_metric_name", SERVICE_LABEL => SERVICE_HTTP);
222///
223/// // We can also pass labels by giving a vector or slice of key/value pairs.  In this scenario,
224/// // a unit or description can still be passed in their respective positions:
225/// let dynamic_val = "woo";
226/// let labels = [("dynamic_key", format!("{}!", dynamic_val))];
227/// let histogram = histogram!("some_metric_name", &labels);
228///
229/// // As mentioned in the documentation, metric names also can be owned strings, including ones
230/// // generated at the callsite via things like `format!`:
231/// let name = String::from("some_owned_metric_name");
232/// let histogram = histogram!(name);
233///
234/// let histogram = histogram!(format!("{}_via_format", "name"));
235/// # }
236/// ```
237#[macro_export]
238macro_rules! histogram {
239    (target: $target:expr, level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {{
240        let metric_key = $crate::key_var!($name $(, $label_key $(=> $label_value)?)*);
241        let metadata = $crate::metadata_var!($target, $level);
242
243        $crate::with_recorder(|recorder| recorder.register_histogram(&metric_key, metadata))
244    }};
245    (target: $target:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
246        $crate::histogram!(target: $target, level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
247    };
248    (level: $level:expr, $name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
249        $crate::histogram!(target: ::std::module_path!(), level: $level, $name $(, $label_key $(=> $label_value)?)*)
250    };
251    ($name:expr $(, $label_key:expr $(=> $label_value:expr)?)* $(,)?) => {
252        $crate::histogram!(target: ::std::module_path!(), level: $crate::Level::INFO, $name $(, $label_key $(=> $label_value)?)*)
253    };
254}
255
256#[doc(hidden)]
257#[macro_export]
258macro_rules! describe {
259    ($method:ident, $name:expr, $unit:expr, $description:expr $(,)?) => {{
260        $crate::with_recorder(|recorder| {
261            recorder.$method(
262                ::core::convert::Into::into($name),
263                ::core::option::Option::Some($unit),
264                ::core::convert::Into::into($description),
265            );
266        });
267    }};
268    ($method:ident, $name:expr, $description:expr $(,)?) => {{
269        $crate::with_recorder(|recorder| {
270            recorder.$method(
271                ::core::convert::Into::into($name),
272                ::core::option::Option::None,
273                ::core::convert::Into::into($description),
274            );
275        });
276    }};
277}
278
279/// Describes a counter.
280///
281/// Counters represent a single monotonic value, which means the value can only be incremented, not
282/// decremented, and always starts out with an initial value of zero.
283///
284/// Metrics can be described with a free-form string, and optionally, a unit can be provided to
285/// describe the value and/or rate of the metric measurements.  Whether or not the installed
286/// recorder does anything with the description, or optional unit, is implementation defined.
287///
288/// Metric names are shown below using string literals, but they can also be owned `String` values,
289/// which includes using macros such as `format!` directly at the callsite. String literals are
290/// preferred for performance where possible.
291///
292/// # Example
293/// ```
294/// # #![no_implicit_prelude]
295/// # use ::std::convert::From;
296/// # use ::std::format;
297/// # use ::std::string::String;
298/// # use metrics::describe_counter;
299/// # use metrics::Unit;
300/// # fn main() {
301/// // A basic counter:
302/// describe_counter!("some_metric_name", "my favorite counter");
303///
304/// // Providing a unit for a counter:
305/// describe_counter!("some_metric_name", Unit::Bytes, "my favorite counter");
306///
307/// // As mentioned in the documentation, metric names also can be owned strings, including ones
308/// // generated at the callsite via things like `format!`:
309/// let name = String::from("some_owned_metric_name");
310/// describe_counter!(name, "my favorite counter");
311///
312/// describe_counter!(format!("{}_via_format", "name"), "my favorite counter");
313/// # }
314/// ```
315#[macro_export]
316macro_rules! describe_counter {
317    ($name:expr, $unit:expr, $description:expr $(,)?) => {
318        $crate::describe!(describe_counter, $name, $unit, $description)
319    };
320    ($name:expr, $description:expr $(,)?) => {
321        $crate::describe!(describe_counter, $name, $description)
322    };
323}
324
325/// Describes a gauge.
326///
327/// Gauges represent a single value that can go up or down over time, and always starts out with an
328/// initial value of zero.
329///
330/// Metrics can be described with a free-form string, and optionally, a unit can be provided to
331/// describe the value and/or rate of the metric measurements.  Whether or not the installed
332/// recorder does anything with the description, or optional unit, is implementation defined.
333///
334/// Metric names are shown below using string literals, but they can also be owned `String` values,
335/// which includes using macros such as `format!` directly at the callsite. String literals are
336/// preferred for performance where possible.
337///
338/// # Example
339/// ```
340/// # #![no_implicit_prelude]
341/// # use ::std::convert::From;
342/// # use ::std::format;
343/// # use ::std::string::String;
344/// # use metrics::describe_gauge;
345/// # use metrics::Unit;
346/// # fn main() {
347/// // A basic gauge:
348/// describe_gauge!("some_metric_name", "my favorite gauge");
349///
350/// // Providing a unit for a gauge:
351/// describe_gauge!("some_metric_name", Unit::Bytes, "my favorite gauge");
352///
353/// // As mentioned in the documentation, metric names also can be owned strings, including ones
354/// // generated at the callsite via things like `format!`:
355/// let name = String::from("some_owned_metric_name");
356/// describe_gauge!(name, "my favorite gauge");
357///
358/// describe_gauge!(format!("{}_via_format", "name"), "my favorite gauge");
359/// # }
360/// ```
361#[macro_export]
362macro_rules! describe_gauge {
363    ($name:expr, $unit:expr, $description:expr $(,)?) => {
364        $crate::describe!(describe_gauge, $name, $unit, $description)
365    };
366    ($name:expr, $description:expr $(,)?) => {
367        $crate::describe!(describe_gauge, $name, $description)
368    };
369}
370
371/// Describes a histogram.
372///
373/// Histograms measure the distribution of values for a given set of measurements, and start with no
374/// initial values.
375///
376/// Metrics can be described with a free-form string, and optionally, a unit can be provided to
377/// describe the value and/or rate of the metric measurements.  Whether or not the installed
378/// recorder does anything with the description, or optional unit, is implementation defined.
379///
380/// Metric names are shown below using string literals, but they can also be owned `String` values,
381/// which includes using macros such as `format!` directly at the callsite. String literals are
382/// preferred for performance where possible.
383///
384/// # Example
385/// ```
386/// # #![no_implicit_prelude]
387/// # use ::std::convert::From;
388/// # use ::std::format;
389/// # use ::std::string::String;
390/// # use metrics::describe_histogram;
391/// # use metrics::Unit;
392/// # fn main() {
393/// // A basic histogram:
394/// describe_histogram!("some_metric_name", "my favorite histogram");
395///
396/// // Providing a unit for a histogram:
397/// describe_histogram!("some_metric_name", Unit::Bytes, "my favorite histogram");
398///
399/// // As mentioned in the documentation, metric names also can be owned strings, including ones
400/// // generated at the callsite via things like `format!`:
401/// let name = String::from("some_owned_metric_name");
402/// describe_histogram!(name, "my favorite histogram");
403///
404/// describe_histogram!(format!("{}_via_format", "name"), "my favorite histogram");
405/// # }
406/// ```
407#[macro_export]
408macro_rules! describe_histogram {
409    ($name:expr, $unit:expr, $description:expr $(,)?) => {
410        $crate::describe!(describe_histogram, $name, $unit, $description)
411    };
412    ($name:expr, $description:expr $(,)?) => {
413        $crate::describe!(describe_histogram, $name, $description)
414    };
415}