Updating README

This commit is contained in:
Francis Lalonde 2018-09-19 16:38:17 -04:00
parent 35c90336b7
commit dc50862ed0
2 changed files with 98 additions and 242 deletions

98
handbook/01_basics.md Normal file
View File

@ -0,0 +1,98 @@
OUT OF DATE for v0.7
Send metrics to multiple outputs:
```rust,skt-fail,no_run
let _app_metrics = metric_scope((
to_stdout(),
to_statsd("localhost:8125")?.with_namespace(&["my", "app"])
));
```
Since instruments are decoupled from the backend, outputs can be swapped easily.
Aggregate metrics and schedule to be periodical publication in the background:
```rust,skt-run
use std::time::Duration;
let app_metrics = metric_scope(aggregate());
route_aggregate_metrics(to_stdout());
app_metrics.flush_every(Duration::from_secs(3));
```
Aggregation is performed locklessly and is very fast.
Count, sum, min, max and average are tracked where they make sense.
Published statistics can be selected with presets such as `all_stats` (see previous example),
`summary`, `average`.
For more control over published statistics, provide your own strategy:
```rust,skt-run
metrics(aggregate());
set_default_aggregate_fn(|_kind, name, score|
match score {
ScoreType::Count(count) =>
Some((Kind::Counter, vec![name, ".per_thousand"], count / 1000)),
_ => None
});
```
Apply statistical sampling to metrics:
```rust,skt-fail
let _app_metrics = metric_scope(to_statsd("server:8125")?.with_sampling_rate(0.01));
```
A fast random algorithm is used to pick samples.
Outputs can use sample rate to expand or format published data.
Metrics can be recorded asynchronously:
```rust,skt-run
let _app_metrics = metric_scope(to_stdout().with_async_queue(64));
```
The async queue uses a Rust channel and a standalone thread.
The current behavior is to block when full.
For speed and easier maintenance, metrics are usually defined statically:
```rust,skt-plain
#[macro_use] extern crate dipstick;
#[macro_use] extern crate lazy_static;
use dipstick::*;
metrics!("my_app" => {
COUNTER_A: Counter = "counter_a";
});
fn main() {
route_aggregate_metrics(to_stdout());
COUNTER_A.count(11);
}
```
Metric definition macros are just `lazy_static!` wrappers.
Where necessary, metrics can be defined _ad-hoc_:
```rust,skt-run
let user_name = "john_day";
let app_metrics = metric_scope(to_log()).with_cache(512);
app_metrics.gauge(format!("gauge_for_user_{}", user_name)).value(44);
```
Defining a cache is optional but will speed up re-definition of common ad-hoc metrics.
Timers can be used multiple ways:
```rust,skt-run
let app_metrics = metric_scope(to_stdout());
let timer = app_metrics.timer("my_timer");
time!(timer, {/* slow code here */} );
timer.time(|| {/* slow code here */} );
let start = timer.start();
/* slow code here */
timer.stop(start);
timer.interval_us(123_456);
```
Related metrics can share a namespace:
```rust,skt-run
let app_metrics = metric_scope(to_stdout());
let db_metrics = app_metrics.add_prefix("database");
let _db_timer = db_metrics.timer("db_timer");
let _db_counter = db_metrics.counter("db_counter");
```

View File

