prometheus/
macros.rs

1// Copyright 2019 TiKV Project Authors. Licensed under Apache-2.0.
2
3/// Create labels with specified name-value pairs.
4///
5/// # Examples
6///
7/// ```
8/// # use std::collections::HashMap;
9/// # use prometheus::labels;
10/// # fn main() {
11/// let labels = labels!{
12///     "test" => "hello",
13///     "foo" => "bar",
14/// };
15/// assert_eq!(labels.len(), 2);
16/// assert!(labels.get("test").is_some());
17/// assert_eq!(*(labels.get("test").unwrap()), "hello");
18///
19/// let labels: HashMap<&str, &str> = labels!{};
20/// assert!(labels.is_empty());
21/// # }
22/// ```
23#[macro_export]
24macro_rules! labels {
25    ( $( $ KEY : expr => $ VALUE : expr ),* $(,)? ) => {
26        {
27            use std::collections::HashMap;
28
29            let mut lbs = HashMap::new();
30            $(
31                lbs.insert($KEY, $VALUE);
32            )*
33
34            lbs
35        }
36    };
37}
38
39#[test]
40fn test_labels_without_trailing_comma() {
41    let labels = labels! {
42        "test" => "hello",
43        "foo" => "bar"
44    };
45    assert_eq!(labels.len(), 2);
46    assert!(labels.get("test").is_some());
47    assert_eq!(*(labels.get("test").unwrap()), "hello");
48}
49
50/// Create an [`Opts`][crate::Opts].
51///
52/// # Examples
53///
54/// ```
55/// # use prometheus::{labels, opts};
56/// # fn main() {
57/// let name = "test_opts";
58/// let help = "test opts help";
59///
60/// let opts = opts!(name, help);
61/// assert_eq!(opts.name, name);
62/// assert_eq!(opts.help, help);
63///
64/// let opts = opts!(name, help, labels!{"test" => "hello", "foo" => "bar",});
65/// assert_eq!(opts.const_labels.len(), 2);
66/// assert!(opts.const_labels.get("foo").is_some());
67/// assert_eq!(opts.const_labels.get("foo").unwrap(), "bar");
68///
69/// let opts = opts!(name,
70///                  help,
71///                  labels!{"test" => "hello", "foo" => "bar",},
72///                  labels!{"ans" => "42",});
73/// assert_eq!(opts.const_labels.len(), 3);
74/// assert!(opts.const_labels.get("ans").is_some());
75/// assert_eq!(opts.const_labels.get("ans").unwrap(), "42");
76/// # }
77/// ```
78#[macro_export]
79macro_rules! opts {
80    ( $ NAME : expr , $ HELP : expr $ ( , $ CONST_LABELS : expr ) * $ ( , ) ? ) => {
81        {
82            use std::collections::HashMap;
83
84            let opts = $crate::Opts::new($NAME, $HELP);
85            let lbs = HashMap::<String, String>::new();
86            $(
87                let mut lbs = lbs;
88                lbs.extend($CONST_LABELS.iter().map(|(k, v)| ((*k).into(), (*v).into())));
89            )*
90
91            opts.const_labels(lbs)
92        }
93    }
94}
95
96#[test]
97fn test_opts_trailing_comma() {
98    let name = "test_opts";
99    let help = "test opts help";
100
101    let opts = opts!(name, help,);
102    assert_eq!(opts.name, name);
103    assert_eq!(opts.help, help);
104
105    let opts = opts!(name, help, labels! {"test" => "hello", "foo" => "bar",},);
106    assert_eq!(opts.const_labels.len(), 2);
107    assert!(opts.const_labels.get("foo").is_some());
108    assert_eq!(opts.const_labels.get("foo").unwrap(), "bar");
109
110    let opts = opts!(
111        name,
112        help,
113        labels! {"test" => "hello", "foo" => "bar",},
114        labels! {"ans" => "42",},
115    );
116    assert_eq!(opts.const_labels.len(), 3);
117    assert!(opts.const_labels.get("ans").is_some());
118    assert_eq!(opts.const_labels.get("ans").unwrap(), "42");
119}
120
121/// Create a [`HistogramOpts`][crate::HistogramOpts].
122///
123/// # Examples
124///
125/// ```
126/// # use prometheus::linear_buckets;
127/// # use prometheus::{histogram_opts, labels};
128/// # fn main() {
129/// let name = "test_histogram_opts";
130/// let help = "test opts help";
131///
132/// let opts = histogram_opts!(name, help);
133/// assert_eq!(opts.common_opts.name, name);
134/// assert_eq!(opts.common_opts.help, help);
135///
136/// let opts = histogram_opts!(name, help, linear_buckets(1.0, 0.5, 4).unwrap());
137/// assert_eq!(opts.common_opts.name, name);
138/// assert_eq!(opts.common_opts.help, help);
139/// assert_eq!(opts.buckets.len(), 4);
140///
141/// let opts = histogram_opts!(name,
142///                            help,
143///                            vec![1.0, 2.0],
144///                            labels!{"key".to_string() => "value".to_string(),});
145/// assert_eq!(opts.common_opts.name, name);
146/// assert_eq!(opts.common_opts.help, help);
147/// assert_eq!(opts.buckets.len(), 2);
148/// assert!(opts.common_opts.const_labels.get("key").is_some());
149/// assert_eq!(opts.common_opts.const_labels.get("key").unwrap(), "value");
150/// # }
151/// ```
152#[macro_export(local_inner_macros)]
153macro_rules! histogram_opts {
154    ($NAME:expr, $HELP:expr $(,)?) => {{
155        $crate::HistogramOpts::new($NAME, $HELP)
156    }};
157
158    ($NAME:expr, $HELP:expr, $BUCKETS:expr $(,)?) => {{
159        let hopts = histogram_opts!($NAME, $HELP);
160        hopts.buckets($BUCKETS)
161    }};
162
163    ($NAME:expr, $HELP:expr, $BUCKETS:expr, $CONST_LABELS:expr $(,)?) => {{
164        let hopts = histogram_opts!($NAME, $HELP, $BUCKETS);
165        hopts.const_labels($CONST_LABELS)
166    }};
167}
168
169#[test]
170fn test_histogram_opts_trailing_comma() {
171    use crate::linear_buckets;
172
173    let name = "test_histogram_opts";
174    let help = "test opts help";
175
176    let opts = histogram_opts!(name, help,);
177    assert_eq!(opts.common_opts.name, name);
178    assert_eq!(opts.common_opts.help, help);
179
180    let opts = histogram_opts!(name, help, linear_buckets(1.0, 0.5, 4).unwrap(),);
181    assert_eq!(opts.common_opts.name, name);
182    assert_eq!(opts.common_opts.help, help);
183    assert_eq!(opts.buckets.len(), 4);
184
185    let opts = histogram_opts!(
186        name,
187        help,
188        vec![1.0, 2.0],
189        labels! {"key".to_string() => "value".to_string(),},
190    );
191    assert_eq!(opts.common_opts.name, name);
192    assert_eq!(opts.common_opts.help, help);
193    assert_eq!(opts.buckets.len(), 2);
194    assert!(opts.common_opts.const_labels.get("key").is_some());
195    assert_eq!(opts.common_opts.const_labels.get("key").unwrap(), "value");
196}
197
198/// Create a [`Counter`][crate::Counter] and registers to default registry.
199///
200/// # Examples
201///
202/// ```
203/// # use prometheus::{opts, register_counter};
204/// # fn main() {
205/// let opts = opts!("test_macro_counter_1", "help");
206/// let res1 = register_counter!(opts);
207/// assert!(res1.is_ok());
208///
209/// let res2 = register_counter!("test_macro_counter_2", "help");
210/// assert!(res2.is_ok());
211/// # }
212/// ```
213#[macro_export(local_inner_macros)]
214macro_rules! register_counter {
215    (@of_type $TYPE:ident, $OPTS:expr) => {{
216        let counter = $crate::$TYPE::with_opts($OPTS).unwrap();
217        $crate::register(Box::new(counter.clone())).map(|()| counter)
218    }};
219
220    ($OPTS:expr $(,)?) => {{
221        register_counter!(@of_type Counter, $OPTS)
222    }};
223
224    ($NAME:expr, $HELP:expr $(,)?) => {{
225        register_counter!(opts!($NAME, $HELP))
226    }};
227}
228
229#[test]
230fn test_register_counter_trailing_comma() {
231    let opts = opts!("test_macro_counter_1", "help",);
232    let res1 = register_counter!(opts,);
233    assert!(res1.is_ok());
234
235    let res2 = register_counter!("test_macro_counter_2", "help",);
236    assert!(res2.is_ok());
237}
238
239/// Create a [`Counter`][crate::Counter] and registers to a custom registry.
240///
241/// # Examples
242///
243/// ```
244/// # use prometheus::{register_counter_with_registry, opts};
245/// # use prometheus::Registry;
246/// # use std::collections::HashMap;
247/// # fn main() {
248/// let mut labels = HashMap::new();
249/// labels.insert("mykey".to_string(), "myvalue".to_string());
250/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
251/// let opts = opts!("test_macro_counter_1", "help");
252/// let res1 = register_counter_with_registry!(opts, custom_registry);
253/// assert!(res1.is_ok());
254///
255/// let res2 = register_counter_with_registry!("test_macro_counter_2", "help", custom_registry);
256/// assert!(res2.is_ok());
257/// # }
258/// ```
259#[macro_export(local_inner_macros)]
260macro_rules! register_counter_with_registry {
261    (@of_type $TYPE: ident, $OPTS:expr, $REGISTRY:expr) => {{
262        let counter = $crate::$TYPE::with_opts($OPTS).unwrap();
263        $REGISTRY.register(Box::new(counter.clone())).map(|()| counter)
264    }};
265
266    ($OPTS:expr, $REGISTRY:expr $(,)?) => {{
267        register_counter_with_registry!(@of_type Counter, $OPTS, $REGISTRY)
268    }};
269
270    ($NAME:expr, $HELP:expr, $REGISTRY:expr $(,)?) => {{
271        register_counter_with_registry!(opts!($NAME, $HELP), $REGISTRY)
272    }};
273}
274
275#[test]
276fn test_register_counter_with_registry_trailing_comma() {
277    use crate::Registry;
278    use std::collections::HashMap;
279
280    let mut labels = HashMap::new();
281    labels.insert("mykey".to_string(), "myvalue".to_string());
282    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
283    let opts = opts!("test_macro_counter_1", "help",);
284    let res1 = register_counter_with_registry!(opts, custom_registry,);
285    assert!(res1.is_ok());
286
287    let res2 = register_counter_with_registry!("test_macro_counter_2", "help", custom_registry,);
288    assert!(res2.is_ok());
289}
290
291/// Create an [`IntCounter`][crate::IntCounter] and registers to default registry.
292///
293/// View docs of `register_counter` for examples.
294#[macro_export(local_inner_macros)]
295macro_rules! register_int_counter {
296    ($OPTS:expr $(,)?) => {{
297        register_counter!(@of_type IntCounter, $OPTS)
298    }};
299
300    ($NAME:expr, $HELP:expr $(,)?) => {{
301        register_int_counter!(opts!($NAME, $HELP))
302    }};
303}
304
305/// Create an [`IntCounter`][crate::IntCounter] and registers to a custom registry.
306///
307/// View docs of `register_counter_with_registry` for examples.
308#[macro_export(local_inner_macros)]
309macro_rules! register_int_counter_with_registry {
310    ($OPTS:expr, $REGISTRY:expr $(,)?) => {{
311        register_counter_with_registry!(@of_type IntCounter, $OPTS, $REGISTRY)
312    }};
313
314    ($NAME:expr, $HELP:expr, $REGISTRY:expr $(,)?) => {{
315        register_int_counter_with_registry!(opts!($NAME, $HELP), $REGISTRY)
316    }};
317}
318
319#[test]
320fn test_register_int_counter() {
321    use crate::Registry;
322    use std::collections::HashMap;
323
324    let opts = opts!("test_opts_int_counter_1", "help");
325    let res = register_int_counter!(opts);
326    assert!(res.is_ok());
327
328    let res = register_int_counter!("test_opts_int_counter_2", "help");
329    assert!(res.is_ok());
330
331    let opts = opts!("test_opts_int_counter_3", "help",);
332    let res = register_int_counter!(opts,);
333    assert!(res.is_ok());
334
335    let res = register_int_counter!("test_opts_int_counter_4", "help",);
336    assert!(res.is_ok());
337
338    let mut labels = HashMap::new();
339    labels.insert("mykey".to_string(), "myvalue".to_string());
340    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
341
342    let opts = opts!("test_opts_int_counter_1", "help");
343    let res = register_int_counter_with_registry!(opts, custom_registry);
344    assert!(res.is_ok());
345
346    let res =
347        register_int_counter_with_registry!("test_opts_int_counter_2", "help", custom_registry);
348    assert!(res.is_ok());
349
350    let opts = opts!("test_opts_int_counter_3", "help");
351    let res = register_int_counter_with_registry!(opts, custom_registry,);
352    assert!(res.is_ok());
353
354    let res =
355        register_int_counter_with_registry!("test_opts_int_counter_4", "help", custom_registry,);
356    assert!(res.is_ok());
357}
358
359#[macro_export]
360#[doc(hidden)]
361macro_rules! __register_counter_vec {
362    ($TYPE:ident, $OPTS:expr, $LABELS_NAMES:expr) => {{
363        let counter_vec = $crate::$TYPE::new($OPTS, $LABELS_NAMES).unwrap();
364        $crate::register(Box::new(counter_vec.clone())).map(|()| counter_vec)
365    }};
366
367    ($TYPE:ident, $OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr) => {{
368        let counter_vec = $crate::$TYPE::new($OPTS, $LABELS_NAMES).unwrap();
369        $REGISTRY
370            .register(Box::new(counter_vec.clone()))
371            .map(|()| counter_vec)
372    }};
373}
374
375/// Create a [`CounterVec`][crate::CounterVec] and registers to default registry.
376///
377/// # Examples
378///
379/// ```
380/// # use prometheus::{opts, register_counter_vec};
381/// # fn main() {
382/// let opts = opts!("test_macro_counter_vec_1", "help");
383/// let counter_vec = register_counter_vec!(opts, &["a", "b"]);
384/// assert!(counter_vec.is_ok());
385///
386/// let counter_vec = register_counter_vec!("test_macro_counter_vec_2", "help", &["a", "b"]);
387/// assert!(counter_vec.is_ok());
388/// # }
389/// ```
390#[macro_export(local_inner_macros)]
391macro_rules! register_counter_vec {
392    ($OPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
393        __register_counter_vec!(CounterVec, $OPTS, $LABELS_NAMES)
394    }};
395
396    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr $(,)?) => {{
397        register_counter_vec!(opts!($NAME, $HELP), $LABELS_NAMES)
398    }};
399}
400
401#[test]
402fn test_register_counter_vec_trailing_comma() {
403    let opts = opts!("test_macro_counter_vec_1", "help",);
404    let counter_vec = register_counter_vec!(opts, &["a", "b"],);
405    assert!(counter_vec.is_ok());
406
407    let counter_vec = register_counter_vec!("test_macro_counter_vec_2", "help", &["a", "b"],);
408    assert!(counter_vec.is_ok());
409}
410
411/// Create a [`CounterVec`][crate::CounterVec] and registers to a custom registry.
412///
413/// # Examples
414///
415/// ```
416/// # use prometheus::{register_counter_vec_with_registry, opts};
417/// # use prometheus::Registry;
418/// # use std::collections::HashMap;
419/// # fn main() {
420/// let mut labels = HashMap::new();
421/// labels.insert("mykey".to_string(), "myvalue".to_string());
422/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
423///
424/// let opts = opts!("test_macro_counter_vec_1", "help");
425/// let counter_vec = register_counter_vec_with_registry!(opts, &["a", "b"], custom_registry);
426/// assert!(counter_vec.is_ok());
427///
428/// let counter_vec = register_counter_vec_with_registry!("test_macro_counter_vec_2", "help", &["a", "b"], custom_registry);
429/// assert!(counter_vec.is_ok());
430/// # }
431/// ```
432#[macro_export(local_inner_macros)]
433macro_rules! register_counter_vec_with_registry {
434    ($OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
435        __register_counter_vec!(CounterVec, $OPTS, $LABELS_NAMES, $REGISTRY)
436    }};
437
438    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
439        register_counter_vec_with_registry!(opts!($NAME, $HELP), $LABELS_NAMES, $REGISTRY)
440    }};
441}
442
443#[test]
444fn test_register_counter_vec_with_registry_trailing_comma() {
445    use crate::Registry;
446    use std::collections::HashMap;
447
448    let mut labels = HashMap::new();
449    labels.insert("mykey".to_string(), "myvalue".to_string());
450    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
451
452    let opts = opts!("test_macro_counter_vec_1", "help",);
453    let counter_vec = register_counter_vec_with_registry!(opts, &["a", "b"], custom_registry,);
454    assert!(counter_vec.is_ok());
455
456    let counter_vec = register_counter_vec_with_registry!(
457        "test_macro_counter_vec_2",
458        "help",
459        &["a", "b"],
460        custom_registry,
461    );
462    assert!(counter_vec.is_ok());
463}
464
465/// Create an [`IntCounterVec`][crate::IntCounterVec] and registers to default registry.
466///
467/// View docs of `register_counter_vec` for examples.
468#[macro_export(local_inner_macros)]
469macro_rules! register_int_counter_vec {
470    ($OPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
471        __register_counter_vec!(IntCounterVec, $OPTS, $LABELS_NAMES)
472    }};
473
474    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr $(,)?) => {{
475        register_int_counter_vec!(opts!($NAME, $HELP), $LABELS_NAMES)
476    }};
477}
478
479/// Create an [`IntCounterVec`][crate::IntCounterVec] and registers to a custom registry.
480///
481/// View docs of `register_counter_vec_with_registry` for examples.
482#[macro_export(local_inner_macros)]
483macro_rules! register_int_counter_vec_with_registry {
484    ($OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
485        __register_counter_vec!(IntCounterVec, $OPTS, $LABELS_NAMES, $REGISTRY)
486    }};
487
488    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
489        register_int_counter_vec_with_registry!(opts!($NAME, $HELP), $LABELS_NAMES, $REGISTRY)
490    }};
491}
492
493#[test]
494fn test_register_int_counter_vec() {
495    use crate::Registry;
496    use std::collections::HashMap;
497
498    let opts = opts!("test_opts_int_counter_vec_1", "help");
499    let res = register_int_counter_vec!(opts, &["a", "b"]);
500    assert!(res.is_ok());
501
502    let res = register_int_counter_vec!("test_opts_int_counter_vec_2", "help", &["a", "b"]);
503    assert!(res.is_ok());
504
505    let opts = opts!("test_opts_int_counter_vec_3", "help",);
506    let res = register_int_counter_vec!(opts, &["a", "b"],);
507    assert!(res.is_ok());
508
509    let res = register_int_counter_vec!("test_opts_int_counter_vec_4", "help", &["a", "b"],);
510    assert!(res.is_ok());
511
512    let mut labels = HashMap::new();
513    labels.insert("mykey".to_string(), "myvalue".to_string());
514    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
515
516    let opts = opts!("test_opts_int_counter_vec_1", "help");
517    let res = register_int_counter_vec_with_registry!(opts, &["a", "b"], custom_registry);
518    assert!(res.is_ok());
519
520    let res = register_int_counter_vec_with_registry!(
521        "test_opts_int_counter_vec_2",
522        "help",
523        &["a", "b"],
524        custom_registry
525    );
526    assert!(res.is_ok());
527
528    let opts = opts!("test_opts_int_counter_vec_3", "help");
529    let res = register_int_counter_vec_with_registry!(opts, &["a", "b"], custom_registry,);
530    assert!(res.is_ok());
531
532    let res = register_int_counter_vec_with_registry!(
533        "test_opts_int_counter_vec_4",
534        "help",
535        &["a", "b"],
536        custom_registry,
537    );
538    assert!(res.is_ok());
539}
540
541#[macro_export]
542#[doc(hidden)]
543macro_rules! __register_gauge {
544    ($TYPE:ident, $OPTS:expr) => {{
545        let gauge = $crate::$TYPE::with_opts($OPTS).unwrap();
546        $crate::register(Box::new(gauge.clone())).map(|()| gauge)
547    }};
548
549    ($TYPE:ident, $OPTS:expr, $REGISTRY:expr) => {{
550        let gauge = $crate::$TYPE::with_opts($OPTS).unwrap();
551        $REGISTRY.register(Box::new(gauge.clone())).map(|()| gauge)
552    }};
553}
554
555/// Create a [`Gauge`][crate::Gauge] and registers to default registry.
556///
557/// # Examples
558///
559/// ```
560/// # use prometheus::{opts, register_gauge};
561/// # fn main() {
562/// let opts = opts!("test_macro_gauge", "help");
563/// let res1 = register_gauge!(opts);
564/// assert!(res1.is_ok());
565///
566/// let res2 = register_gauge!("test_macro_gauge_2", "help");
567/// assert!(res2.is_ok());
568/// # }
569/// ```
570#[macro_export(local_inner_macros)]
571macro_rules! register_gauge {
572    ($OPTS:expr $(,)?) => {{
573        __register_gauge!(Gauge, $OPTS)
574    }};
575
576    ($NAME:expr, $HELP:expr $(,)?) => {{
577        register_gauge!(opts!($NAME, $HELP))
578    }};
579}
580
581#[test]
582fn test_register_gauge_trailing_comma() {
583    let opts = opts!("test_macro_gauge", "help",);
584    let res1 = register_gauge!(opts,);
585    assert!(res1.is_ok());
586
587    let res2 = register_gauge!("test_macro_gauge_2", "help",);
588    assert!(res2.is_ok());
589}
590
591/// Create a [`Gauge`][crate::Gauge] and registers to a custom registry.
592///
593/// # Examples
594///
595/// ```
596/// # use prometheus::{register_gauge_with_registry, opts};
597/// # use prometheus::Registry;
598/// # use std::collections::HashMap;
599/// # fn main() {
600/// let mut labels = HashMap::new();
601/// labels.insert("mykey".to_string(), "myvalue".to_string());
602/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
603///
604/// let opts = opts!("test_macro_gauge", "help");
605/// let res1 = register_gauge_with_registry!(opts, custom_registry);
606/// assert!(res1.is_ok());
607///
608/// let res2 = register_gauge_with_registry!("test_macro_gauge_2", "help", custom_registry);
609/// assert!(res2.is_ok());
610/// # }
611/// ```
612#[macro_export(local_inner_macros)]
613macro_rules! register_gauge_with_registry {
614    ($OPTS:expr, $REGISTRY:expr $(,)?) => {{
615        __register_gauge!(Gauge, $OPTS, $REGISTRY)
616    }};
617
618    ($NAME:expr, $HELP:expr, $REGISTRY:expr $(,)?) => {{
619        register_gauge_with_registry!(opts!($NAME, $HELP), $REGISTRY)
620    }};
621}
622
623#[test]
624fn test_register_gauge_with_registry_trailing_comma() {
625    use crate::Registry;
626    use std::collections::HashMap;
627
628    let mut labels = HashMap::new();
629    labels.insert("mykey".to_string(), "myvalue".to_string());
630    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
631
632    let opts = opts!("test_macro_gauge", "help",);
633    let res1 = register_gauge_with_registry!(opts, custom_registry,);
634    assert!(res1.is_ok());
635
636    let res2 = register_gauge_with_registry!("test_macro_gauge_2", "help", custom_registry,);
637    assert!(res2.is_ok());
638}
639
640/// Create an [`IntGauge`][crate::IntGauge] and registers to default registry.
641///
642/// View docs of `register_gauge` for examples.
643#[macro_export(local_inner_macros)]
644macro_rules! register_int_gauge {
645    ($OPTS:expr $(,)?) => {{
646        __register_gauge!(IntGauge, $OPTS)
647    }};
648
649    ($NAME:expr, $HELP:expr $(,)?) => {{
650        register_int_gauge!(opts!($NAME, $HELP))
651    }};
652}
653
654/// Create an [`IntGauge`][crate::IntGauge] and registers to a custom registry.
655///
656/// View docs of `register_gauge_with_registry` for examples.
657#[macro_export(local_inner_macros)]
658macro_rules! register_int_gauge_with_registry {
659    ($OPTS:expr, $REGISTRY:expr $(,)?) => {{
660        __register_gauge!(IntGauge, $OPTS, $REGISTRY)
661    }};
662
663    ($NAME:expr, $HELP:expr, $REGISTRY:expr $(,)?) => {{
664        register_int_gauge_with_registry!(opts!($NAME, $HELP), $REGISTRY)
665    }};
666}
667
668#[macro_export]
669#[doc(hidden)]
670macro_rules! __register_gauge_vec {
671    ($TYPE:ident, $OPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
672        let gauge_vec = $crate::$TYPE::new($OPTS, $LABELS_NAMES).unwrap();
673        $crate::register(Box::new(gauge_vec.clone())).map(|()| gauge_vec)
674    }};
675
676    ($TYPE:ident, $OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
677        let gauge_vec = $crate::$TYPE::new($OPTS, $LABELS_NAMES).unwrap();
678        $REGISTRY
679            .register(Box::new(gauge_vec.clone()))
680            .map(|()| gauge_vec)
681    }};
682}
683
684#[test]
685fn test_register_int_gauge() {
686    use crate::Registry;
687    use std::collections::HashMap;
688
689    let opts = opts!("test_opts_int_gauge_1", "help");
690    let res = register_int_gauge!(opts);
691    assert!(res.is_ok());
692
693    let res = register_int_gauge!("test_opts_int_gauge_2", "help");
694    assert!(res.is_ok());
695
696    let opts = opts!("test_opts_int_gauge_3", "help",);
697    let res = register_int_gauge!(opts,);
698    assert!(res.is_ok());
699
700    let res = register_int_gauge!("test_opts_int_gauge_4", "help",);
701    assert!(res.is_ok());
702
703    let mut labels = HashMap::new();
704    labels.insert("mykey".to_string(), "myvalue".to_string());
705    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
706
707    let opts = opts!("test_opts_int_gauge_1", "help");
708    let res = register_int_gauge_with_registry!(opts, custom_registry);
709    assert!(res.is_ok());
710
711    let res = register_int_gauge_with_registry!("test_opts_int_gauge_2", "help", custom_registry);
712    assert!(res.is_ok());
713
714    let opts = opts!("test_opts_int_gauge_3", "help");
715    let res = register_int_gauge_with_registry!(opts, custom_registry,);
716    assert!(res.is_ok());
717
718    let res = register_int_gauge_with_registry!("test_opts_int_gauge_4", "help", custom_registry,);
719    assert!(res.is_ok());
720}
721
722/// Create a [`GaugeVec`][crate::GaugeVec] and registers to default registry.
723///
724/// # Examples
725///
726/// ```
727/// # use prometheus::{opts, register_gauge_vec};
728/// # fn main() {
729/// let opts = opts!("test_macro_gauge_vec_1", "help");
730/// let gauge_vec = register_gauge_vec!(opts, &["a", "b"]);
731/// assert!(gauge_vec.is_ok());
732///
733/// let gauge_vec = register_gauge_vec!("test_macro_gauge_vec_2", "help", &["a", "b"]);
734/// assert!(gauge_vec.is_ok());
735/// # }
736/// ```
737#[macro_export(local_inner_macros)]
738macro_rules! register_gauge_vec {
739    ($OPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
740        __register_gauge_vec!(GaugeVec, $OPTS, $LABELS_NAMES)
741    }};
742
743    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr $(,)?) => {{
744        register_gauge_vec!(opts!($NAME, $HELP), $LABELS_NAMES)
745    }};
746}
747
748#[test]
749fn test_register_gauge_vec_trailing_comma() {
750    let opts = opts!("test_macro_gauge_vec_1", "help",);
751    let gauge_vec = register_gauge_vec!(opts, &["a", "b"],);
752    assert!(gauge_vec.is_ok());
753
754    let gauge_vec = register_gauge_vec!("test_macro_gauge_vec_2", "help", &["a", "b"],);
755    assert!(gauge_vec.is_ok());
756}
757
758/// Create a [`GaugeVec`][crate::GaugeVec] and registers to a custom registry.
759///
760/// # Examples
761///
762/// ```
763/// # use prometheus::{register_gauge_vec_with_registry, opts};
764/// # use prometheus::Registry;
765/// # use std::collections::HashMap;
766/// # fn main() {
767/// let mut labels = HashMap::new();
768/// labels.insert("mykey".to_string(), "myvalue".to_string());
769/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
770///
771/// let opts = opts!("test_macro_gauge_vec_1", "help");
772/// let gauge_vec = register_gauge_vec_with_registry!(opts, &["a", "b"], custom_registry);
773/// assert!(gauge_vec.is_ok());
774///
775/// let gauge_vec = register_gauge_vec_with_registry!("test_macro_gauge_vec_2", "help", &["a", "b"], custom_registry);
776/// assert!(gauge_vec.is_ok());
777/// # }
778/// ```
779#[macro_export(local_inner_macros)]
780macro_rules! register_gauge_vec_with_registry {
781    ($OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
782        __register_gauge_vec!(GaugeVec, $OPTS, $LABELS_NAMES, $REGISTRY)
783    }};
784
785    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
786        register_gauge_vec_with_registry!(opts!($NAME, $HELP), $LABELS_NAMES, $REGISTRY)
787    }};
788}
789
790#[test]
791fn test_register_gauge_vec_with_registry_trailing_comma() {
792    use crate::Registry;
793    use std::collections::HashMap;
794
795    let mut labels = HashMap::new();
796    labels.insert("mykey".to_string(), "myvalue".to_string());
797    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
798
799    let opts = opts!("test_macro_gauge_vec_1", "help",);
800    let gauge_vec = register_gauge_vec_with_registry!(opts, &["a", "b"], custom_registry,);
801    assert!(gauge_vec.is_ok());
802
803    let gauge_vec = register_gauge_vec_with_registry!(
804        "test_macro_gauge_vec_2",
805        "help",
806        &["a", "b"],
807        custom_registry,
808    );
809    assert!(gauge_vec.is_ok());
810}
811
812/// Create an [`IntGaugeVec`][crate::IntGaugeVec] and registers to default registry.
813///
814/// View docs of `register_gauge_vec` for examples.
815#[macro_export(local_inner_macros)]
816macro_rules! register_int_gauge_vec {
817    ($OPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
818        __register_gauge_vec!(IntGaugeVec, $OPTS, $LABELS_NAMES)
819    }};
820
821    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr $(,)?) => {{
822        register_int_gauge_vec!(opts!($NAME, $HELP), $LABELS_NAMES)
823    }};
824}
825
826/// Create an [`IntGaugeVec`][crate::IntGaugeVec] and registers to a custom registry.
827///
828/// View docs of `register_gauge_vec_with_registry` for examples.
829#[macro_export(local_inner_macros)]
830macro_rules! register_int_gauge_vec_with_registry {
831    ($OPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
832        __register_gauge_vec!(IntGaugeVec, $OPTS, $LABELS_NAMES, $REGISTRY)
833    }};
834
835    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
836        register_int_gauge_vec_with_registry!(opts!($NAME, $HELP), $LABELS_NAMES, $REGISTRY)
837    }};
838}
839
840#[test]
841fn test_register_int_gauge_vec() {
842    use crate::Registry;
843    use std::collections::HashMap;
844
845    let opts = opts!("test_opts_int_gauge_vec_1", "help");
846    let res = register_int_gauge_vec!(opts, &["a", "b"]);
847    assert!(res.is_ok());
848
849    let res = register_int_gauge_vec!("test_opts_int_gauge_vec_2", "help", &["a", "b"]);
850    assert!(res.is_ok());
851
852    let opts = opts!("test_opts_int_gauge_vec_3", "help",);
853    let res = register_int_gauge_vec!(opts, &["a", "b"],);
854    assert!(res.is_ok());
855
856    let res = register_int_gauge_vec!("test_opts_int_gauge_vec_4", "help", &["a", "b"],);
857    assert!(res.is_ok());
858
859    let mut labels = HashMap::new();
860    labels.insert("mykey".to_string(), "myvalue".to_string());
861    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
862
863    let opts = opts!("test_opts_int_gauge_vec_1", "help");
864    let res = register_int_gauge_vec_with_registry!(opts, &["a", "b"], custom_registry);
865    assert!(res.is_ok());
866
867    let res = register_int_gauge_vec_with_registry!(
868        "test_opts_int_gauge_vec_2",
869        "help",
870        &["a", "b"],
871        custom_registry
872    );
873    assert!(res.is_ok());
874
875    let opts = opts!("test_opts_int_gauge_vec_3", "help");
876    let res = register_int_gauge_vec_with_registry!(opts, &["a", "b"], custom_registry,);
877    assert!(res.is_ok());
878
879    let res = register_int_gauge_vec_with_registry!(
880        "test_opts_int_gauge_vec_4",
881        "help",
882        &["a", "b"],
883        custom_registry,
884    );
885    assert!(res.is_ok());
886}
887
888/// Create a [`Histogram`][crate::Histogram] and registers to default registry.
889///
890/// # Examples
891///
892/// ```
893/// # use prometheus::{histogram_opts, register_histogram};
894/// # fn main() {
895/// let opts = histogram_opts!("test_macro_histogram", "help");
896/// let res1 = register_histogram!(opts);
897/// assert!(res1.is_ok());
898///
899/// let res2 = register_histogram!("test_macro_histogram_2", "help");
900/// assert!(res2.is_ok());
901///
902/// let res3 = register_histogram!("test_macro_histogram_4",
903///                                 "help",
904///                                 vec![1.0, 2.0]);
905/// assert!(res3.is_ok());
906/// # }
907/// ```
908#[macro_export(local_inner_macros)]
909macro_rules! register_histogram {
910    ($NAME:expr, $HELP:expr $(,)?) => {
911        register_histogram!(histogram_opts!($NAME, $HELP))
912    };
913
914    ($NAME:expr, $HELP:expr, $BUCKETS:expr $(,)?) => {
915        register_histogram!(histogram_opts!($NAME, $HELP, $BUCKETS))
916    };
917
918    ($HOPTS:expr $(,)?) => {{
919        let histogram = $crate::Histogram::with_opts($HOPTS).unwrap();
920        $crate::register(Box::new(histogram.clone())).map(|()| histogram)
921    }};
922}
923
924#[test]
925fn test_register_histogram_trailing_comma() {
926    let opts = histogram_opts!("test_macro_histogram", "help",);
927    let res1 = register_histogram!(opts,);
928    assert!(res1.is_ok());
929
930    let res2 = register_histogram!("test_macro_histogram_2", "help",);
931    assert!(res2.is_ok());
932
933    let res3 = register_histogram!("test_macro_histogram_4", "help", vec![1.0, 2.0],);
934    assert!(res3.is_ok());
935}
936
937/// Create a [`Histogram`][crate::Histogram] and registers to a custom registry.
938///
939/// # Examples
940///
941/// ```
942/// # use prometheus::{register_histogram_with_registry, histogram_opts};
943/// # use prometheus::Registry;
944/// # use std::collections::HashMap;
945/// # fn main() {
946/// let mut labels = HashMap::new();
947/// labels.insert("mykey".to_string(), "myvalue".to_string());
948/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
949///
950/// let opts = histogram_opts!("test_macro_histogram", "help");
951/// let res1 = register_histogram_with_registry!(opts, custom_registry);
952/// assert!(res1.is_ok());
953///
954/// let res2 = register_histogram_with_registry!("test_macro_histogram_2", "help", custom_registry);
955/// assert!(res2.is_ok());
956///
957/// let res3 = register_histogram_with_registry!("test_macro_histogram_4",
958///                                 "help",
959///                                 vec![1.0, 2.0], custom_registry);
960/// assert!(res3.is_ok());
961/// # }
962/// ```
963#[macro_export(local_inner_macros)]
964macro_rules! register_histogram_with_registry {
965    ($NAME:expr, $HELP:expr, $REGISTRY:expr $(,)?) => {
966        register_histogram_with_registry!(histogram_opts!($NAME, $HELP), $REGISTRY)
967    };
968
969    ($NAME:expr, $HELP:expr, $BUCKETS:expr, $REGISTRY:expr $(,)?) => {
970        register_histogram_with_registry!(histogram_opts!($NAME, $HELP, $BUCKETS), $REGISTRY)
971    };
972
973    ($HOPTS:expr, $REGISTRY:expr $(,)?) => {{
974        let histogram = $crate::Histogram::with_opts($HOPTS).unwrap();
975        $REGISTRY
976            .register(Box::new(histogram.clone()))
977            .map(|()| histogram)
978    }};
979}
980
981#[test]
982fn test_register_histogram_with_registry_trailing_comma() {
983    use crate::Registry;
984    use std::collections::HashMap;
985
986    let mut labels = HashMap::new();
987    labels.insert("mykey".to_string(), "myvalue".to_string());
988    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
989
990    let opts = histogram_opts!("test_macro_histogram", "help",);
991    let res1 = register_histogram_with_registry!(opts, custom_registry,);
992    assert!(res1.is_ok());
993
994    let res2 =
995        register_histogram_with_registry!("test_macro_histogram_2", "help", custom_registry,);
996    assert!(res2.is_ok());
997
998    let res3 = register_histogram_with_registry!(
999        "test_macro_histogram_4",
1000        "help",
1001        vec![1.0, 2.0],
1002        custom_registry,
1003    );
1004    assert!(res3.is_ok());
1005}
1006
1007/// Create a [`HistogramVec`][crate::HistogramVec] and registers to default registry.
1008///
1009/// # Examples
1010///
1011/// ```
1012/// # use prometheus::{histogram_opts, register_histogram_vec};
1013/// # fn main() {
1014/// let opts = histogram_opts!("test_macro_histogram_vec_1", "help");
1015/// let histogram_vec = register_histogram_vec!(opts, &["a", "b"]);
1016/// assert!(histogram_vec.is_ok());
1017///
1018/// let histogram_vec =
1019///     register_histogram_vec!("test_macro_histogram_vec_2", "help", &["a", "b"]);
1020/// assert!(histogram_vec.is_ok());
1021///
1022/// let histogram_vec = register_histogram_vec!("test_macro_histogram_vec_3",
1023///                                             "help",
1024///                                             &["test_label"],
1025///                                             vec![0.0, 1.0, 2.0]);
1026/// assert!(histogram_vec.is_ok());
1027/// # }
1028/// ```
1029#[macro_export(local_inner_macros)]
1030macro_rules! register_histogram_vec {
1031    ($HOPTS:expr, $LABELS_NAMES:expr $(,)?) => {{
1032        let histogram_vec = $crate::HistogramVec::new($HOPTS, $LABELS_NAMES).unwrap();
1033        $crate::register(Box::new(histogram_vec.clone())).map(|()| histogram_vec)
1034    }};
1035
1036    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr $(,)?) => {{
1037        register_histogram_vec!(histogram_opts!($NAME, $HELP), $LABELS_NAMES)
1038    }};
1039
1040    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $BUCKETS:expr $(,)?) => {{
1041        register_histogram_vec!(histogram_opts!($NAME, $HELP, $BUCKETS), $LABELS_NAMES)
1042    }};
1043}
1044
1045#[test]
1046fn test_register_histogram_vec_trailing_comma() {
1047    let opts = histogram_opts!("test_macro_histogram_vec_1", "help",);
1048    let histogram_vec = register_histogram_vec!(opts, &["a", "b"],);
1049    assert!(histogram_vec.is_ok());
1050
1051    let histogram_vec = register_histogram_vec!("test_macro_histogram_vec_2", "help", &["a", "b"],);
1052    assert!(histogram_vec.is_ok());
1053
1054    let histogram_vec = register_histogram_vec!(
1055        "test_macro_histogram_vec_3",
1056        "help",
1057        &["test_label"],
1058        vec![0.0, 1.0, 2.0],
1059    );
1060    assert!(histogram_vec.is_ok());
1061}
1062
1063/// Create a [`HistogramVec`][crate::HistogramVec] and registers to default registry.
1064///
1065/// # Examples
1066///
1067/// ```
1068/// # use prometheus::{register_histogram_vec_with_registry, histogram_opts};
1069/// # use prometheus::Registry;
1070/// # use std::collections::HashMap;
1071/// # fn main() {
1072/// let mut labels = HashMap::new();
1073/// labels.insert("mykey".to_string(), "myvalue".to_string());
1074/// let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
1075///
1076/// let opts = histogram_opts!("test_macro_histogram_vec_1", "help");
1077/// let histogram_vec = register_histogram_vec_with_registry!(opts, &["a", "b"], custom_registry);
1078/// assert!(histogram_vec.is_ok());
1079///
1080/// let histogram_vec =
1081///     register_histogram_vec_with_registry!("test_macro_histogram_vec_2", "help", &["a", "b"], custom_registry);
1082/// assert!(histogram_vec.is_ok());
1083///
1084/// let histogram_vec = register_histogram_vec_with_registry!("test_macro_histogram_vec_3",
1085///                                             "help",
1086///                                             &["test_label"],
1087///                                             vec![0.0, 1.0, 2.0], custom_registry);
1088/// assert!(histogram_vec.is_ok());
1089/// # }
1090/// ```
1091#[macro_export(local_inner_macros)]
1092macro_rules! register_histogram_vec_with_registry {
1093    ($HOPTS:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
1094        let histogram_vec = $crate::HistogramVec::new($HOPTS, $LABELS_NAMES).unwrap();
1095        $REGISTRY
1096            .register(Box::new(histogram_vec.clone()))
1097            .map(|()| histogram_vec)
1098    }};
1099
1100    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $REGISTRY:expr $(,)?) => {{
1101        register_histogram_vec_with_registry!(
1102            histogram_opts!($NAME, $HELP),
1103            $LABELS_NAMES,
1104            $REGISTRY
1105        )
1106    }};
1107
1108    ($NAME:expr, $HELP:expr, $LABELS_NAMES:expr, $BUCKETS:expr, $REGISTRY:expr $(,)?) => {{
1109        register_histogram_vec_with_registry!(
1110            histogram_opts!($NAME, $HELP, $BUCKETS),
1111            $LABELS_NAMES,
1112            $REGISTRY
1113        )
1114    }};
1115}
1116
1117#[test]
1118fn test_register_histogram_vec_with_registry_trailing_comma() {
1119    use crate::Registry;
1120    use std::collections::HashMap;
1121
1122    let mut labels = HashMap::new();
1123    labels.insert("mykey".to_string(), "myvalue".to_string());
1124    let custom_registry = Registry::new_custom(Some("myprefix".to_string()), Some(labels)).unwrap();
1125
1126    let opts = histogram_opts!("test_macro_histogram_vec_1", "help",);
1127    let histogram_vec = register_histogram_vec_with_registry!(opts, &["a", "b"], custom_registry,);
1128    assert!(histogram_vec.is_ok());
1129
1130    let histogram_vec = register_histogram_vec_with_registry!(
1131        "test_macro_histogram_vec_2",
1132        "help",
1133        &["a", "b"],
1134        custom_registry,
1135    );
1136    assert!(histogram_vec.is_ok());
1137
1138    let histogram_vec = register_histogram_vec_with_registry!(
1139        "test_macro_histogram_vec_3",
1140        "help",
1141        &["test_label"],
1142        vec![0.0, 1.0, 2.0],
1143        custom_registry,
1144    );
1145    assert!(histogram_vec.is_ok());
1146}