Skip to content

Instantly share code, notes, and snippets.

@insanitybit
Created April 11, 2017 21:41
Show Gist options
  • Save insanitybit/f3eb7785444bed3a4c91eec18ce32c7d to your computer and use it in GitHub Desktop.
Save insanitybit/f3eb7785444bed3a4c91eec18ce32c7d to your computer and use it in GitHub Desktop.
#![allow(warnings)]
use std::thread::{JoinHandle, spawn};
use dogstatsd::{Client, Options};
use spmc::{Sender, Receiver, channel};
use std::error::Error;
use slog;
#[derive(Clone, Debug)]
pub enum Metric {
Timing(String, i64, Vec<String>),
Increment(String, Vec<String>),
Decrement(String, Vec<String>),
Gauge(String, String, Vec<String>),
Histogram(String, String, Vec<String>),
Event(String, String, Vec<String>),
Set(String, String, Vec<String>),
}
pub struct MetricActor {
sender: Sender<Metric>,
logger: slog::Logger
}
impl MetricActor {
pub fn new(workers: u16, logger: slog::Logger) -> MetricActor {
let (sender, receiver) = channel();
for _ in 0..workers {
let recv = receiver.clone();
let log = logger.clone();
spawn(move || {
loop {
let msg = match recv.recv() {
Ok(t) => t,
Err(e) => break
};
let client = Client::new(Options::default());
match msg {
Metric::Timing(stat, ms, tags) => MetricActor::_timing(client, &stat, ms, &tags[..], &log),
Metric::Increment(stat, tags) => MetricActor::_incr(client, &stat, &tags[..], &log),
Metric::Decrement(stat, tags) => MetricActor::_decr(client, &stat, &tags[..], &log),
Metric::Gauge(stat, value, tags) => MetricActor::_gauge(client, &stat, &value, &tags[..], &log),
Metric::Histogram(stat, value, tags) => MetricActor::_histogram(client, &stat, &value, &tags[..], &log),
Metric::Event(stat, value, tags) => MetricActor::_event(client, &stat, &value, &tags[..], &log),
Metric::Set(stat, value, tags) => MetricActor::_set(client, &stat, &value, &tags[..], &log),
}
}
});
}
MetricActor {
sender: sender,
logger: logger
}
}
pub fn timing(&self, stat: String, ms: i64, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Timing(stat, ms, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn incr(&self, stat: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn decr(&self, stat: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn gauge(&self, stat: String, value: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn histogram(&self, stat: String, value: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn event(&self, stat: String, value: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn set(&self, stat: String, value: String, tags: Vec<String>) {
if let Err(e) = self.sender.send(Metric::Increment(stat, tags)) {
error!(self.logger, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _timing(client: Client, stat: &str, ms: i64, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.timing(stat, ms, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _incr(client: Client, stat: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.incr(stat, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _decr(client: Client, stat: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.decr(stat, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _histogram(client: Client, stat: &str, value: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.histogram(stat, value, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _set(client: Client, stat: &str, value: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.set(stat, value, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _gauge(client: Client, stat: &str, value: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.gauge(stat, value, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
pub fn _event(client: Client, stat: &str, value: &str, tags: &[String], log: &slog::Logger) {
if let Err(e) = client.event(stat, value, tags.to_vec()) {
error!(log, format!("No more receivers for metrics {}", e.cause().map(|e| e.to_string()).unwrap_or("Unknown".to_owned())));
};
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_metric() {
let datadog = MetricActor::new(4, 100_000);
datadog.timing("".to_owned(), 0, vec![]);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment