datadog_client/
events.rs

1use crate::client::{Client, Error};
2use serde::Serialize;
3
4#[derive(Debug, Serialize)]
5#[serde(rename_all = "snake_case")]
6pub enum AlertType {
7    Error,
8    Warning,
9    Info,
10    Success,
11    UserUpdate,
12    Recommendation,
13    Snapshot,
14}
15
16#[derive(Debug, Serialize)]
17#[serde(rename_all = "snake_case")]
18pub enum Priority {
19    Normal,
20    Low,
21}
22
23/// # Examples
24///
25/// ```
26/// use datadog_client::events::{CreateEventPayload, AlertType, Priority};
27///
28/// let event = CreateEventPayload::new(
29///     "Some Title".to_string(),
30///     "Some Text in Markdown".to_string(),
31/// )
32///     .set_aggregation_key("whatever".to_string())
33///     .add_tag("environment:prod".to_string());
34/// ```
35#[derive(Debug, Serialize)]
36pub struct CreateEventPayload {
37    // An arbitrary string to use for aggregation. Limited to 100 characters. If you specify
38    // a key, all events using that key are grouped together in the Event Stream.
39    #[serde(skip_serializing_if = "Option::is_none")]
40    aggregation_key: Option<String>,
41    // If an alert event is enabled, set its type. For example, error, warning, info, success,
42    // user_update, recommendation, and snapshot.
43    #[serde(skip_serializing_if = "Option::is_none")]
44    alert_type: Option<AlertType>,
45    // POSIX timestamp of the event. Must be sent as an integer (i.e. no quotes).
46    // Limited to events no older than 7 days.
47    #[serde(skip_serializing_if = "Option::is_none")]
48    date_happened: Option<i64>,
49    // A device name
50    #[serde(skip_serializing_if = "Option::is_none")]
51    device_name: Option<String>,
52    // Host name to associate with the event. Any tags associated with the host are also applied to this event.
53    #[serde(skip_serializing_if = "Option::is_none")]
54    host: Option<String>,
55    // The priority of the event. For example, normal or low.
56    #[serde(skip_serializing_if = "Option::is_none")]
57    priority: Option<Priority>,
58    // ID of the parent event. Must be sent as an integer (i.e. no quotes).
59    #[serde(skip_serializing_if = "Option::is_none")]
60    related_event_id: Option<i64>,
61    // The type of event being posted.
62    // Option examples include nagios, hudson, jenkins, my_apps, chef, puppet, git, bitbucket, etc.
63    #[serde(skip_serializing_if = "Option::is_none")]
64    source_type_name: Option<String>,
65    // A list of tags to apply to the event.
66    #[serde(skip_serializing_if = "Vec::is_empty")]
67    tags: Vec<String>,
68    // The body of the event. Limited to 4000 characters. The text supports markdown.
69    // To use markdown in the event text, start the text block with %%% \n and end the text block with \n %%%.
70    // Use msg_text with the Datadog Ruby library.
71    text: String,
72    // The event title. Limited to 100 characters.
73    title: String,
74}
75
76impl CreateEventPayload {
77    pub fn new(title: String, text: String) -> Self {
78        Self {
79            aggregation_key: None,
80            alert_type: None,
81            date_happened: None,
82            device_name: None,
83            host: None,
84            priority: None,
85            related_event_id: None,
86            source_type_name: None,
87            tags: Vec::new(),
88            title,
89            text,
90        }
91    }
92
93    pub fn set_aggregation_key(mut self, value: String) -> Self {
94        self.aggregation_key = Some(value);
95        self
96    }
97
98    pub fn set_alert_type(mut self, value: AlertType) -> Self {
99        self.alert_type = Some(value);
100        self
101    }
102
103    pub fn set_date_happened(mut self, value: i64) -> Self {
104        self.date_happened = Some(value);
105        self
106    }
107
108    pub fn set_device_name(mut self, value: String) -> Self {
109        self.device_name = Some(value);
110        self
111    }
112
113    pub fn set_host(mut self, value: String) -> Self {
114        self.host = Some(value);
115        self
116    }
117
118    pub fn set_priority(mut self, value: Priority) -> Self {
119        self.priority = Some(value);
120        self
121    }
122
123    pub fn set_related_event_id(mut self, value: i64) -> Self {
124        self.related_event_id = Some(value);
125        self
126    }
127
128    pub fn set_source_type_name(mut self, value: String) -> Self {
129        self.source_type_name = Some(value);
130        self
131    }
132
133    pub fn add_tag(mut self, value: String) -> Self {
134        self.tags.push(value);
135        self
136    }
137
138    pub fn set_tags(mut self, tags: Vec<String>) -> Self {
139        self.tags = tags;
140        self
141    }
142}
143
144impl Client {
145    /// Post an event
146    ///
147    /// This endpoint allows you to post events to the stream.
148    /// Tag them, set priority and event aggregate them with other events.
149    ///
150    /// https://docs.datadoghq.com/api/latest/events/#post-an-event
151    ///
152    pub async fn post_event(&self, event: &CreateEventPayload) -> Result<(), Error> {
153        self.post("/api/v1/events", event).await
154    }
155}
156
157#[cfg(test)]
158mod tests {
159    use super::*;
160    use mockito::mock;
161
162    #[tokio::test]
163    async fn post_metrics_success() {
164        let call = mock("POST", "/api/v1/events").with_status(202).create();
165        let client = Client::new(mockito::server_url(), String::from("fake-api-key"));
166        let event = CreateEventPayload::new(
167            String::from("Some Event Title"),
168            String::from("Some event text"),
169        )
170        .add_tag(String::from("testing"));
171        let result = client.post_event(&event).await;
172        assert!(result.is_ok());
173        call.expect(1);
174    }
175
176    #[tokio::test]
177    async fn post_metrics_unauthorized() {
178        let call = mock("POST", "/api/v1/series")
179            .with_status(403)
180            .with_body("{\"errors\":[\"Authentication error\"]}")
181            .create();
182        let client = Client::new(mockito::server_url(), String::from("fake-api-key"));
183        let event = CreateEventPayload::new(
184            String::from("Some Event Title"),
185            String::from("Some event text"),
186        )
187        .add_tag(String::from("testing"));
188        let result = client.post_event(&event).await;
189        assert!(result.is_err());
190        call.expect(1);
191    }
192}