pub use lazy_static::*;
#[macro_export]
macro_rules! time {
($timer: expr, $body: expr) => {{
let start_time = $timer.start();
let value = $body;
$timer.stop(start_time);
value
}};
}
#[macro_export]
macro_rules! labels {
(@single $($x:tt)*) => (());
(@count $($rest:expr),*) => (<[()]>::len(&[$(labels!(@single $rest)),*]));
($($key:expr => $value:expr,)+) => { labels!($($key => $value),+) };
($($key:expr => $value:expr),*) => {
{
let _cap = labels!(@count $($key),*);
let mut _map: ::std::collections::HashMap<String, ::std::sync::Arc<String>> = ::std::collections::HashMap::with_capacity(_cap);
$(
let _ = _map.insert($key.into(), ::std::sync::Arc::new($value.into()));
)*
::Labels::from(_map)
}
};
() => {
::Labels::default()
}
}
#[macro_export]
macro_rules! metrics {
($(#[$attr:meta])* pub $IDENT:ident: $TYPE:ty = $e:expr => { $($BRANCH:tt)*} $($REST:tt)*) => {
lazy_static! { $(#[$attr])* pub static ref $IDENT: $TYPE = $e.into(); }
metrics!{ @internal $IDENT; $TYPE; $($BRANCH)* }
metrics!{ $($REST)* }
};
($(#[$attr:meta])* $IDENT:ident: $TYPE:ty = $e:expr => { $($BRANCH:tt)* } $($REST:tt)*) => {
lazy_static! { $(#[$attr])* static ref $IDENT: $TYPE = $e.into(); }
metrics!{ @internal $IDENT; $TYPE; $($BRANCH)* }
metrics!{ $($REST)* }
};
($(#[$attr:meta])* pub $IDENT:ident = $e:expr => { $($BRANCH:tt)* } $($REST:tt)*) => {
lazy_static! { $(#[$attr])* pub static ref $IDENT: Proxy = $e.into(); }
metrics!{ @internal $IDENT; Proxy; $($BRANCH)* }
metrics!{ $($REST)* }
};
($(#[$attr:meta])* $IDENT:ident = $e:expr => { $($BRANCH:tt)* } $($REST:tt)*) => {
lazy_static! { $(#[$attr])* static ref $IDENT: Proxy = $e.into(); }
metrics!{ @internal $IDENT; Proxy; $($BRANCH)* }
metrics!{ $($REST)* }
};
($e:ident => { $($BRANCH:tt)+ } $($REST:tt)*) => {
metrics!{ @internal $e; Proxy; $($BRANCH)* }
metrics!{ $($REST)* }
};
($e:expr => { $($BRANCH:tt)+ } $($REST:tt)*) => {
lazy_static! { static ref PROXY_METRICS: Proxy = $e.into(); }
metrics!{ @internal PROXY_METRICS; Proxy; $($BRANCH)* }
metrics!{ $($REST)* }
};
($(#[$attr:meta])* pub $IDENT:ident: $TYPE:ty = $e:expr; $($REST:tt)*) => {
metrics!{ @internal Proxy::default(); Proxy; $(#[$attr])* pub $IDENT: $TYPE = $e; }
metrics!{ $($REST)* }
};
($(#[$attr:meta])* $IDENT:ident: $TYPE:ty = $e:expr; $($REST:tt)*) => {
metrics!{ @internal Proxy::default(); Proxy; $(#[$attr])* $IDENT: $TYPE = $e; }
metrics!{ $($REST)* }
};
() => ();
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* pub $IDENT:ident: $MTY:ty = $METRIC_NAME:expr; $($REST:tt)*) => {
lazy_static! { $(#[$attr])* pub static ref $IDENT: $MTY =
$WITH.new_metric($METRIC_NAME.into(), stringify!($MTY).into()).into();
}
metrics!{ @internal $WITH; $TY; $($REST)* }
};
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* $IDENT:ident: $MTY:ty = $METRIC_NAME:expr; $($REST:tt)*) => {
lazy_static! { $(#[$attr])* static ref $IDENT: $MTY =
$WITH.new_metric($METRIC_NAME.into(), stringify!($MTY).into()).into();
}
metrics!{ @internal $WITH; $TY; $($REST)* }
};
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* pub $IDENT:ident = $e:expr => { $($BRANCH:tt)*} $($REST:tt)*) => {
lazy_static! { $(#[$attr])* pub static ref $IDENT = $WITH.add_prefix($e); }
metrics!( @internal $IDENT; $TY; $($BRANCH)*);
metrics!( @internal $WITH; $TY; $($REST)*);
};
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* $IDENT:ident = $e:expr => { $($BRANCH:tt)*} $($REST:tt)*) => {
lazy_static! { $(#[$attr])* static ref $IDENT = $WITH.add_prefix($e); }
metrics!( @internal $IDENT; $TY; $($BRANCH)*);
metrics!( @internal $WITH; $TY; $($REST)*);
};
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* pub $e:expr => { $($BRANCH:tt)*} $($REST:tt)*) => {
metrics!( @internal $WITH.add_prefix($e); $TY; $($BRANCH)*);
metrics!( @internal $WITH; $TY; $($REST)*);
};
(@internal $WITH:expr; $TY:ty; $(#[$attr:meta])* $e:expr => { $($BRANCH:tt)*} $($REST:tt)*) => {
metrics!( @internal $WITH.add_prefix($e); $TY; $($BRANCH)*);
metrics!( @internal $WITH; $TY; $($REST)*);
};
(@internal $WITH:expr; $TYPE:ty;) => ()
}
#[cfg(test)]
mod test {
use core::input::*;
use core::proxy::Proxy;
metrics!{TEST: Proxy = "test_prefix" => {
pub M1: Marker = "failed";
C1: Counter = "failed";
G1: Gauge = "failed";
T1: Timer = "failed";
}}
metrics!("my_app" => {
COUNTER_A: Counter = "counter_a";
});
#[test]
fn gurp() {
COUNTER_A.count(11);
}
#[test]
fn call_new_macro_defined_metrics() {
M1.mark();
C1.count(1);
G1.value(1);
T1.interval_us(1);
}
}