Add app_metric! forms for tuples and arrays

This commit is contained in:
Francis Lalonde 2018-01-16 16:56:34 -05:00
parent a6b044f7a9
commit e635e7c329
10 changed files with 77 additions and 28 deletions

View File

@ -3,6 +3,7 @@ members = [
"./",
"examples/counter_timer_gauge/",
"examples/multi_outs/",
"examples/macro_outs/",
"examples/aggregate_print/",
"examples/summary_print/",
"examples/async_print/",

View File

@ -0,0 +1,8 @@
[package]
name = "macro_outs"
version = "0.0.0"
workspace = "../../"
[dependencies]
dipstick = { path = '../../' }
lazy_static = "0.2"

View File

@ -0,0 +1,32 @@
//! A sample application sending ad-hoc counter values both to statsd _and_ to stdout.
extern crate dipstick;
#[macro_use] extern crate lazy_static;
use dipstick::*;
use std::time::Duration;
app_metrics!((Statsd, String), DIFFERENT_TYPES = (
// combine outputs of different types by using a tuple
to_statsd("localhost:8125").expect("Connecting"),
to_stdout(),
));
app_metrics!(Vec<String>, SAME_TYPE = [
// combine multiple outputs of the same type by using an array
to_stdout().with_prefix("yeah"),
to_stdout().with_prefix("ouch"),
to_stdout().with_sampling_rate(0.5),
]);
app_metrics!(Vec<String>, MUTANT_CHILD = SAME_TYPE.with_prefix("super").with_prefix("duper"));
fn main() {
loop {
DIFFERENT_TYPES.counter("counter_a").count(123);
SAME_TYPE.timer("timer_a").interval_us(2000000);
MUTANT_CHILD.gauge("gauge_z").value(34534);
std::thread::sleep(Duration::from_millis(40));
}
}

View File

@ -6,12 +6,15 @@ use dipstick::*;
use std::time::Duration;
fn main() {
// note that this can also be done using the app_metrics! macro
let different_type_metrics = app_metrics((
// combine metrics of different types in a tuple
to_statsd("localhost:8125").expect("Connecting"),
to_stdout(),
));
// note that this can also be done using the app_metrics! macro
let same_type_metrics = app_metrics(
&[
// use slices to combine multiple metrics of the same type

View File

@ -7,7 +7,7 @@ use dipstick::*;
fn main() {
// print only 1 out of every 10000 metrics recorded
let app_metrics = app_metrics(to_stdout().with_sampling_rate(0.0001));
let app_metrics: AppMetrics<String> = app_metrics(to_stdout().with_sampling_rate(0.0001));
let marker = app_metrics.marker("marker_a");

View File

@ -48,6 +48,16 @@ where
}
}
impl<M> From<Chain<M>> for AppMetrics<M> {
fn from(chain: Chain<M>) -> AppMetrics<M> {
let static_scope = chain.open_scope(false);
AppMetrics {
scope: static_scope,
chain: Arc::new(chain),
}
}
}
/// A monotonic counter metric.
/// Since value is only ever increased by one, no value parameter is provided,
/// preventing programming errors.

View File

@ -167,7 +167,7 @@ pub struct Chain<M> {
#[derivative(Debug = "ignore")] scope_metric_fn: OpenScopeFn<M>,
}
impl<M: Send + Sync + Clone + 'static> Chain<M> {
impl<M> Chain<M> {
/// Define a new metric.
#[allow(unused_variables)]
pub fn define_metric(&self, kind: Kind, name: &str, sampling: Rate) -> M {
@ -206,7 +206,9 @@ impl<M: Send + Sync + Clone + 'static> Chain<M> {
pub fn unbuffered_scope(&self) -> ControlScopeFn<M> {
self.open_scope(false)
}
}
impl<M: Send + Sync + Clone + 'static> Chain<M> {
/// Create a new metric chain with the provided metric definition and scope creation functions.
pub fn new<MF, WF>(make_metric: MF, make_scope: WF) -> Self
where
@ -336,9 +338,9 @@ impl<M: Clone> ScopeGauge<M> {
/// A timer that sends values to the metrics backend
/// Timers can record time intervals in multiple ways :
/// - with the time! macrohich wraps an expression or block with start() and stop() calls.
/// - with the time(Fn) methodhich wraps a closure with start() and stop() calls.
/// - with start() and stop() methodsrapping around the operation to time
/// - with the time! macro which wraps an expression or block with start() and stop() calls.
/// - with the time(Fn) method which wraps a closure with start() and stop() calls.
/// - with start() and stop() methods wrapping around the operation to time
/// - with the interval_us() method, providing an externally determined microsecond interval
#[derive(Derivative)]
#[derivative(Debug)]

View File

@ -23,16 +23,14 @@ macro_rules! time {
/// Define application-scoped metrics.
#[macro_export]
macro_rules! app_metrics {
($type_param: ty, $metric_id: ident = $app_metrics: expr) => {
lazy_static! { pub static ref $metric_id: AppMetrics<$type_param> = $app_metrics; }
($type_param: ty, $metric_id: ident = ($($app_metrics: expr),+ $(,)*)) => {
lazy_static! { pub static ref $metric_id: AppMetrics<$type_param> = app_metrics(($($app_metrics),*)); }
};
($type_param: ty, $metric_id: ident = [$($app_metrics: expr),+ $(,)*]) => {
lazy_static! { pub static ref $metric_id: AppMetrics<$type_param> = app_metrics(&[$($app_metrics),*][..],); }
};
}
#[macro_export]
#[deprecated(since = "0.6.3", note = "Use `app_metrics!` instead.")]
macro_rules! app_metric {
($type_param: ty, $metric_id: ident = $app_metrics: expr) => {
lazy_static! { pub static ref $metric_id: AppMetrics<$type_param> = $app_metrics; }
lazy_static! { pub static ref $metric_id: AppMetrics<$type_param> = $app_metrics.into(); }
};
}
@ -75,16 +73,14 @@ macro_rules! app_timer {
/// Define module-scoped metrics.
#[macro_export]
macro_rules! mod_metrics {
($type_param: ty, $metric_id: ident = $mod_metrics: expr) => {
lazy_static! { static ref $metric_id: AppMetrics<$type_param> = $mod_metrics; }
($type_param: ty, $metric_id: ident = ($($app_metrics: expr),+ $(,)*)) => {
lazy_static! { static ref $metric_id: AppMetrics<$type_param> = app_metrics(($($app_metrics),*)); }
};
($type_param: ty, $metric_id: ident = [$($app_metrics: expr),+ $(,)*]) => {
lazy_static! { static ref $metric_id: AppMetrics<$type_param> = app_metrics(&[$($app_metrics),*][..],); }
};
}
#[macro_export]
#[deprecated(since = "0.6.3", note = "Use `mod_metrics!` instead.")]
macro_rules! mod_metric {
($type_param: ty, $metric_id: ident = $mod_metrics: expr) => {
lazy_static! { static ref $metric_id: AppMetrics<$type_param> = $mod_metrics; }
lazy_static! { static ref $metric_id: AppMetrics<$type_param> = $mod_metrics.into(); }
};
}

View File

@ -43,11 +43,11 @@ where
/// Multiple chains of the same type can be combined in a slice.
/// The chains will act as one, each receiving calls in the order the appear in the slice.
impl<'a, M> From<&'a [Chain<M>]> for Chain<Box<[M]>>
impl<'a, M> From<&'a [Chain<M>]> for Chain<Vec<M>>
where
M: 'static + Clone + Send + Sync,
{
fn from(chains: &'a [Chain<M>]) -> Chain<Box<[M]>> {
fn from(chains: &'a [Chain<M>]) -> Chain<Vec<M>> {
let chains = chains.to_vec();
let chains2 = chains.clone();
@ -57,7 +57,7 @@ where
for chain in &chains {
metric.push(chain.define_metric(kind, name, rate));
}
metric.into_boxed_slice()
metric
},
move |buffered| {
let mut scopes = Vec::with_capacity(chains2.len());
@ -67,7 +67,7 @@ where
ControlScopeFn::new(move |cmd| match cmd {
ScopeCmd::Write(metric, value) => {
let metric: &Box<[M]> = metric;
let metric: &Vec<M> = metric;
for (i, scope) in scopes.iter().enumerate() {
scope.write(&metric[i], value)
}

View File

@ -99,9 +99,6 @@ impl Scoreboard {
if self.snapshot(now, &mut scores) {
let duration_seconds = (now - scores[0]) as f64 / 1_000_000_000.0;
println!("duration {}s", duration_seconds);
println!("rate {}/s", scores[2] as f64 / duration_seconds);
let mut snapshot = Vec::new();
match self.kind {
Marker => {