mirror of https://github.com/fralalonde/dipstick
Fix format + naming + a few tests
This commit is contained in:
parent
9b84a1ac42
commit
d4274cf49c
|
@ -98,12 +98,12 @@ For speed and easier maintenance, metrics are usually defined statically:
|
|||
#[macro_use] extern crate lazy_static;
|
||||
use dipstick::*;
|
||||
|
||||
app_metrics!(String, APP_METRICS = to_stdout());
|
||||
app_counter!(String, APP_METRICS, {
|
||||
COUNTER_A: "counter_a",
|
||||
app_metrics!("my_app" => {
|
||||
@Counter COUNTER_A: "counter_a";
|
||||
});
|
||||
|
||||
fn main() {
|
||||
send_delegated_metrics(to_stdout());
|
||||
COUNTER_A.count(11);
|
||||
}
|
||||
```
|
||||
|
|
2
build.rs
2
build.rs
|
@ -3,4 +3,4 @@ extern crate skeptic;
|
|||
fn main() {
|
||||
// generates doc tests for `README.md`.
|
||||
skeptic::generate_doc_tests(&["README.md"]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,11 +7,13 @@ use dipstick::*;
|
|||
use std::time::Duration;
|
||||
|
||||
fn main() {
|
||||
// badlog::init(Some("info"));
|
||||
// badlog::init(Some("info"));
|
||||
|
||||
let metrics = app_metrics(
|
||||
to_graphite("localhost:2003").expect("Connecting")
|
||||
.with_namespace(&["my", "app"][..]));
|
||||
to_graphite("localhost:2003")
|
||||
.expect("Connecting")
|
||||
.with_namespace(&["my", "app"][..]),
|
||||
);
|
||||
|
||||
loop {
|
||||
metrics.counter("counter_a").count(123);
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
//! A sample application sending ad-hoc counter values both to statsd _and_ to stdout.
|
||||
|
||||
extern crate dipstick;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use dipstick::*;
|
||||
use std::time::Duration;
|
||||
|
@ -41,11 +42,11 @@ app_metrics!(LIB_METRICS => {
|
|||
});
|
||||
|
||||
fn main() {
|
||||
|
||||
set_global_metrics_receiver(to_stdout());
|
||||
send_delegated_metrics(to_stdout());
|
||||
|
||||
loop {
|
||||
ROOT_COUNTER.count(123);
|
||||
ANOTHER_COUNTER.count(456);
|
||||
ROOT_TIMER.interval_us(2000000);
|
||||
ROOT_GAUGE.value(34534);
|
||||
std::thread::sleep(Duration::from_millis(40));
|
||||
|
|
|
@ -1,28 +1,28 @@
|
|||
//! A sample application sending ad-hoc counter values both to statsd _and_ to stdout.
|
||||
|
||||
extern crate dipstick;
|
||||
#[macro_use] extern crate lazy_static;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
use dipstick::*;
|
||||
use std::time::Duration;
|
||||
|
||||
app_metrics!((Statsd, String), DIFFERENT_TYPES = (
|
||||
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 = [
|
||||
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"););
|
||||
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);
|
||||
|
|
|
@ -6,7 +6,6 @@ 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
|
||||
|
|
|
@ -15,7 +15,6 @@ pub mod metric {
|
|||
// and is even more work because IDE's such as IntelliJ can not yet see through macro blocks :(
|
||||
lazy_static! {
|
||||
pub static ref METRICS: AppMetrics<String> = app_metrics(to_stdout());
|
||||
|
||||
pub static ref COUNTER_A: AppCounter<String> = METRICS.counter("counter_a");
|
||||
pub static ref TIMER_B: AppTimer<String> = METRICS.timer("timer_b");
|
||||
}
|
||||
|
|
|
@ -18,8 +18,7 @@ use std::sync::{Arc, RwLock};
|
|||
/// Needs to be connected to a publish to be useful.
|
||||
/// ```
|
||||
/// use dipstick::*;
|
||||
/// let sink = aggregate(4, summary, to_stdout());
|
||||
/// let metrics = global_metrics(sink);
|
||||
/// let metrics: AppMetrics<_> = aggregate(summary, to_stdout()).into();
|
||||
/// metrics.marker("my_event").mark();
|
||||
/// metrics.marker("my_event").mark();
|
||||
/// ```
|
||||
|
@ -30,7 +29,7 @@ where
|
|||
{
|
||||
Aggregator {
|
||||
metrics: Arc::new(RwLock::new(HashMap::new())),
|
||||
publish: Arc::new(Publisher::new(stat_fn, to_chain))
|
||||
publish: Arc::new(Publisher::new(stat_fn, to_chain)),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,11 +42,9 @@ impl From<Aggregator> for AppMetrics<Aggregate> {
|
|||
ScopeCmd::Write(metric, value) => {
|
||||
let metric: &Aggregate = metric;
|
||||
metric.update(value)
|
||||
},
|
||||
ScopeCmd::Flush => {
|
||||
agg_1.flush()
|
||||
}
|
||||
})
|
||||
ScopeCmd::Flush => agg_1.flush(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +64,6 @@ pub struct Aggregator {
|
|||
publish: Arc<Publish>,
|
||||
}
|
||||
|
||||
|
||||
impl Aggregator {
|
||||
/// Build a new metric aggregation point with specified initial capacity of metrics to aggregate.
|
||||
pub fn with_capacity(size: usize, publish: Arc<Publish>) -> Aggregator {
|
||||
|
@ -95,7 +91,9 @@ impl Aggregator {
|
|||
|
||||
/// Lookup or create a scoreboard for the requested metric.
|
||||
pub fn define_metric(&self, kind: Kind, name: &str, _rate: Rate) -> Aggregate {
|
||||
self.metrics.write().expect("Locking aggregator")
|
||||
self.metrics
|
||||
.write()
|
||||
.expect("Locking aggregator")
|
||||
.entry(name.to_string())
|
||||
.or_insert_with(|| Arc::new(Scoreboard::new(kind, name.to_string())))
|
||||
.clone()
|
||||
|
|
|
@ -36,7 +36,8 @@ where
|
|||
#[derivative(Debug)]
|
||||
pub struct AppMarker<M> {
|
||||
metric: M,
|
||||
#[derivative(Debug = "ignore")] scope: ControlScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
scope: ControlScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> AppMarker<M> {
|
||||
|
@ -51,7 +52,8 @@ impl<M> AppMarker<M> {
|
|||
#[derivative(Debug)]
|
||||
pub struct AppCounter<M> {
|
||||
metric: M,
|
||||
#[derivative(Debug = "ignore")] scope: ControlScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
scope: ControlScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> AppCounter<M> {
|
||||
|
@ -69,7 +71,8 @@ impl<M> AppCounter<M> {
|
|||
#[derivative(Debug)]
|
||||
pub struct AppGauge<M> {
|
||||
metric: M,
|
||||
#[derivative(Debug = "ignore")] scope: ControlScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
scope: ControlScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> AppGauge<M> {
|
||||
|
@ -92,7 +95,8 @@ impl<M> AppGauge<M> {
|
|||
#[derivative(Debug)]
|
||||
pub struct AppTimer<M> {
|
||||
metric: M,
|
||||
#[derivative(Debug = "ignore")] scope: ControlScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
scope: ControlScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> AppTimer<M> {
|
||||
|
@ -102,7 +106,8 @@ impl<M> AppTimer<M> {
|
|||
where
|
||||
V: ToPrimitive,
|
||||
{
|
||||
self.scope.write(&self.metric, interval_us.to_u64().unwrap());
|
||||
self.scope
|
||||
.write(&self.metric, interval_us.to_u64().unwrap());
|
||||
interval_us
|
||||
}
|
||||
|
||||
|
@ -143,26 +148,31 @@ impl<M> AppTimer<M> {
|
|||
#[derive(Derivative, Clone)]
|
||||
#[derivative(Debug)]
|
||||
pub struct AppMetrics<M> {
|
||||
#[derivative(Debug = "ignore")] define_metric_fn: DefineMetricFn<M>,
|
||||
#[derivative(Debug = "ignore")] single_scope: ControlScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
define_metric_fn: DefineMetricFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
single_scope: ControlScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> AppMetrics<M> {
|
||||
/// Create new application metrics instance.
|
||||
pub fn new(define_metric_fn: DefineMetricFn<M>, scope: ControlScopeFn<M>, ) -> Self {
|
||||
AppMetrics { define_metric_fn, single_scope: scope }
|
||||
pub fn new(define_metric_fn: DefineMetricFn<M>, scope: ControlScopeFn<M>) -> Self {
|
||||
AppMetrics {
|
||||
define_metric_fn,
|
||||
single_scope: scope,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<M> AppMetrics<M>
|
||||
where
|
||||
M: Clone + Send + Sync + 'static,
|
||||
where
|
||||
M: Clone + Send + Sync + 'static,
|
||||
{
|
||||
#[inline]
|
||||
fn define_metric(&self, kind: Kind, name: &str, rate: Rate) -> M {
|
||||
(self.define_metric_fn)(kind, name, rate)
|
||||
}
|
||||
|
||||
|
||||
/// Get an event counter of the provided name.
|
||||
pub fn marker<AS: AsRef<str>>(&self, name: AS) -> AppMarker<M> {
|
||||
let metric = self.define_metric(Marker, name.as_ref(), 1.0);
|
||||
|
@ -226,10 +236,7 @@ impl<M: Send + Sync + Clone + 'static> Receiver for AppMetrics<M> {
|
|||
let scope: ControlScopeFn<M> = self.single_scope.clone();
|
||||
let metric: M = self.define_metric(kind, name, rate);
|
||||
|
||||
Box::new(AppReceiverMetric {
|
||||
metric,
|
||||
scope,
|
||||
})
|
||||
Box::new(AppReceiverMetric { metric, scope })
|
||||
}
|
||||
|
||||
fn flush(&self) {
|
||||
|
@ -247,7 +254,7 @@ impl<M> ReceiverMetric for AppReceiverMetric<M> {
|
|||
|
||||
impl<M: Send + Sync + Clone + 'static> WithNamespace for AppMetrics<M> {
|
||||
fn with_name<IN: Into<Namespace>>(&self, names: IN) -> Self {
|
||||
let ref ns = names.into();
|
||||
let ns = &names.into();
|
||||
AppMetrics {
|
||||
define_metric_fn: add_namespace(ns, self.define_metric_fn.clone()),
|
||||
single_scope: self.single_scope.clone(),
|
||||
|
|
|
@ -10,9 +10,10 @@ use std::sync::Arc;
|
|||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
|
||||
mod_metrics!{
|
||||
Aggregate, DIPSTICK_METRICS.with_prefix("async_queue");
|
||||
@Marker SEND_FAILED: "send_failed";
|
||||
app_metrics!{
|
||||
<Aggregate> DIPSTICK_METRICS.with_prefix("async_queue") => {
|
||||
@Marker SEND_FAILED: "send_failed";
|
||||
}
|
||||
}
|
||||
|
||||
/// Enqueue collected metrics for dispatch on background thread.
|
||||
|
@ -57,7 +58,7 @@ impl<M: Send + Sync + Clone + 'static> WithAsyncQueue for ScopeMetrics<M> {
|
|||
ScopeCmd::Write(metric, value) => {
|
||||
let metric: &M = metric;
|
||||
Some((metric.clone(), value))
|
||||
},
|
||||
}
|
||||
ScopeCmd::Flush => None,
|
||||
};
|
||||
sender
|
||||
|
|
|
@ -20,7 +20,7 @@ where
|
|||
/// Add a caching decorator to a metric definition function.
|
||||
pub fn add_cache<M>(cache_size: usize, next: DefineMetricFn<M>) -> DefineMetricFn<M>
|
||||
where
|
||||
M: Clone + Send + Sync + 'static
|
||||
M: Clone + Send + Sync + 'static,
|
||||
{
|
||||
let cache: RwLock<LRUCache<String, M>> = RwLock::new(LRUCache::with_capacity(cache_size));
|
||||
Arc::new(move |kind, name, rate| {
|
||||
|
|
|
@ -99,16 +99,16 @@ pub enum ScopeCmd<'a, M: 'a> {
|
|||
|
||||
/// Create a new metric scope based on the provided scope function.
|
||||
pub fn control_scope<M, F>(scope_fn: F) -> ControlScopeFn<M>
|
||||
where F: Fn(ScopeCmd<M>) + 'static
|
||||
where
|
||||
F: Fn(ScopeCmd<M>) + 'static,
|
||||
{
|
||||
Arc::new(InnerControlScopeFn {
|
||||
flush_on_drop: true,
|
||||
scope_fn: Box::new(scope_fn)
|
||||
scope_fn: Box::new(scope_fn),
|
||||
})
|
||||
}
|
||||
|
||||
impl<M> InnerControlScopeFn<M> {
|
||||
|
||||
/// Write a value to this scope.
|
||||
///
|
||||
/// ```rust
|
||||
|
@ -132,7 +132,6 @@ impl<M> InnerControlScopeFn<M> {
|
|||
pub fn flush(&self) {
|
||||
(self.scope_fn)(Flush)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<M> Drop for InnerControlScopeFn<M> {
|
||||
|
@ -142,4 +141,3 @@ impl<M> Drop for InnerControlScopeFn<M> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,13 +12,15 @@ use atomic_refcell::*;
|
|||
|
||||
/// The registry contains a list of every metrics dispatch point in the app.
|
||||
lazy_static! {
|
||||
static ref DISPATCH_REGISTRY: RwLock<Vec<DelegationPoint>> = RwLock::new(vec![]);
|
||||
static ref DELEGATE_REGISTRY: RwLock<Vec<DelegationPoint>> = RwLock::new(vec![]);
|
||||
}
|
||||
|
||||
/// Install a new receiver for all dispatched metrics, replacing any previous receiver.
|
||||
pub fn set_global_metrics_receiver<IS: Into<AppMetrics<T>>, T: Send + Sync + Clone + 'static>(receiver: IS) {
|
||||
pub fn send_delegated_metrics<IS: Into<AppMetrics<T>>, T: Send + Sync + Clone + 'static>(
|
||||
receiver: IS,
|
||||
) {
|
||||
let rec = receiver.into();
|
||||
for d in DISPATCH_REGISTRY.read().unwrap().iter() {
|
||||
for d in DELEGATE_REGISTRY.read().unwrap().iter() {
|
||||
d.set_receiver(rec.clone());
|
||||
}
|
||||
}
|
||||
|
@ -30,9 +32,12 @@ pub fn delegate() -> DelegationPoint {
|
|||
inner: Arc::new(RwLock::new(InnerDelegationPoint {
|
||||
metrics: HashMap::new(),
|
||||
receiver: Box::new(app_metrics(to_void())),
|
||||
}))
|
||||
})),
|
||||
};
|
||||
DISPATCH_REGISTRY.write().unwrap().push(delegation_point.clone());
|
||||
DELEGATE_REGISTRY
|
||||
.write()
|
||||
.unwrap()
|
||||
.push(delegation_point.clone());
|
||||
delegation_point
|
||||
}
|
||||
|
||||
|
@ -107,32 +112,40 @@ impl From<DelegationPoint> for AppMetrics<Delegate> {
|
|||
AppMetrics::new(
|
||||
// define metric
|
||||
Arc::new(move |kind, name, rate| dispatcher.define_metric(kind, name, rate)),
|
||||
|
||||
// write / flush metric
|
||||
control_scope(move |cmd| match cmd {
|
||||
ScopeCmd::Write(metric, value) => {
|
||||
let dispatch: &Arc<DelegatingMetric> = metric;
|
||||
let receiver_metric: AtomicRef<Box<ReceiverMetric + Send + Sync>> = dispatch.receiver.borrow();
|
||||
let receiver_metric: AtomicRef<
|
||||
Box<ReceiverMetric + Send + Sync>,
|
||||
> = dispatch.receiver.borrow();
|
||||
receiver_metric.write(value)
|
||||
},
|
||||
ScopeCmd::Flush => {
|
||||
dispatcher_1.inner.write().expect("Locking dispatcher").receiver.flush()
|
||||
},
|
||||
})
|
||||
}
|
||||
ScopeCmd::Flush => dispatcher_1
|
||||
.inner
|
||||
.write()
|
||||
.expect("Locking dispatcher")
|
||||
.receiver
|
||||
.flush(),
|
||||
}),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
impl DelegationPoint {
|
||||
|
||||
/// Install a new metric receiver, replacing the previous one.
|
||||
pub fn set_receiver<IS: Into<AppMetrics<T>>, T: Send + Sync + Clone + 'static>(&self, receiver: IS) {
|
||||
pub fn set_receiver<IS: Into<AppMetrics<T>>, T: Send + Sync + Clone + 'static>(
|
||||
&self,
|
||||
receiver: IS,
|
||||
) {
|
||||
let receiver: Box<Receiver + Send + Sync> = Box::new(receiver.into());
|
||||
let inner: &mut InnerDelegationPoint = &mut *self.inner.write().expect("Locking dispatcher");
|
||||
let inner: &mut InnerDelegationPoint =
|
||||
&mut *self.inner.write().expect("Locking dispatcher");
|
||||
|
||||
for mut metric in inner.metrics.values() {
|
||||
if let Some(metric) = metric.upgrade() {
|
||||
let receiver_metric = receiver.box_metric(metric.kind, metric.name.as_ref(), metric.rate);
|
||||
let receiver_metric =
|
||||
receiver.box_metric(metric.kind, metric.name.as_ref(), metric.rate);
|
||||
*metric.receiver.borrow_mut() = receiver_metric;
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +160,7 @@ impl DelegationPoint {
|
|||
|
||||
let receiver_metric = inner.receiver.box_metric(kind, name, rate);
|
||||
|
||||
let dispatcher_metric = Arc::new(DelegatingMetric {
|
||||
let delegating_metric = Arc::new(DelegatingMetric {
|
||||
kind,
|
||||
name: name.to_string(),
|
||||
rate,
|
||||
|
@ -155,17 +168,19 @@ impl DelegationPoint {
|
|||
dispatcher: self.clone(),
|
||||
});
|
||||
|
||||
inner.metrics.insert(dispatcher_metric.name.clone(), Arc::downgrade(&dispatcher_metric));
|
||||
dispatcher_metric
|
||||
inner.metrics.insert(
|
||||
delegating_metric.name.clone(),
|
||||
Arc::downgrade(&delegating_metric),
|
||||
);
|
||||
delegating_metric
|
||||
}
|
||||
|
||||
fn drop_metric(&self, metric: &DelegatingMetric) {
|
||||
let mut inner = self.inner.write().expect("Locking dispatcher");
|
||||
if let None = inner.metrics.remove(&metric.name) {
|
||||
panic!("Could not remove DispatchMetric weak ref from Dispatcher")
|
||||
let mut inner = self.inner.write().expect("Locking delegation point");
|
||||
if inner.metrics.remove(&metric.name).is_none() {
|
||||
panic!("Could not remove DelegatingMetric weak ref from delegation point")
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(feature = "bench")]
|
||||
|
|
|
@ -15,8 +15,7 @@ use std::fmt::Debug;
|
|||
use socket::RetrySocket;
|
||||
|
||||
app_metrics!{
|
||||
Aggregate,
|
||||
DIPSTICK_METRICS.with_prefix("graphite") => {
|
||||
<Aggregate> DIPSTICK_METRICS.with_prefix("graphite") => {
|
||||
@Marker SEND_ERR: "send_failed";
|
||||
@Marker TRESHOLD_EXCEEDED: "bufsize_exceeded";
|
||||
@Counter SENT_BYTES: "sent_bytes";
|
||||
|
@ -50,7 +49,7 @@ where
|
|||
by a factor of {} when sent to graphite.",
|
||||
kind, name, rate, upsample
|
||||
);
|
||||
scale = scale * upsample;
|
||||
scale *= upsample;
|
||||
}
|
||||
|
||||
Graphite { prefix, scale }
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
|
12
src/lib.rs
12
src/lib.rs
|
@ -1,14 +1,8 @@
|
|||
//! A quick, modular metrics toolkit for Rust applications.
|
||||
|
||||
#![cfg_attr(feature = "bench", feature(test))]
|
||||
#![warn(
|
||||
missing_docs,
|
||||
trivial_casts,
|
||||
trivial_numeric_casts,
|
||||
unused_extern_crates,
|
||||
unused_import_braces,
|
||||
unused_qualifications,
|
||||
)]
|
||||
#![warn(missing_docs, trivial_casts, trivial_numeric_casts, unused_extern_crates,
|
||||
unused_import_braces, unused_qualifications)]
|
||||
|
||||
#[cfg(feature = "bench")]
|
||||
extern crate test;
|
||||
|
@ -20,9 +14,9 @@ extern crate log;
|
|||
extern crate derivative;
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
extern crate atomic_refcell;
|
||||
extern crate num;
|
||||
extern crate time;
|
||||
extern crate atomic_refcell;
|
||||
|
||||
mod pcg32;
|
||||
mod lru_cache;
|
||||
|
|
|
@ -121,7 +121,7 @@ impl<K: Clone + Hash + Eq, V> LRUCache<K, V> {
|
|||
/// Removes an item from the linked list.
|
||||
fn remove_from_list(&mut self, i: usize) {
|
||||
let (prev, next) = {
|
||||
let entry = self.entries.get_mut(i).unwrap();
|
||||
let entry = &mut self.entries[i];
|
||||
(entry.prev, entry.next)
|
||||
};
|
||||
match (prev, next) {
|
||||
|
|
193
src/macros.rs
193
src/macros.rs
|
@ -14,46 +14,48 @@ macro_rules! time {
|
|||
let value = $body;
|
||||
$timer.stop(start_time);
|
||||
value
|
||||
}}
|
||||
}};
|
||||
}
|
||||
|
||||
/// AppMetrics can be used from anywhere (public), does not need to declare metrics in this block.
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! app_metrics {
|
||||
// TYPED
|
||||
// typed, public, no metrics
|
||||
($METRIC_TYPE:ty, pub $METRIC_ID:ident = $e:expr;) => {
|
||||
(<$METRIC_TYPE:ty> pub $METRIC_ID:ident = $e:expr;) => {
|
||||
lazy_static! { pub static ref $METRIC_ID: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
};
|
||||
// typed, public, some metrics
|
||||
($METRIC_TYPE:ty, pub $METRIC_ID:ident = $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
(<$METRIC_TYPE:ty> pub $METRIC_ID:ident = $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
lazy_static! { pub static ref $METRIC_ID: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
__metrics_block!($METRIC_ID: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
// typed, module, no metrics
|
||||
($METRIC_TYPE:ty, $METRIC_ID:ident = $e:expr;) => {
|
||||
(<$METRIC_TYPE:ty> $METRIC_ID:ident = $e:expr;) => {
|
||||
lazy_static! { pub static ref $METRIC_ID: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
};
|
||||
// typed, module, some metrics
|
||||
($METRIC_TYPE:ty, $METRIC_ID:ident = $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
(<$METRIC_TYPE:ty> $METRIC_ID:ident = $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
lazy_static! { pub static ref $METRIC_ID: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
__metrics_block!($METRIC_ID: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
// typed, reuse predeclared
|
||||
($METRIC_TYPE:ty, $METRIC_ID:ident => { $($REMAINING:tt)+ }) => {
|
||||
(<$METRIC_TYPE:ty> $METRIC_ID:ident => { $($REMAINING:tt)+ }) => {
|
||||
__metrics_block!($METRIC_ID: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
// typed, unidentified, some metrics
|
||||
($METRIC_TYPE:ty, $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
(<$METRIC_TYPE:ty> $e:expr => { $($REMAINING:tt)+ }) => {
|
||||
lazy_static! { pub static ref UNIDENT_METRIC: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
__metrics_block!(UNIDENT_METRIC: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
// typed, root, some metrics
|
||||
($METRIC_TYPE:ty, { $($REMAINING:tt)+ }) => {
|
||||
(<$METRIC_TYPE:ty> { $($REMAINING:tt)+ }) => {
|
||||
lazy_static! { pub static ref ROOT_METRICS: AppMetrics<$METRIC_TYPE> = "".into(); }
|
||||
__metrics_block!(ROOT_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
|
||||
|
||||
// DELEGATED
|
||||
// delegated, public, no metrics
|
||||
(pub $METRIC_ID:ident = $e:expr;) => {
|
||||
lazy_static! { pub static ref $METRIC_ID: AppMetrics<Delegate> = $e.into(); }
|
||||
|
@ -76,7 +78,6 @@ macro_rules! app_metrics {
|
|||
($METRIC_ID:ident => { $($REMAINING:tt)+ }) => {
|
||||
__metrics_block!($METRIC_ID: Delegate; $($REMAINING)*);
|
||||
};
|
||||
|
||||
// delegated, unidentified, some metrics
|
||||
($e:expr => { $($REMAINING:tt)+ }) => {
|
||||
lazy_static! { pub static ref UNIDENT_METRIC: AppMetrics<Delegate> = $e.into(); }
|
||||
|
@ -89,188 +90,131 @@ macro_rules! app_metrics {
|
|||
};
|
||||
}
|
||||
|
||||
// ModMetrics be used from declaring module, does not need to declare metrics in this block.
|
||||
#[macro_export]
|
||||
#[deprecated]
|
||||
macro_rules! mod_metrics {
|
||||
($METRIC_TYPE:ty, $METRIC_ID:ident = $e:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { static ref $METRIC_ID: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
__metrics_block!($METRIC_ID: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
|
||||
// Anonymous Mod Metrics
|
||||
// Can't be used outside macro, any metrics must be declared in same block.
|
||||
($METRIC_TYPE:ty, $e:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { static ref __LOCAL_METRICS: AppMetrics<$METRIC_TYPE> = $e.into(); }
|
||||
__metrics_block!(__LOCAL_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// Internal macro required to abstract over pub/non-pub versions of the macro
|
||||
#[macro_export]
|
||||
#[doc(hidden)]
|
||||
macro_rules! __metrics_block {
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* pub @Counter $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppCounter<$METRIC_TYPE> = $APP_METRICS.counter($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* pub @Counter $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID:
|
||||
AppCounter<$METRIC_TYPE> = $APP_METRICS.counter($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* @Counter $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID: AppCounter<$METRIC_TYPE> = $APP_METRICS.counter($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* @Counter $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID:
|
||||
AppCounter<$METRIC_TYPE> = $APP_METRICS.counter($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* pub @Marker $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMarker<$METRIC_TYPE> = $APP_METRICS.marker($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* pub @Marker $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID:
|
||||
AppMarker<$METRIC_TYPE> = $APP_METRICS.marker($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* @Marker $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID: AppMarker<$METRIC_TYPE> = $APP_METRICS.marker($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* @Marker $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID:
|
||||
AppMarker<$METRIC_TYPE> = $APP_METRICS.marker($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* pub @Gauge $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppGauge<$METRIC_TYPE> = $APP_METRICS.gauge($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* pub @Gauge $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID:
|
||||
AppGauge<$METRIC_TYPE> = $APP_METRICS.gauge($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* @Gauge $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID: AppGauge<$METRIC_TYPE> = $APP_METRICS.gauge($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* @Gauge $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID:
|
||||
AppGauge<$METRIC_TYPE> = $APP_METRICS.gauge($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* pub @Timer $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppTimer<$METRIC_TYPE> = $APP_METRICS.timer($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* pub @Timer $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* pub static ref $METRIC_ID:
|
||||
AppTimer<$METRIC_TYPE> = $APP_METRICS.timer($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty; $(#[$attr:meta])* @Timer $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID: AppTimer<$METRIC_TYPE> = $APP_METRICS.timer($METRIC_NAME); }
|
||||
($APP_METRICS:ident : $METRIC_TYPE:ty;
|
||||
$(#[$attr:meta])* @Timer $METRIC_ID:ident : $METRIC_NAME:expr; $($REMAINING:tt)*) => {
|
||||
lazy_static! { $(#[$attr])* static ref $METRIC_ID:
|
||||
AppTimer<$METRIC_TYPE> = $APP_METRICS.timer($METRIC_NAME); }
|
||||
__metrics_block!($APP_METRICS: $METRIC_TYPE; $($REMAINING)*);
|
||||
};
|
||||
($METRIC_ID:ident : $METRIC_TYPE:ty;) => ()
|
||||
}
|
||||
|
||||
|
||||
/// Define application-scoped markers.
|
||||
#[macro_export]
|
||||
#[deprecated]
|
||||
macro_rules! marker {
|
||||
($type_param: ty, $app_metrics: expr, { $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id: AppMarker<$type_param> = $app_metrics.marker( $metric_name );)* }
|
||||
macro_rules! app_marker {
|
||||
(<$type_param: ty> $app_metrics: expr =>
|
||||
{ $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id:
|
||||
AppMarker<$type_param> = $app_metrics.marker( $metric_name );)* }
|
||||
};
|
||||
}
|
||||
|
||||
/// Define application-scoped counters.
|
||||
#[macro_export]
|
||||
#[deprecated]
|
||||
macro_rules! counter {
|
||||
($type_param: ty, $app_metrics: expr, { $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id: AppCounter<$type_param> = $app_metrics.counter( $metric_name );)* }
|
||||
macro_rules! app_counter {
|
||||
(<$type_param: ty> $app_metrics: expr =>
|
||||
{ $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id:
|
||||
AppCounter<$type_param> = $app_metrics.counter( $metric_name );)* }
|
||||
};
|
||||
}
|
||||
|
||||
/// Define application-scoped gauges.
|
||||
#[macro_export]
|
||||
#[deprecated]
|
||||
macro_rules! gauge {
|
||||
($type_param: ty, $app_metrics: expr, { $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id: AppGauge<$type_param> = $app_metrics.gauge( $metric_name );)* }
|
||||
macro_rules! app_gauge {
|
||||
(<$type_param: ty> $app_metrics: expr =>
|
||||
{ $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id:
|
||||
AppGauge<$type_param> = $app_metrics.gauge( $metric_name );)* }
|
||||
};
|
||||
}
|
||||
|
||||
/// Define application-scoped timers.
|
||||
#[macro_export]
|
||||
#[deprecated]
|
||||
macro_rules! timer {
|
||||
($type_param: ty, $app_metrics: expr, { $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id: AppTimer<$type_param> = $app_metrics.timer( $metric_name );)* }
|
||||
macro_rules! app_timer {
|
||||
(<$type_param: ty> $app_metrics: expr =>
|
||||
{ $($metric_id: ident: $metric_name: expr),* $(,)* } ) => {
|
||||
lazy_static! { $(pub static ref $metric_id:
|
||||
AppTimer<$type_param> = $app_metrics.timer( $metric_name );)* }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
///// Define delegated metrics.
|
||||
//#[macro_export]
|
||||
//macro_rules! delegated_metrics {
|
||||
// // Public delegation point
|
||||
// ($(#[$attr:meta])* pub $METRIC_ID:ident = $e:expr;) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Delegate> = $e.into(); }
|
||||
// };
|
||||
// // Local delegation point
|
||||
// ($(#[$attr:meta])* $METRIC_ID:ident = $e:expr;) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Delegate> = $e.into(); }
|
||||
// };
|
||||
//
|
||||
//
|
||||
// // Public delegation point and some metrics
|
||||
// ($(#[$attr:meta])* pub $METRIC_ID:ident = $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Delegate> = $e.into(); }
|
||||
// __metrics_block!($METRIC_ID: Delegate ; $($REMAINING)*);
|
||||
// };
|
||||
// // Local delegation point and some metrics
|
||||
// ($(#[$attr:meta])* $METRIC_ID:ident = $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Delegate> = $e.into(); }
|
||||
// __metrics_block!($METRIC_ID: Delegate ; $($REMAINING)*);
|
||||
// };
|
||||
// // Anonymous delegation point and some metrics
|
||||
// ($(#[$attr:meta])* $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* static ref __LOCAL_METRICS: AppMetrics<Delegate> = $e.into(); }
|
||||
// __metrics_block!(__LOCAL_METRICS: Delegate ; $($REMAINING)*);
|
||||
// };
|
||||
//}
|
||||
//
|
||||
///// Define delegated metrics.
|
||||
//#[macro_export]
|
||||
//macro_rules! aggregated_metrics {
|
||||
// // Public delegation point
|
||||
// ($(#[$attr:meta])* pub $METRIC_ID:ident = $e:expr;) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Aggregate> = $e.into(); }
|
||||
// };
|
||||
// // Local delegation point
|
||||
// ($(#[$attr:meta])* $METRIC_ID:ident = $e:expr;) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Aggregate> = $e.into(); }
|
||||
// };
|
||||
//
|
||||
//
|
||||
// // Public delegation point and some metrics
|
||||
// ($(#[$attr:meta])* pub $METRIC_ID:ident = $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Aggregate> = $e.into(); }
|
||||
// __metrics_block!($METRIC_ID: Aggregate ; $($REMAINING)*);
|
||||
// };
|
||||
// // Local delegation point and some metrics
|
||||
// ($(#[$attr:meta])* $METRIC_ID:ident = $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* pub static ref $METRIC_ID: AppMetrics<Aggregate> = $e.into(); }
|
||||
// __metrics_block!($METRIC_ID: Aggregate ; $($REMAINING)*);
|
||||
// };
|
||||
// // Anonymous delegation point and some metrics
|
||||
// ($(#[$attr:meta])* $e:expr => {$($REMAINING:tt)+}) => {
|
||||
// lazy_static! { $(#[$attr])* static ref __LOCAL_METRICS: AppMetrics<Aggregate> = $e.into(); }
|
||||
// __metrics_block!(__LOCAL_METRICS: Aggregate ; $($REMAINING)*);
|
||||
// };
|
||||
//}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test_app {
|
||||
use self_metrics::*;
|
||||
|
||||
app_metrics!(TEST_METRICS <Aggregate> = DIPSTICK_METRICS.with_prefix("test_prefix"));
|
||||
app_metrics!(<Aggregate> TEST_METRICS = DIPSTICK_METRICS.with_prefix("test_prefix"););
|
||||
|
||||
app_marker!(Aggregate, TEST_METRICS, {
|
||||
app_marker!(<Aggregate> TEST_METRICS => {
|
||||
M1: "failed",
|
||||
M2: "success",
|
||||
});
|
||||
|
||||
app_counter!(Aggregate, TEST_METRICS, {
|
||||
app_counter!(<Aggregate> TEST_METRICS => {
|
||||
C1: "failed",
|
||||
C2: "success",
|
||||
});
|
||||
|
||||
app_gauge!(Aggregate, TEST_METRICS, {
|
||||
app_gauge!(<Aggregate> TEST_METRICS => {
|
||||
G1: "failed",
|
||||
G2: "success",
|
||||
});
|
||||
|
||||
app_timer!(Aggregate, TEST_METRICS, {
|
||||
app_timer!(<Aggregate> TEST_METRICS => {
|
||||
T1: "failed",
|
||||
T2: "success",
|
||||
});
|
||||
|
||||
|
||||
#[test]
|
||||
fn call_macro_defined_metrics() {
|
||||
M1.mark();
|
||||
|
@ -286,4 +230,3 @@ mod test_app {
|
|||
T2.interval_us(2);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
16
src/multi.rs
16
src/multi.rs
|
@ -20,7 +20,7 @@ where
|
|||
move |kind, name, rate| {
|
||||
(
|
||||
combo.0.define_metric(kind, name, rate),
|
||||
combo.1.define_metric(kind, &name, rate),
|
||||
combo.1.define_metric(kind, name, rate),
|
||||
)
|
||||
},
|
||||
move |buffered| {
|
||||
|
@ -44,9 +44,9 @@ where
|
|||
}
|
||||
|
||||
impl<M1, M2> From<(ScopeMetrics<M1>, ScopeMetrics<M2>)> for AppMetrics<(M1, M2)>
|
||||
where
|
||||
M1: 'static + Clone + Send + Sync,
|
||||
M2: 'static + Clone + Send + Sync,
|
||||
where
|
||||
M1: 'static + Clone + Send + Sync,
|
||||
M2: 'static + Clone + Send + Sync,
|
||||
{
|
||||
fn from(combo: (ScopeMetrics<M1>, ScopeMetrics<M2>)) -> AppMetrics<(M1, M2)> {
|
||||
let chain: ScopeMetrics<(M1, M2)> = combo.into();
|
||||
|
@ -84,7 +84,7 @@ where
|
|||
for (i, scope) in scopes.iter().enumerate() {
|
||||
scope.write(&metric[i], value)
|
||||
}
|
||||
},
|
||||
}
|
||||
ScopeCmd::Flush => for scope in &scopes {
|
||||
scope.flush()
|
||||
},
|
||||
|
@ -95,11 +95,11 @@ where
|
|||
}
|
||||
|
||||
impl<'a, M> From<&'a [ScopeMetrics<M>]> for AppMetrics<Vec<M>>
|
||||
where
|
||||
M: 'static + Clone + Send + Sync,
|
||||
where
|
||||
M: 'static + Clone + Send + Sync,
|
||||
{
|
||||
fn from(chains: &'a [ScopeMetrics<M>]) -> AppMetrics<Vec<M>> {
|
||||
let chain: ScopeMetrics<Vec<M>> = chains.into();
|
||||
app_metrics(chain)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ const DEFAULT_SEPARATOR: &'static str = ".";
|
|||
|
||||
/// A list of parts of a metric's name.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Namespace (Vec<String>);
|
||||
pub struct Namespace(Vec<String>);
|
||||
|
||||
impl Namespace {
|
||||
/// Make this namespace a subspace of the parent.
|
||||
|
@ -45,24 +45,23 @@ where
|
|||
Self: Sized,
|
||||
{
|
||||
/// Insert prefix in newly defined metrics.
|
||||
// #[deprecated(since = "0.6.3", note = "Use `with_name` instead.")]
|
||||
// #[deprecated(since = "0.6.3", note = "Use `with_name` instead.")]
|
||||
fn with_prefix<AS: AsRef<str>>(&self, prefix: AS) -> Self {
|
||||
self.with_namespace(&[prefix.as_ref()])
|
||||
}
|
||||
|
||||
/// Join namespace and prepend in newly defined metrics.
|
||||
// #[deprecated(since = "0.6.3", note = "Use `with_name` instead.")]
|
||||
// #[deprecated(since = "0.6.3", note = "Use `with_name` instead.")]
|
||||
fn with_namespace(&self, names: &[&str]) -> Self {
|
||||
self.with_name(names)
|
||||
}
|
||||
|
||||
/// Join namespace and prepend in newly defined metrics.
|
||||
fn with_name<IN: Into<Namespace>>(&self, names: IN) -> Self;
|
||||
|
||||
}
|
||||
|
||||
/// Add a namespace decorator to a metric definition function.
|
||||
pub fn add_namespace<M: 'static>(names: &Namespace, next: DefineMetricFn<M>) -> DefineMetricFn<M> {
|
||||
pub fn add_namespace<M: 'static>(names: &Namespace, next: DefineMetricFn<M>) -> DefineMetricFn<M> {
|
||||
let nspace = names.join(DEFAULT_SEPARATOR);
|
||||
Arc::new(move |kind, name, rate| {
|
||||
let name = [nspace.as_ref(), name].join(DEFAULT_SEPARATOR);
|
||||
|
|
|
@ -20,7 +20,9 @@ pub fn to_stdout() -> ScopeMetrics<String> {
|
|||
control_scope(move |cmd| {
|
||||
let mut buf = buf.write().expect("Locking stdout buffer");
|
||||
match cmd {
|
||||
ScopeCmd::Write(metric, value) => buf.push_str(format!("{}: {}\n", metric, value).as_ref()),
|
||||
ScopeCmd::Write(metric, value) => {
|
||||
buf.push_str(format!("{}: {}\n", metric, value).as_ref())
|
||||
}
|
||||
ScopeCmd::Flush => {
|
||||
println!("{}", buf);
|
||||
buf.clear();
|
||||
|
@ -49,7 +51,9 @@ pub fn to_log() -> ScopeMetrics<String> {
|
|||
control_scope(move |cmd| {
|
||||
let mut buf = buf.write().expect("Locking string buffer");
|
||||
match cmd {
|
||||
ScopeCmd::Write(metric, value) => buf.push_str(format!("{}: {}\n", metric, value).as_ref()),
|
||||
ScopeCmd::Write(metric, value) => {
|
||||
buf.push_str(format!("{}: {}\n", metric, value).as_ref())
|
||||
}
|
||||
ScopeCmd::Flush => {
|
||||
info!("{}", buf);
|
||||
buf.clear();
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
//! ```
|
||||
//! use dipstick::*;
|
||||
//!
|
||||
//! let (sink, source) = aggregate();
|
||||
//! let app_metrics = aggregate(summary, to_stdout());
|
||||
//! publish(&source, &log("aggregated"), publish::all_stats);
|
||||
//! ```
|
||||
//!
|
||||
|
@ -13,8 +13,8 @@
|
|||
//! use dipstick::*;
|
||||
//! use std::time::Duration;
|
||||
//!
|
||||
//! let (sink, source) = aggregate();
|
||||
//! let job = publish_every(Duration::from_millis(100), &source, &log("aggregated"), publish::all_stats);
|
||||
//! let (sink, source) = aggregate(summary, to_stdout());
|
||||
//! let job = publish_every(Duration::from_millis(100), &source, &log("aggregated"), all_stats);
|
||||
//! // publish will go on until cancelled
|
||||
//! job.cancel();
|
||||
//! ```
|
||||
|
@ -38,7 +38,8 @@ pub trait Publish: Send + Sync + Debug {
|
|||
#[derive(Derivative, Clone)]
|
||||
#[derivative(Debug)]
|
||||
pub struct Publisher<E, M> {
|
||||
#[derivative(Debug = "ignore")] statistics: Box<E>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
statistics: Box<E>,
|
||||
target_chain: ScopeMetrics<M>,
|
||||
}
|
||||
|
||||
|
|
|
@ -36,15 +36,13 @@ impl<M: Send + Sync + 'static + Clone> WithSamplingRate for ScopeMetrics<M> {
|
|||
}),
|
||||
Arc::new(move |buffered| {
|
||||
let next_scope = scope_fn(buffered);
|
||||
control_scope(move |cmd| {
|
||||
match cmd {
|
||||
ScopeCmd::Write(metric, value) => {
|
||||
if pcg32::accept_sample(int_sampling_rate) {
|
||||
next_scope.write(metric, value)
|
||||
}
|
||||
},
|
||||
ScopeCmd::Flush => next_scope.flush()
|
||||
control_scope(move |cmd| match cmd {
|
||||
ScopeCmd::Write(metric, value) => {
|
||||
if pcg32::accept_sample(int_sampling_rate) {
|
||||
next_scope.write(metric, value)
|
||||
}
|
||||
}
|
||||
ScopeCmd::Flush => next_scope.flush(),
|
||||
})
|
||||
}),
|
||||
)
|
||||
|
|
|
@ -9,15 +9,16 @@ use std::sync::Arc;
|
|||
use cache::*;
|
||||
use namespace::*;
|
||||
|
||||
|
||||
/// A pair of functions composing a twin "chain of command".
|
||||
/// This is the building block for the metrics backend.
|
||||
#[derive(Derivative, Clone)]
|
||||
#[derivative(Debug)]
|
||||
pub struct ScopeMetrics<M> {
|
||||
#[derivative(Debug = "ignore")] define_metric_fn: DefineMetricFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
define_metric_fn: DefineMetricFn<M>,
|
||||
|
||||
#[derivative(Debug = "ignore")] scope_metric_fn: OpenScopeFn<M>,
|
||||
#[derivative(Debug = "ignore")]
|
||||
scope_metric_fn: OpenScopeFn<M>,
|
||||
}
|
||||
|
||||
impl<M> ScopeMetrics<M> {
|
||||
|
@ -64,9 +65,9 @@ impl<M> ScopeMetrics<M> {
|
|||
impl<M: Send + Sync + Clone + 'static> ScopeMetrics<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
|
||||
MF: Fn(Kind, &str, Rate) -> M + Send + Sync + 'static,
|
||||
WF: Fn(bool) -> ControlScopeFn<M> + Send + Sync + 'static,
|
||||
where
|
||||
MF: Fn(Kind, &str, Rate) -> M + Send + Sync + 'static,
|
||||
WF: Fn(bool) -> ControlScopeFn<M> + Send + Sync + 'static,
|
||||
{
|
||||
ScopeMetrics {
|
||||
// capture the provided closures in Arc to provide cheap clones
|
||||
|
@ -101,9 +102,9 @@ impl<M: Send + Sync + Clone + 'static> ScopeMetrics<M> {
|
|||
|
||||
/// Intercept both metric definition and scope creation, possibly changing the metric type.
|
||||
pub fn mod_both<MF, N>(&self, mod_fn: MF) -> ScopeMetrics<N>
|
||||
where
|
||||
MF: Fn(DefineMetricFn<M>, OpenScopeFn<M>) -> (DefineMetricFn<N>, OpenScopeFn<N>),
|
||||
N: Clone + Send + Sync,
|
||||
where
|
||||
MF: Fn(DefineMetricFn<M>, OpenScopeFn<M>) -> (DefineMetricFn<N>, OpenScopeFn<N>),
|
||||
N: Clone + Send + Sync,
|
||||
{
|
||||
let (metric_fn, scope_fn) =
|
||||
mod_fn(self.define_metric_fn.clone(), self.scope_metric_fn.clone());
|
||||
|
@ -115,8 +116,8 @@ impl<M: Send + Sync + Clone + 'static> ScopeMetrics<M> {
|
|||
|
||||
/// Intercept scope creation.
|
||||
pub fn mod_scope<MF>(&self, mod_fn: MF) -> Self
|
||||
where
|
||||
MF: Fn(OpenScopeFn<M>) -> OpenScopeFn<M>,
|
||||
where
|
||||
MF: Fn(OpenScopeFn<M>) -> OpenScopeFn<M>,
|
||||
{
|
||||
ScopeMetrics {
|
||||
define_metric_fn: self.define_metric_fn.clone(),
|
||||
|
@ -140,7 +141,6 @@ impl<M: Send + Sync + Clone + 'static> WithCache for ScopeMetrics<M> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
impl<M: Send + Sync + Clone + 'static> WithNamespace for ScopeMetrics<M> {
|
||||
fn with_name<IN: Into<Namespace>>(&self, names: IN) -> Self {
|
||||
let ref ninto = names.into();
|
||||
|
@ -179,8 +179,8 @@ impl<M> ScopeCounter<M> {
|
|||
/// Record a value count.
|
||||
#[inline]
|
||||
pub fn count<V>(&self, scope: &mut ControlScopeFn<M>, count: V)
|
||||
where
|
||||
V: ToPrimitive,
|
||||
where
|
||||
V: ToPrimitive,
|
||||
{
|
||||
scope.write(&self.metric, count.to_u64().unwrap());
|
||||
}
|
||||
|
@ -197,8 +197,8 @@ impl<M: Clone> ScopeGauge<M> {
|
|||
/// Record a value point for this gauge.
|
||||
#[inline]
|
||||
pub fn value<V>(&self, scope: &mut ControlScopeFn<M>, value: V)
|
||||
where
|
||||
V: ToPrimitive,
|
||||
where
|
||||
V: ToPrimitive,
|
||||
{
|
||||
scope.write(&self.metric, value.to_u64().unwrap());
|
||||
}
|
||||
|
@ -221,8 +221,8 @@ impl<M: Clone> ScopeTimer<M> {
|
|||
/// Can be used in place of start()/stop() if an external time interval source is used
|
||||
#[inline]
|
||||
pub fn interval_us<V>(&self, scope: &mut ControlScopeFn<M>, interval_us: V) -> V
|
||||
where
|
||||
V: ToPrimitive,
|
||||
where
|
||||
V: ToPrimitive,
|
||||
{
|
||||
scope.write(&self.metric, interval_us.to_u64().unwrap());
|
||||
interval_us
|
||||
|
@ -252,8 +252,8 @@ impl<M: Clone> ScopeTimer<M> {
|
|||
/// Record the time taken to execute the provided closure
|
||||
#[inline]
|
||||
pub fn time<F, R>(&self, scope: &mut ControlScopeFn<M>, operations: F) -> R
|
||||
where
|
||||
F: FnOnce() -> R,
|
||||
where
|
||||
F: FnOnce() -> R,
|
||||
{
|
||||
let start_time = self.start();
|
||||
let value: R = operations();
|
||||
|
|
|
@ -18,7 +18,7 @@ lazy_static! {
|
|||
|
||||
/// Application metrics are collected to the aggregator
|
||||
|
||||
app_metrics!(Aggregate, DIPSTICK_METRICS = build_self_metrics(););
|
||||
app_metrics!(<Aggregate> DIPSTICK_METRICS = build_self_metrics(););
|
||||
|
||||
fn build_aggregator() -> Aggregator {
|
||||
// TODO make publishable
|
||||
|
@ -35,4 +35,3 @@ fn build_self_metrics() -> AppMetrics<Aggregate> {
|
|||
let am: AppMetrics<Aggregate> = mug.clone().into();
|
||||
am.with_prefix("dipstick")
|
||||
}
|
||||
|
||||
|
|
|
@ -10,10 +10,11 @@ use std::sync::{Arc, RwLock};
|
|||
|
||||
pub use std::net::ToSocketAddrs;
|
||||
|
||||
mod_metrics! {
|
||||
Aggregate, DIPSTICK_METRICS.with_prefix("statsd");
|
||||
@Marker SEND_ERR: "send_failed";
|
||||
@Counter SENT_BYTES: "sent_bytes";
|
||||
app_metrics! {
|
||||
<Aggregate> DIPSTICK_METRICS.with_prefix("statsd") => {
|
||||
@Marker SEND_ERR: "send_failed";
|
||||
@Counter SENT_BYTES: "sent_bytes";
|
||||
}
|
||||
}
|
||||
|
||||
/// Send metrics to a statsd server at the address and port provided.
|
||||
|
|
|
@ -1 +1 @@
|
|||
include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));
|
||||
include!(concat!(env!("OUT_DIR"), "/skeptic-tests.rs"));
|
||||
|
|
Loading…
Reference in New Issue