Crate dipstick [] [src]

A fast and modular metrics toolkit for all Rust applications. Similar to popular logging frameworks, but with counters, markers, gauges and timers.

Out of the box, Dipstick can aggregate, sample, cache and queue metrics (async). If aggregated, statistics can be published on demand or on schedule.

Dipstick does not bind application code to a single metrics output implementation. Outputs to_log, to_stdout and to_statsd are currently provided, and defining new modules is easy.

Dipstick builds on stable Rust with minimal dependencies.

use dipstick::*;
let app_metrics = metrics(to_log("metrics:"));
app_metrics.counter("my_counter").count(3);

Metrics can be sent to multiple outputs at the same time: rust let app_metrics = metrics((to_stdout(), to_statsd("localhost:8125", "app1.host."))); Since instruments are decoupled from the backend, outputs can be swapped easily.

Metrics can be aggregated and scheduled to be published periodically in the background: rust use std::time::Duration; let (to_aggregate, from_aggregate) = aggregate(); publish_every(Duration::from_secs(10), from_aggregate, to_log("last_ten_secs:"), all_stats); let app_metrics = metrics(to_aggregate); 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, a custom filter can be provided: rust let (_to_aggregate, from_aggregate) = aggregate(); publish(from_aggregate, to_log("my_custom_stats:"), |metric_kind, metric_name, metric_score| match metric_score { HitCount(hit_count) => Some((Counter, vec![metric_name, ".per_thousand"], hit_count / 1000)), _ => None });

Metrics can be statistically sampled: rust let app_metrics = metrics(sample(0.001, to_statsd("server:8125", "app.sampled."))); 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 let app_metrics = metrics(async(48, to_stdout())); The async queue uses a Rust channel and a standalone thread. The current behavior is to block when full.

Metric definitions can be cached to make using ad-hoc metrics faster: rust let app_metrics = metrics(cache(512, to_log())); app_metrics.gauge(format!("my_gauge_{}", 34)).value(44);

The preferred way is to predefine metrics, possibly in a lazy_static! block: ```rust

[macro_use] external crate lazy_static;

lazy_static! { pub static ref METRICS: AppMetrics> = metrics(to_stdout()); pub static ref COUNTER_A: Counter = METRICS.counter("counter_a"); } COUNTER_A.count(11); ```

Timers can be used multiple ways: ```rust 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 let db_metrics = app_metrics.with_prefix("database."); let db_timer = db_metrics.timer("db_timer"); let db_counter = db_metrics.counter("db_counter");

Reexports

pub use error::*;
pub use core::*;

Modules

core

Dipstick metrics core types and traits. This is mostly centered around the backend. Application-facing types are in the app module.

error

Error-chain like mechanism, without the error-chain dependency.

macros

Publicly exposed metric macros are defined here. Although dipstick does not have a macro-based API, in some situations they can make instrumented code simpler.

Macros

time

A convenience macro to wrap a block or an expression with a start / stop timer. Elapsed time is sent to the supplied statsd client after the computation has been performed. Expression result (if any) is transparently returned.

Structs

AggregateSink

A sink where to send metrics for aggregation. The parameters of aggregation may be set upon creation. Just clone() to use as a shared aggregator.

AggregateSource

Enumerate the metrics being aggregated and their scores.

Aggregator

Central aggregation structure. Since AggregateKeys themselves contain scores, the aggregator simply maintains a shared list of metrics for enumeration when used as source.

AppMetrics

Variations of this should also provide control of the metric recording scope.

CancelHandle

A handle to cancel a scheduled task if required.

Counter

A counter that sends values to the metrics backend

FnSink

FnSink delegates metric creation and scoping to the functions or closures it was provided upon its creation.

Gauge

A gauge that sends values to the metrics backend

METRICS_SOURCE

Source of dipstick inner metrics, for eventual publication.

Marker

A monotonic counter metric. Since value is only ever increased by one, no value parameter is provided, preventing programming errors.

MetricCache

A cache to help with ad-hoc defined metrics Does not alter the values of the metrics

MetricQueue

A metric command-queue using a sync channel. Each client thread gets it's own scope and sender. Writes are dispatched by a single receiving thread.

MetricScores

A metric that holds aggregated values. Some fields are kept public to ease publishing.

QueueCommand

Carry the scope command over the queue, from the sender, to be executed by the receiver.

Sample

The metric sampling key also holds the sampling rate to apply to it.

SampleSink

A sampling sink adapter.

ScopeCounter

A counter that sends values to the metrics backend

ScopeGauge

A gauge that sends values to the metrics backend

ScopeMarker

A monotonic counter metric. Since value is only ever increased by one, no value parameter is provided, preventing programming errors.

ScopeTimer

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 interval_us() method, providing an externally determined microsecond interval

ScopedMetrics

Variations of this should also provide control of the metric recording scope.

StatsdMetric

Key of a statsd metric.

StatsdSink

Allows sending metrics to a statsd server

Timer

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 interval_us() method, providing an externally determined microsecond interval

Enums

ScoreType

Possibly aggregated scores.

Traits

AsSource

Something that can be seen as a metric source.

ToPrimitive

A generic trait for converting a value to a number.

ToSocketAddrs

A trait for objects which can be converted or resolved to one or more SocketAddr values.

Functions

aggregate

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.

all_stats

A predefined export strategy reporting all aggregated stats for all metric types. Resulting stats are named by appending a short suffix to each metric's name.

async

Cache metrics to prevent them from being re-defined on every use. Use of this should be transparent, this has no effect on the values. Stateful sinks (i.e. Aggregate) may naturally cache their definitions.

average

A predefined export strategy reporting the average value for every non-marker metric. Marker metrics export their hit count instead.

cache

Cache metrics to prevent them from being re-defined on every use. Use of this should be transparent, this has no effect on the values. Stateful sinks (i.e. Aggregate) may naturally cache their definitions.

make_sink

Compose a sink dynamically using a generic FnSink. Two methods have to be provided: One to make new metrics and one to create scopes.

metrics

Wrap the metrics backend to provide an application-friendly interface.

publish

Define and write metrics from aggregated scores to the target channel If this is called repeatedly it can be a good idea to use the metric cache to prevent new metrics from being created every time.

publish_every

Schedules the publisher to run at recurrent intervals

sample

Perform random sampling of values according to the specified rate.

schedule

Schedule a task to run periodically. Starts a new thread for every task.

scope_metrics

Wrap the metrics backend to provide an application-friendly interface. When reporting a value, scoped metrics also need to be passed a [Scope]. New scopes can be obtained from

summary

A predefined single-stat-per-metric export strategy: - Timers and Counters each export their sums - Markers each export their hit count - Gauges each export their average

to_log

Write metric values to the standard log using info!.

to_statsd

Send metrics to a statsd server at the address and port provided.

to_stdout

Write metric values to stdout using println!.

to_void

Special sink that discards all metric values sent to it.

Type Definitions

Aggregate

The type of metric created by the AggregateSink. Each Aggregate

DoubleKey

Hold each sink's metric key.

DoubleSink

Hold the two target sinks. Multiple DoubleSinks can be combined if more than two sinks are needed.

MetricFn

Dynamic metric definition function. Metrics can be defined from any thread, concurrently (Fn is Sync). The resulting metrics themselves can be also be safely shared across threads ( is Send + Sync). Concurrent usage of a metric is done using threaded scopes. Shared concurrent scopes may be provided by some backends (aggregate).

QueueSender

Thread safe sender to the queue

ScoresSnapshot

To-be-published snapshot of aggregated score values for a metric.