6 releases (breaking)

0.5.0 Mar 6, 2024
0.4.0 Aug 19, 2022
0.3.0 Feb 6, 2021
0.2.0 Nov 22, 2020
0.1.0 Oct 29, 2020

#2 in #task-pool

Download history 19/week @ 2023-12-22 31/week @ 2023-12-29 135/week @ 2024-01-05 37/week @ 2024-01-12 88/week @ 2024-01-19 33/week @ 2024-01-26 60/week @ 2024-02-02 72/week @ 2024-02-09 106/week @ 2024-02-16 113/week @ 2024-02-23 158/week @ 2024-03-01 106/week @ 2024-03-08 113/week @ 2024-03-15 87/week @ 2024-03-22 58/week @ 2024-03-29 38/week @ 2024-04-05

318 downloads per month

MIT license

33KB
626 lines

Metric Sinks for Cadence built on Tokio

Crates.io Docs.rs

A collection of Cadence Metric Sink implementations that process metrics asynchronously using Tokio.

The Statsd client provided by Cadence does not support asynchronous operation -- submitting a metric may in fact block the caller!

This is undesirable in asynchronous contexts.

The Metric Sinks implemented in this crate alleviate this issue by allowing the application code to enqueue metrics without blocking, and offloading their actual sending to a separate asynchronous task.

Features

  • emit metrics without blocking by utilizing a non-blocking, buffered channel
  • batch multiple metrics, up to a maximum delay (or when the batch buffer fills up)
  • process metrics asynchronously in a Tokio task pool of the application's choice

Installation

Add cadence, tokio, and tokio-cadence to your Cargo.toml:

[dependencies]
cadence = "1"
tokio = { version = "1", features = ["full"] }
tokio-cadence = "0.5"

Usage

The Metric Sink constructors return a tuple consisting of the sink instance itself as well as a future, which the application must drive to completion; e.g., spawn it in a Tokio task pool.

use cadence::prelude::*;
use cadence::{StatsdClient, DEFAULT_PORT};
use tokio_cadence::TokioBatchUdpMetricSink;
use tokio::{spawn, net::UdpSocket};

#[tokio::main]
async fn main() -> cadence::MetricResult<()> {
    let host = ("metrics.example.com", DEFAULT_PORT);
    let socket = UdpSocket::bind("0.0.0.0:0").await?;
    let (sink, process) = TokioBatchUdpMetricSink::from(host, socket)?;

    // Spawn the future!
    let processing_job = spawn(process);

    {
        let client = StatsdClient::from_sink("my.metrics", sink);

        // Emit metrics!
        client.incr("some.counter");
        client.time("some.methodCall", 42);
        client.gauge("some.thing", 7);
        client.meter("some.value", 5);

        // the client drops here, and the sink along with it
    }

    // Wait for the processing job to complete!
    processing_job.await.unwrap();
    Ok(())
}

Note that in order to ensure that all buffered metrics are submitted, the application must await the completion of the processing job after the client, as well as the sink along with it, are dropped.

License

Licensed under the MIT license.

Dependencies

~3–13MB
~117K SLoC