@ -1,242 +0,0 @@
//use core::*;
//
////use async_queue::WithAsyncQueue;
////use sample::WithSamplingRate;
//use bucket::Bucket;
//
///// Backward compatibility alias.
//pub type Aggregate = Bucket;
//
/////// Aggregate metrics in memory.
/////// Depending on the type of metric, count, sum, minimum and maximum of values will be tracked.
/////// Needs to be connected to a publish to be useful.
////#[deprecated(since = "0.7.0", note = "Use `Bucket::new()` instead.")]
////pub fn aggregate<M, E, P>(stats_fn: E, pub_scope: P) -> Bucket
//// where
//// E: Fn(Kind, Name, ScoreType) -> Option<(Kind, Name, Value)> + Send + Sync + 'static,
//// P: Into<MetricOutput<M>>,
//// M: Send + Sync + 'static + Clone,
////{
//// let agg = Bucket::new();
//// agg.set_stats(stats_fn);
//// agg.set_output(pub_scope);
//// agg
////}
////
/////// Enqueue collected metrics for dispatch on background thread.
////#[deprecated(since = "0.5.0", note = "Use `with_async_queue` instead.")]
////pub fn async<M, IC>(queue_size: usize, chain: IC) -> MetricOutput<M>
//// where
//// M: Clone + Send + Sync + 'static,
//// IC: Into<MetricOutput<M>>,
////{
//// let chain = chain.into();
//// chain.with_async_queue(queue_size)
////}
////
/////// Perform random sampling of values according to the specified rate.
////#[deprecated(since = "0.5.0", note = "Use `with_sampling_rate` instead.")]
////pub fn sample<M, IC>(sampling_rate: Sampling, chain: IC) -> MetricOutput<M>
//// where
//// M: Clone + Send + Sync + 'static,
//// IC: Into<MetricOutput<M>>,
////{
//// let chain = chain.into();
//// chain.with_sampling_rate(sampling_rate)
////}
////
/////// Wrap the metrics backend to provide an application-friendly interface.
/////// Open a metric scope to share across the application.
////#[deprecated(since = "0.7.0", note = "Use into() instead")]
////pub fn app_metrics<M, AM>(scope: AM) -> MetricScope<M>
//// where
//// M: Clone + Send + Sync + 'static,
//// AM: Into<MetricScope<M>>,
////{
//// scope.into()
////}
//
///// Help transition to new syntax
//#[deprecated(since = "0.7.0", note = "Use Metrics instead")]
//pub type AppMetrics = Input;
//
///// Help transition to new syntax
//#[deprecated(since = "0.7.0", note = "Use Marker instead")]
//pub type AppMarker = Marker;
//
///// Help transition to new syntax
//#[deprecated(since = "0.7.0", note = "Use Counter instead")]
//pub type AppCounter = Counter;
//
///// Help transition to new syntax
//#[deprecated(since = "0.7.0", note = "Use Gauge instead")]
//pub type AppGauge = Gauge;
//
///// Help transition to new syntax
//#[deprecated(since = "0.7.0", note = "Use Timer instead")]
//pub type AppTimer = Timer;
//
///// Define application-scoped metrics.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! app_metrics {
// (<$type_param:ty>, $metric_id:ident = $SCOPE:expr) => {
// lazy_static! {
// pub static ref $metric_id: $type_param = $SCOPE.into();
// }
// };
//}
//
///// Define application-scoped markers.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! app_marker {
// (<$type_param: ty> $SCOPE: expr => { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! {
// $(pub static ref $metric_id: Marker = $SCOPE.marker( $m_exp );)*
// }
// };
//}
//
///// Define application-scoped counters.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! app_counter {
// (<$type_param: ty> $SCOPE: expr => { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! {
// $(pub static ref $metric_id: Counter = $SCOPE.counter( $m_exp );)*
// }
// };
//}
//
///// Define application-scoped gauges.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! app_gauge {
// (<$type_param: ty> $SCOPE: expr => { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! {
// $(pub static ref $metric_id: Gauge = $SCOPE.gauge( $m_exp );)*
// }
// };
//}
//
///// Define application-scoped timers.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! app_timer {
// (<$type_param: ty> $SCOPE: expr => { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! {
// $(pub static ref $metric_id: Timer = $SCOPE.timer( $m_exp );)*
// }
// };
//}
//
///////////////
//// MOD SCOPE
//
///// Define module-scoped metrics.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! mod_metrics {
// ($type_param: ty, $metric_id: ident = ($($SCOPE: expr),+ $(,)*)) => {
// lazy_static! {
// static ref $metric_id: MetricScope<$type_param> = metric_scope(($($SCOPE),*));
// }
// };
// ($type_param: ty, $metric_id: ident = [$($SCOPE: expr),+ $(,)*]) => {
// lazy_static! { static ref $metric_id: MetricScope<$type_param> =
// metric_scope(&[$($SCOPE),*][..],); }
// };
// ($type_param: ty, $metric_id: ident = $mod_metrics: expr) => {
// lazy_static! { static ref $metric_id: MetricScope<$type_param> =
// $mod_metrics.into(); }
// };
//}
//
///// Define module-scoped markers.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! mod_marker {
// ($type_param: ty, $mod_metrics: expr, { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! { $(static ref $metric_id: Marker =
// $mod_metrics.marker( $m_exp );)* }
// };
//}
//
///// Define module-scoped counters.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! mod_counter {
// ($type_param: ty, $mod_metrics: expr, { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! { $(static ref $metric_id: Counter =
// $mod_metrics.counter( $m_exp );)* }
// };
//}
//
///// Define module-scoped gauges.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! mod_gauge {
// ($type_param: ty, $mod_metrics: expr, { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! { $(static ref $metric_id: Gauge =
// $mod_metrics.gauge( $m_exp );)* }
// };
// ($type_param: ty, $mod_metrics: expr, $metric_id: ident: $m_exp: expr) => {
// lazy_static! { static ref $metric_id: Gauge =
// $mod_metrics.gauge( $m_exp ); }
// }
//}
//
///// Define module-scoped timers.
//#[macro_export]
//#[deprecated(since = "0.7.0", note = "Use metrics!() instead")]
//macro_rules! mod_timer {
// ($type_param: ty, $mod_metrics: expr, { $($metric_id: ident: $m_exp: expr),* $(,)* } ) => {
// lazy_static! { $(static ref $metric_id: Timer =
// $mod_metrics.timer( $m_exp );)* }
// };
//}
//
//#[cfg(test)]
//mod legacy_test {
// use core::*;
// use self_metrics::*;
// use deprecated::*;
//
// app_metrics!(<Aggregate>, TEST_METRICS = DIPSTICK_METRICS.add_prefix("test_prefix"));
//
// app_marker!(<Aggregate> TEST_METRICS => {
// M1: "failed",
// M2: "success",
// });
//
// app_counter!(<Aggregate> TEST_METRICS => {
// C1: "failed",
// C2: "success",
// });
//
// app_gauge!(<Aggregate> TEST_METRICS => {
// G1: "failed",
// G2: "success",
// });
//
// app_timer!(<Aggregate> TEST_METRICS => {
// T1: "failed",
// T2: "success",
// });
//
// #[test]
// fn call_old_macro_defined_metrics() {
// M1.mark();
// M2.mark();
//
// C1.count(1);
// C2.count(2);
//
// G1.value(1);
// G2.value(2);
//
// T1.interval_us(1);
// T2.interval_us(2);
// }
//}