datadog_api_client/datadogV1/api/
api_events.rs

1// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License.
2// This product includes software developed at Datadog (https://www.datadoghq.com/).
3// Copyright 2019-Present Datadog, Inc.
4use crate::datadog;
5use flate2::{
6    write::{GzEncoder, ZlibEncoder},
7    Compression,
8};
9use reqwest::header::{HeaderMap, HeaderValue};
10use serde::{Deserialize, Serialize};
11use std::io::Write;
12
13/// ListEventsOptionalParams is a struct for passing parameters to the method [`EventsAPI::list_events`]
14#[non_exhaustive]
15#[derive(Clone, Default, Debug)]
16pub struct ListEventsOptionalParams {
17    /// Priority of your events, either `low` or `normal`.
18    pub priority: Option<crate::datadogV1::model::EventPriority>,
19    /// A comma separated string of sources.
20    pub sources: Option<String>,
21    /// A comma separated list indicating what tags, if any, should be used to filter the list of events.
22    pub tags: Option<String>,
23    /// Set unaggregated to `true` to return all events within the specified [`start`,`end`] timeframe.
24    /// Otherwise if an event is aggregated to a parent event with a timestamp outside of the timeframe,
25    /// it won't be available in the output. Aggregated events with `is_aggregate=true` in the response will still be returned unless exclude_aggregate is set to `true.`
26    pub unaggregated: Option<bool>,
27    /// Set `exclude_aggregate` to `true` to only return unaggregated events where `is_aggregate=false` in the response. If the `exclude_aggregate` parameter is set to `true`,
28    /// then the unaggregated parameter is ignored and will be `true` by default.
29    pub exclude_aggregate: Option<bool>,
30    /// By default 1000 results are returned per request. Set page to the number of the page to return with `0` being the first page. The page parameter can only be used
31    /// when either unaggregated or exclude_aggregate is set to `true.`
32    pub page: Option<i32>,
33}
34
35impl ListEventsOptionalParams {
36    /// Priority of your events, either `low` or `normal`.
37    pub fn priority(mut self, value: crate::datadogV1::model::EventPriority) -> Self {
38        self.priority = Some(value);
39        self
40    }
41    /// A comma separated string of sources.
42    pub fn sources(mut self, value: String) -> Self {
43        self.sources = Some(value);
44        self
45    }
46    /// A comma separated list indicating what tags, if any, should be used to filter the list of events.
47    pub fn tags(mut self, value: String) -> Self {
48        self.tags = Some(value);
49        self
50    }
51    /// Set unaggregated to `true` to return all events within the specified [`start`,`end`] timeframe.
52    /// Otherwise if an event is aggregated to a parent event with a timestamp outside of the timeframe,
53    /// it won't be available in the output. Aggregated events with `is_aggregate=true` in the response will still be returned unless exclude_aggregate is set to `true.`
54    pub fn unaggregated(mut self, value: bool) -> Self {
55        self.unaggregated = Some(value);
56        self
57    }
58    /// Set `exclude_aggregate` to `true` to only return unaggregated events where `is_aggregate=false` in the response. If the `exclude_aggregate` parameter is set to `true`,
59    /// then the unaggregated parameter is ignored and will be `true` by default.
60    pub fn exclude_aggregate(mut self, value: bool) -> Self {
61        self.exclude_aggregate = Some(value);
62        self
63    }
64    /// By default 1000 results are returned per request. Set page to the number of the page to return with `0` being the first page. The page parameter can only be used
65    /// when either unaggregated or exclude_aggregate is set to `true.`
66    pub fn page(mut self, value: i32) -> Self {
67        self.page = Some(value);
68        self
69    }
70}
71
72/// CreateEventError is a struct for typed errors of method [`EventsAPI::create_event`]
73#[derive(Debug, Clone, Serialize, Deserialize)]
74#[serde(untagged)]
75pub enum CreateEventError {
76    APIErrorResponse(crate::datadogV1::model::APIErrorResponse),
77    UnknownValue(serde_json::Value),
78}
79
80/// GetEventError is a struct for typed errors of method [`EventsAPI::get_event`]
81#[derive(Debug, Clone, Serialize, Deserialize)]
82#[serde(untagged)]
83pub enum GetEventError {
84    APIErrorResponse(crate::datadogV1::model::APIErrorResponse),
85    UnknownValue(serde_json::Value),
86}
87
88/// ListEventsError is a struct for typed errors of method [`EventsAPI::list_events`]
89#[derive(Debug, Clone, Serialize, Deserialize)]
90#[serde(untagged)]
91pub enum ListEventsError {
92    APIErrorResponse(crate::datadogV1::model::APIErrorResponse),
93    UnknownValue(serde_json::Value),
94}
95
96/// The Event Management API allows you to programmatically post events to the Events Explorer and fetch events from the Events Explorer. See the [Event Management page](<https://docs.datadoghq.com/service_management/events/>) for more information.
97///
98/// **Update to Datadog monitor events `aggregation_key` starting March 1, 2025:** The Datadog monitor events `aggregation_key` is unique to each Monitor ID. Starting March 1st, this key will also include Monitor Group, making it unique per *Monitor ID and Monitor Group*. If you're using monitor events `aggregation_key` in dashboard queries or the Event API, you must migrate to use `@monitor.id`. Reach out to [support](<https://www.datadoghq.com/support/>) if you have any question.
99#[derive(Debug, Clone)]
100pub struct EventsAPI {
101    config: datadog::Configuration,
102    client: reqwest_middleware::ClientWithMiddleware,
103}
104
105impl Default for EventsAPI {
106    fn default() -> Self {
107        Self::with_config(datadog::Configuration::default())
108    }
109}
110
111impl EventsAPI {
112    pub fn new() -> Self {
113        Self::default()
114    }
115    pub fn with_config(config: datadog::Configuration) -> Self {
116        let mut reqwest_client_builder = reqwest::Client::builder();
117
118        if let Some(proxy_url) = &config.proxy_url {
119            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
120            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
121        }
122
123        let mut middleware_client_builder =
124            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
125
126        if config.enable_retry {
127            struct RetryableStatus;
128            impl reqwest_retry::RetryableStrategy for RetryableStatus {
129                fn handle(
130                    &self,
131                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
132                ) -> Option<reqwest_retry::Retryable> {
133                    match res {
134                        Ok(success) => reqwest_retry::default_on_request_success(success),
135                        Err(_) => None,
136                    }
137                }
138            }
139            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
140                .build_with_max_retries(config.max_retries);
141
142            let retry_middleware =
143                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
144                    backoff_policy,
145                    RetryableStatus,
146                );
147
148            middleware_client_builder = middleware_client_builder.with(retry_middleware);
149        }
150
151        let client = middleware_client_builder.build();
152
153        Self { config, client }
154    }
155
156    pub fn with_client_and_config(
157        config: datadog::Configuration,
158        client: reqwest_middleware::ClientWithMiddleware,
159    ) -> Self {
160        Self { config, client }
161    }
162
163    /// This endpoint allows you to post events to the stream.
164    /// Tag them, set priority and event aggregate them with other events.
165    pub async fn create_event(
166        &self,
167        body: crate::datadogV1::model::EventCreateRequest,
168    ) -> Result<crate::datadogV1::model::EventCreateResponse, datadog::Error<CreateEventError>>
169    {
170        match self.create_event_with_http_info(body).await {
171            Ok(response_content) => {
172                if let Some(e) = response_content.entity {
173                    Ok(e)
174                } else {
175                    Err(datadog::Error::Serde(serde::de::Error::custom(
176                        "response content was None",
177                    )))
178                }
179            }
180            Err(err) => Err(err),
181        }
182    }
183
184    /// This endpoint allows you to post events to the stream.
185    /// Tag them, set priority and event aggregate them with other events.
186    pub async fn create_event_with_http_info(
187        &self,
188        body: crate::datadogV1::model::EventCreateRequest,
189    ) -> Result<
190        datadog::ResponseContent<crate::datadogV1::model::EventCreateResponse>,
191        datadog::Error<CreateEventError>,
192    > {
193        let local_configuration = &self.config;
194        let operation_id = "v1.create_event";
195
196        let local_client = &self.client;
197
198        let local_uri_str = format!(
199            "{}/api/v1/events",
200            local_configuration.get_operation_host(operation_id)
201        );
202        let mut local_req_builder =
203            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
204
205        // build headers
206        let mut headers = HeaderMap::new();
207        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
208        headers.insert("Accept", HeaderValue::from_static("application/json"));
209
210        // build user agent
211        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
212            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
213            Err(e) => {
214                log::warn!("Failed to parse user agent header: {e}, falling back to default");
215                headers.insert(
216                    reqwest::header::USER_AGENT,
217                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
218                )
219            }
220        };
221
222        // build auth
223        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
224            headers.insert(
225                "DD-API-KEY",
226                HeaderValue::from_str(local_key.key.as_str())
227                    .expect("failed to parse DD-API-KEY header"),
228            );
229        };
230
231        // build body parameters
232        let output = Vec::new();
233        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
234        if body.serialize(&mut ser).is_ok() {
235            if let Some(content_encoding) = headers.get("Content-Encoding") {
236                match content_encoding.to_str().unwrap_or_default() {
237                    "gzip" => {
238                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
239                        let _ = enc.write_all(ser.into_inner().as_slice());
240                        match enc.finish() {
241                            Ok(buf) => {
242                                local_req_builder = local_req_builder.body(buf);
243                            }
244                            Err(e) => return Err(datadog::Error::Io(e)),
245                        }
246                    }
247                    "deflate" => {
248                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
249                        let _ = enc.write_all(ser.into_inner().as_slice());
250                        match enc.finish() {
251                            Ok(buf) => {
252                                local_req_builder = local_req_builder.body(buf);
253                            }
254                            Err(e) => return Err(datadog::Error::Io(e)),
255                        }
256                    }
257                    "zstd1" => {
258                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
259                        let _ = enc.write_all(ser.into_inner().as_slice());
260                        match enc.finish() {
261                            Ok(buf) => {
262                                local_req_builder = local_req_builder.body(buf);
263                            }
264                            Err(e) => return Err(datadog::Error::Io(e)),
265                        }
266                    }
267                    _ => {
268                        local_req_builder = local_req_builder.body(ser.into_inner());
269                    }
270                }
271            } else {
272                local_req_builder = local_req_builder.body(ser.into_inner());
273            }
274        }
275
276        local_req_builder = local_req_builder.headers(headers);
277        let local_req = local_req_builder.build()?;
278        log::debug!("request content: {:?}", local_req.body());
279        let local_resp = local_client.execute(local_req).await?;
280
281        let local_status = local_resp.status();
282        let local_content = local_resp.text().await?;
283        log::debug!("response content: {}", local_content);
284
285        if !local_status.is_client_error() && !local_status.is_server_error() {
286            match serde_json::from_str::<crate::datadogV1::model::EventCreateResponse>(
287                &local_content,
288            ) {
289                Ok(e) => {
290                    return Ok(datadog::ResponseContent {
291                        status: local_status,
292                        content: local_content,
293                        entity: Some(e),
294                    })
295                }
296                Err(e) => return Err(datadog::Error::Serde(e)),
297            };
298        } else {
299            let local_entity: Option<CreateEventError> = serde_json::from_str(&local_content).ok();
300            let local_error = datadog::ResponseContent {
301                status: local_status,
302                content: local_content,
303                entity: local_entity,
304            };
305            Err(datadog::Error::ResponseError(local_error))
306        }
307    }
308
309    /// This endpoint allows you to query for event details.
310    ///
311    /// **Note**: If the event you’re querying contains markdown formatting of any kind,
312    /// you may see characters such as `%`,`\`,`n` in your output.
313    pub async fn get_event(
314        &self,
315        event_id: i64,
316    ) -> Result<crate::datadogV1::model::EventResponse, datadog::Error<GetEventError>> {
317        match self.get_event_with_http_info(event_id).await {
318            Ok(response_content) => {
319                if let Some(e) = response_content.entity {
320                    Ok(e)
321                } else {
322                    Err(datadog::Error::Serde(serde::de::Error::custom(
323                        "response content was None",
324                    )))
325                }
326            }
327            Err(err) => Err(err),
328        }
329    }
330
331    /// This endpoint allows you to query for event details.
332    ///
333    /// **Note**: If the event you’re querying contains markdown formatting of any kind,
334    /// you may see characters such as `%`,`\`,`n` in your output.
335    pub async fn get_event_with_http_info(
336        &self,
337        event_id: i64,
338    ) -> Result<
339        datadog::ResponseContent<crate::datadogV1::model::EventResponse>,
340        datadog::Error<GetEventError>,
341    > {
342        let local_configuration = &self.config;
343        let operation_id = "v1.get_event";
344
345        let local_client = &self.client;
346
347        let local_uri_str = format!(
348            "{}/api/v1/events/{event_id}",
349            local_configuration.get_operation_host(operation_id),
350            event_id = event_id
351        );
352        let mut local_req_builder =
353            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
354
355        // build headers
356        let mut headers = HeaderMap::new();
357        headers.insert("Accept", HeaderValue::from_static("application/json"));
358
359        // build user agent
360        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
361            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
362            Err(e) => {
363                log::warn!("Failed to parse user agent header: {e}, falling back to default");
364                headers.insert(
365                    reqwest::header::USER_AGENT,
366                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
367                )
368            }
369        };
370
371        // build auth
372        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
373            headers.insert(
374                "DD-API-KEY",
375                HeaderValue::from_str(local_key.key.as_str())
376                    .expect("failed to parse DD-API-KEY header"),
377            );
378        };
379        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
380            headers.insert(
381                "DD-APPLICATION-KEY",
382                HeaderValue::from_str(local_key.key.as_str())
383                    .expect("failed to parse DD-APPLICATION-KEY header"),
384            );
385        };
386
387        local_req_builder = local_req_builder.headers(headers);
388        let local_req = local_req_builder.build()?;
389        log::debug!("request content: {:?}", local_req.body());
390        let local_resp = local_client.execute(local_req).await?;
391
392        let local_status = local_resp.status();
393        let local_content = local_resp.text().await?;
394        log::debug!("response content: {}", local_content);
395
396        if !local_status.is_client_error() && !local_status.is_server_error() {
397            match serde_json::from_str::<crate::datadogV1::model::EventResponse>(&local_content) {
398                Ok(e) => {
399                    return Ok(datadog::ResponseContent {
400                        status: local_status,
401                        content: local_content,
402                        entity: Some(e),
403                    })
404                }
405                Err(e) => return Err(datadog::Error::Serde(e)),
406            };
407        } else {
408            let local_entity: Option<GetEventError> = serde_json::from_str(&local_content).ok();
409            let local_error = datadog::ResponseContent {
410                status: local_status,
411                content: local_content,
412                entity: local_entity,
413            };
414            Err(datadog::Error::ResponseError(local_error))
415        }
416    }
417
418    /// The event stream can be queried and filtered by time, priority, sources and tags.
419    ///
420    /// **Notes**:
421    /// - If the event you’re querying contains markdown formatting of any kind,
422    /// you may see characters such as `%`,`\`,`n` in your output.
423    ///
424    /// - This endpoint returns a maximum of `1000` most recent results. To return additional results,
425    /// identify the last timestamp of the last result and set that as the `end` query time to
426    /// paginate the results. You can also use the page parameter to specify which set of `1000` results to return.
427    pub async fn list_events(
428        &self,
429        start: i64,
430        end: i64,
431        params: ListEventsOptionalParams,
432    ) -> Result<crate::datadogV1::model::EventListResponse, datadog::Error<ListEventsError>> {
433        match self.list_events_with_http_info(start, end, params).await {
434            Ok(response_content) => {
435                if let Some(e) = response_content.entity {
436                    Ok(e)
437                } else {
438                    Err(datadog::Error::Serde(serde::de::Error::custom(
439                        "response content was None",
440                    )))
441                }
442            }
443            Err(err) => Err(err),
444        }
445    }
446
447    /// The event stream can be queried and filtered by time, priority, sources and tags.
448    ///
449    /// **Notes**:
450    /// - If the event you’re querying contains markdown formatting of any kind,
451    /// you may see characters such as `%`,`\`,`n` in your output.
452    ///
453    /// - This endpoint returns a maximum of `1000` most recent results. To return additional results,
454    /// identify the last timestamp of the last result and set that as the `end` query time to
455    /// paginate the results. You can also use the page parameter to specify which set of `1000` results to return.
456    pub async fn list_events_with_http_info(
457        &self,
458        start: i64,
459        end: i64,
460        params: ListEventsOptionalParams,
461    ) -> Result<
462        datadog::ResponseContent<crate::datadogV1::model::EventListResponse>,
463        datadog::Error<ListEventsError>,
464    > {
465        let local_configuration = &self.config;
466        let operation_id = "v1.list_events";
467
468        // unbox and build optional parameters
469        let priority = params.priority;
470        let sources = params.sources;
471        let tags = params.tags;
472        let unaggregated = params.unaggregated;
473        let exclude_aggregate = params.exclude_aggregate;
474        let page = params.page;
475
476        let local_client = &self.client;
477
478        let local_uri_str = format!(
479            "{}/api/v1/events",
480            local_configuration.get_operation_host(operation_id)
481        );
482        let mut local_req_builder =
483            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
484
485        local_req_builder = local_req_builder.query(&[("start", &start.to_string())]);
486        local_req_builder = local_req_builder.query(&[("end", &end.to_string())]);
487        if let Some(ref local_query_param) = priority {
488            local_req_builder =
489                local_req_builder.query(&[("priority", &local_query_param.to_string())]);
490        };
491        if let Some(ref local_query_param) = sources {
492            local_req_builder =
493                local_req_builder.query(&[("sources", &local_query_param.to_string())]);
494        };
495        if let Some(ref local_query_param) = tags {
496            local_req_builder =
497                local_req_builder.query(&[("tags", &local_query_param.to_string())]);
498        };
499        if let Some(ref local_query_param) = unaggregated {
500            local_req_builder =
501                local_req_builder.query(&[("unaggregated", &local_query_param.to_string())]);
502        };
503        if let Some(ref local_query_param) = exclude_aggregate {
504            local_req_builder =
505                local_req_builder.query(&[("exclude_aggregate", &local_query_param.to_string())]);
506        };
507        if let Some(ref local_query_param) = page {
508            local_req_builder =
509                local_req_builder.query(&[("page", &local_query_param.to_string())]);
510        };
511
512        // build headers
513        let mut headers = HeaderMap::new();
514        headers.insert("Accept", HeaderValue::from_static("application/json"));
515
516        // build user agent
517        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
518            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
519            Err(e) => {
520                log::warn!("Failed to parse user agent header: {e}, falling back to default");
521                headers.insert(
522                    reqwest::header::USER_AGENT,
523                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
524                )
525            }
526        };
527
528        // build auth
529        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
530            headers.insert(
531                "DD-API-KEY",
532                HeaderValue::from_str(local_key.key.as_str())
533                    .expect("failed to parse DD-API-KEY header"),
534            );
535        };
536        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
537            headers.insert(
538                "DD-APPLICATION-KEY",
539                HeaderValue::from_str(local_key.key.as_str())
540                    .expect("failed to parse DD-APPLICATION-KEY header"),
541            );
542        };
543
544        local_req_builder = local_req_builder.headers(headers);
545        let local_req = local_req_builder.build()?;
546        log::debug!("request content: {:?}", local_req.body());
547        let local_resp = local_client.execute(local_req).await?;
548
549        let local_status = local_resp.status();
550        let local_content = local_resp.text().await?;
551        log::debug!("response content: {}", local_content);
552
553        if !local_status.is_client_error() && !local_status.is_server_error() {
554            match serde_json::from_str::<crate::datadogV1::model::EventListResponse>(&local_content)
555            {
556                Ok(e) => {
557                    return Ok(datadog::ResponseContent {
558                        status: local_status,
559                        content: local_content,
560                        entity: Some(e),
561                    })
562                }
563                Err(e) => return Err(datadog::Error::Serde(e)),
564            };
565        } else {
566            let local_entity: Option<ListEventsError> = serde_json::from_str(&local_content).ok();
567            let local_error = datadog::ResponseContent {
568                status: local_status,
569                content: local_content,
570                entity: local_entity,
571            };
572            Err(datadog::Error::ResponseError(local_error))
573        }
574    }
575}