Skip to content

Commit

Permalink
add actuall support for new macro
Browse files Browse the repository at this point in the history
  • Loading branch information
cpiemontese committed Nov 25, 2024
1 parent f979e1f commit 55d83d4
Show file tree
Hide file tree
Showing 10 changed files with 191 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .mise.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[tools]
rust = "1.74"
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM rust:1.72.0
FROM rust:1.74.0

WORKDIR /code

Expand Down
13 changes: 13 additions & 0 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::future::Future;

use async_trait::async_trait;
use dogstatsd::EventOptions;

use crate::{ServiceCheckOptions, ServiceStatus, TagsProvider};

Expand Down Expand Up @@ -75,6 +76,11 @@ pub trait DogstatsdClient {
fn event<S>(&self, title: &str, text: &str, tags: impl TagsProvider<S>)
where
S: AsRef<str>;

/// Send a custom event as a title and a body
fn event_with_options<S>(&self, title: &str, text: &str, tags: impl TagsProvider<S>, options: Option<EventOptions>)
where
S: AsRef<str>;
}

#[async_trait]
Expand Down Expand Up @@ -172,4 +178,11 @@ impl DogstatsdClient for dogstatsd::Client {
{
let _ = self.event(title, text, tags.as_ref());
}

fn event_with_options<S>(&self, title: &str, text: &str, tags: impl TagsProvider<S>, options: Option<EventOptions>)
where
S: AsRef<str>,
{
let _ = self.event_with_options(title, text, tags.as_ref(), options);
}
}
28 changes: 28 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@
use std::future::Future;

use configuration::Configuration;
use dogstatsd::EventOptions;
pub use dogstatsd::{ServiceCheckOptions, ServiceStatus};
use once_cell::sync::OnceCell;

Expand Down Expand Up @@ -295,6 +296,18 @@ impl Datadog<dogstatsd::Client> {
}
}

/// Send a custom event as a title, a body and some options
pub fn event_with_options<S: AsRef<str>>(
metric: impl AsRef<str>,
text: impl AsRef<str>,
tags: impl TagsProvider<S>,
options: Option<EventOptions>,
) {
if let Some(instance) = INSTANCE.get() {
instance.do_event_with_options(metric.as_ref(), text.as_ref(), tags, options);
}
}

/// Acquire a timing guard.
/// When this guard is dropped, it will emit a timing metric for the duration it
/// existed. The metric name is metric, and the tags are tags.
Expand Down Expand Up @@ -455,4 +468,19 @@ impl<C: DogstatsdClient> Datadog<C> {
self.tag_tracker.track(&self.inner, metric.as_ref(), tags),
);
}

pub(crate) fn do_event_with_options<S: AsRef<str>>(
&self,
metric: impl AsRef<str>,
text: impl AsRef<str>,
tags: impl TagsProvider<S>,
options: Option<EventOptions>,
) {
self.inner.event_with_options(
metric.as_ref(),
text.as_ref(),
self.tag_tracker.track(&self.inner, metric.as_ref(), tags),
options,
);
}
}
23 changes: 23 additions & 0 deletions src/macros/event_with_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/// Send a custom event as a title and a body
/// NOTE: Try to minimise variation in tag values (avoid things like timestamps or ids). See note in lib docs!
#[macro_export]
macro_rules! event_with_options {
($stat:path, $text:expr) => {
$crate::Datadog::event_with_options($stat.as_ref(), $text, $crate::EMPTY_TAGS, None);
};
($stat:expr, $text:expr) => {
$crate::Datadog::event_with_options($stat, $text, $crate::EMPTY_TAGS, None);
};
($stat:expr, $text:expr; $( $key:literal => $value:literal ), *) => {
$crate::Datadog::event_with_options($stat, $text, &[$(::core::concat!($key, ":", $value)), *], None);
};
($stat:path, $text:expr; $( $key:literal => $value:literal ), *) => {
$crate::Datadog::event_with_options($stat.as_ref(), $text, &[$(::core::concat!($key, ":", $value)), *], None);
};
($stat:expr, $text:expr; $( $key:expr => $value:expr ), *) => {
$crate::Datadog::event_with_options($stat, $text, &[$(::std::format!("{}:{}", $key, $value).as_str()), *], None);
};
($stat:path, $text:expr; $( $key:expr => $value:expr ), *) => {
$crate::Datadog::event_with_options($stat.as_ref(), $text, &[$(::std::format!("{}:{}", $key, $value).as_str()), *], None);
};
}
1 change: 1 addition & 0 deletions src/macros/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod count;
mod decr;
mod distribution;
mod event;
mod event_with_options;
mod gauge;
mod histogram;
mod incr;
Expand Down
83 changes: 83 additions & 0 deletions src/tests/event_with_options.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
use dogstatsd::EventAlertType;
use dogstatsd::EventOptions;
use dogstatsd::EventPriority;

use crate::event_with_options;
use crate::tests::mocks;
use crate::tests::TestEvent;
use crate::Datadog;
use crate::TagTrackerConfiguration;
use crate::EMPTY_TAGS;

#[test]
pub fn event_with_options_with_literal() {
let mock = mocks::event_with_options_mock("test", "test_value", &[], None);
Datadog::new(mock, TagTrackerConfiguration::new()).do_event_with_options("test", "test_value", EMPTY_TAGS, None);
}

#[test]
pub fn event_with_options_with_type() {
let mock = mocks::event_with_options_mock("test1_event", "test_value", &[], None);
Datadog::new(mock, TagTrackerConfiguration::new()).do_event_with_options(
TestEvent::Test1,
"test_value",
EMPTY_TAGS,
None,
);
}

#[test]
pub fn event_with_options_with_literal_and_tags() {
let mock = mocks::event_with_options_mock("test", "test_value", &["added:tag", "env:test"], None);
Datadog::new(mock, TagTrackerConfiguration::new()).do_event_with_options(
"test",
"test_value",
vec!["added:tag".to_string()],
None,
);
}

#[test]
pub fn event_with_options_with_type_and_tags() {
let mock = mocks::event_with_options_mock("test1_event", "test_value", &["added:tag", "env:test"], None);
Datadog::new(mock, TagTrackerConfiguration::new()).do_event_with_options(
TestEvent::Test1,
"test_value",
vec!["added:tag".to_string()],
None,
);
}

#[test]
pub fn event_with_options_with_options() {
let options = Some(
EventOptions::new()
.with_alert_type(EventAlertType::Info)
.with_priority(EventPriority::Low)
.with_aggregation_key("aggregation_key")
.with_source_type_name("source_type_name")
.with_hostname("hostname")
.with_timestamp(12341234),
);

let mock = mocks::event_with_options_mock("test1_event", "test_value", &["added:tag", "env:test"], options);
Datadog::new(mock, TagTrackerConfiguration::new()).do_event_with_options(
TestEvent::Test1,
"test_value",
vec!["added:tag".to_string()],
options,
);
}

#[test]
pub fn test_macro() {
let tag = String::from("tag");
// no tags
event_with_options!("test", "test_value");
// just literal tags
event_with_options!("test", "test_value"; "literal" => 1);
// just expression tags
event_with_options!("test", "test_value"; "expression" => tag);
// mixed tags
event_with_options!("test", "test_value"; "literal" => 1, "expression" => tag);
}
14 changes: 14 additions & 0 deletions src/tests/mocks/dogstatsd_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ pub(super) trait MockDogstatsdClient {
fn set(&self, metric: &str, val: &str, tags: Vec<String>);
fn service_check(&self, metric: &str, val: ServiceStatus, tags: Vec<String>, options: Option<ServiceCheckOptions>);
fn event(&self, title: &str, text: &str, tags: Vec<String>);
fn event_with_options(&self, title: &str, text: &str, tags: Vec<String>, options: Option<EventOptions>);
}

#[async_trait]
Expand Down Expand Up @@ -143,4 +144,17 @@ impl<C: MockDogstatsdClient + Sync> DogstatsdClient for C {
tags.as_ref().iter().map(|s| s.as_ref().to_string()).collect(),
)
}

fn event_with_options<S>(&self, title: &str, text: &str, tags: impl TagsProvider<S>, options: Option<EventOptions>)
where
S: AsRef<str>,
{
MockDogstatsdClient::event_with_options(
self,
title,
text,
tags.as_ref().iter().map(|s| s.as_ref().to_string()).collect(),
options,
)
}
}
25 changes: 25 additions & 0 deletions src/tests/mocks/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ mock! {

/// Send a custom event as a title and a body
fn event(&self, title: &str, text: &str, tags: Vec<String>);

/// Send a custom event as a title, a body and some options
fn event_with_options<'a>(&self, title: &str, text: &str, tags: Vec<String>, options: Option<EventOptions<'a>>);
}
}

Expand Down Expand Up @@ -236,6 +239,28 @@ pub fn event_mock(metric: &'static str, text: &'static str, tags: &'static [&str
client_mock
}

#[allow(dead_code)]
pub fn event_with_options_mock(
metric: &'static str,
text: &'static str,
tags: &'static [&str],
options: Option<EventOptions<'static>>,
) -> MockClient {
let mut client_mock = MockClient::new();
client_mock
.expect_event_with_options()
.once()
.withf(move |called_metric, called_text, called_tags, called_options| {
called_metric == metric
&& called_text == text
&& called_tags.iter().all(|tag| tags.contains(&tag.as_str()))
&& matches!((called_options, options), (Some(_), Some(_)) | (None, None))
})
.return_const(());

client_mock
}

pub fn expect_incr(mut mock: MockClient, metric: &'static str, tags: impl IntoIterator<Item = String>) -> MockClient {
let tags = tags.into_iter().collect::<Vec<_>>();
mock.expect_incr()
Expand Down
1 change: 1 addition & 0 deletions src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ mod count;
mod decr;
mod distribution;
mod event;
mod event_with_options;
mod gauge;
mod histogram;
mod incr;
Expand Down

0 comments on commit 55d83d4

Please sign in to comment.