datadog_api_client/datadogV2/api/
api_logs.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 async_stream::try_stream;
6use flate2::{
7    write::{GzEncoder, ZlibEncoder},
8    Compression,
9};
10use futures_core::stream::Stream;
11use reqwest::header::{HeaderMap, HeaderValue};
12use serde::{Deserialize, Serialize};
13use std::io::Write;
14
15/// ListLogsOptionalParams is a struct for passing parameters to the method [`LogsAPI::list_logs`]
16#[non_exhaustive]
17#[derive(Clone, Default, Debug)]
18pub struct ListLogsOptionalParams {
19    pub body: Option<crate::datadogV2::model::LogsListRequest>,
20}
21
22impl ListLogsOptionalParams {
23    pub fn body(mut self, value: crate::datadogV2::model::LogsListRequest) -> Self {
24        self.body = Some(value);
25        self
26    }
27}
28
29/// ListLogsGetOptionalParams is a struct for passing parameters to the method [`LogsAPI::list_logs_get`]
30#[non_exhaustive]
31#[derive(Clone, Default, Debug)]
32pub struct ListLogsGetOptionalParams {
33    /// Search query following logs syntax.
34    pub filter_query: Option<String>,
35    /// For customers with multiple indexes, the indexes to search.
36    /// Defaults to '*' which means all indexes
37    pub filter_indexes: Option<Vec<String>>,
38    /// Minimum timestamp for requested logs.
39    pub filter_from: Option<chrono::DateTime<chrono::Utc>>,
40    /// Maximum timestamp for requested logs.
41    pub filter_to: Option<chrono::DateTime<chrono::Utc>>,
42    /// Specifies the storage type to be used
43    pub filter_storage_tier: Option<crate::datadogV2::model::LogsStorageTier>,
44    /// Order of logs in results.
45    pub sort: Option<crate::datadogV2::model::LogsSort>,
46    /// List following results with a cursor provided in the previous query.
47    pub page_cursor: Option<String>,
48    /// Maximum number of logs in the response.
49    pub page_limit: Option<i32>,
50}
51
52impl ListLogsGetOptionalParams {
53    /// Search query following logs syntax.
54    pub fn filter_query(mut self, value: String) -> Self {
55        self.filter_query = Some(value);
56        self
57    }
58    /// For customers with multiple indexes, the indexes to search.
59    /// Defaults to '*' which means all indexes
60    pub fn filter_indexes(mut self, value: Vec<String>) -> Self {
61        self.filter_indexes = Some(value);
62        self
63    }
64    /// Minimum timestamp for requested logs.
65    pub fn filter_from(mut self, value: chrono::DateTime<chrono::Utc>) -> Self {
66        self.filter_from = Some(value);
67        self
68    }
69    /// Maximum timestamp for requested logs.
70    pub fn filter_to(mut self, value: chrono::DateTime<chrono::Utc>) -> Self {
71        self.filter_to = Some(value);
72        self
73    }
74    /// Specifies the storage type to be used
75    pub fn filter_storage_tier(mut self, value: crate::datadogV2::model::LogsStorageTier) -> Self {
76        self.filter_storage_tier = Some(value);
77        self
78    }
79    /// Order of logs in results.
80    pub fn sort(mut self, value: crate::datadogV2::model::LogsSort) -> Self {
81        self.sort = Some(value);
82        self
83    }
84    /// List following results with a cursor provided in the previous query.
85    pub fn page_cursor(mut self, value: String) -> Self {
86        self.page_cursor = Some(value);
87        self
88    }
89    /// Maximum number of logs in the response.
90    pub fn page_limit(mut self, value: i32) -> Self {
91        self.page_limit = Some(value);
92        self
93    }
94}
95
96/// SubmitLogOptionalParams is a struct for passing parameters to the method [`LogsAPI::submit_log`]
97#[non_exhaustive]
98#[derive(Clone, Default, Debug)]
99pub struct SubmitLogOptionalParams {
100    /// HTTP header used to compress the media-type.
101    pub content_encoding: Option<crate::datadogV2::model::ContentEncoding>,
102    /// Log tags can be passed as query parameters with `text/plain` content type.
103    pub ddtags: Option<String>,
104}
105
106impl SubmitLogOptionalParams {
107    /// HTTP header used to compress the media-type.
108    pub fn content_encoding(mut self, value: crate::datadogV2::model::ContentEncoding) -> Self {
109        self.content_encoding = Some(value);
110        self
111    }
112    /// Log tags can be passed as query parameters with `text/plain` content type.
113    pub fn ddtags(mut self, value: String) -> Self {
114        self.ddtags = Some(value);
115        self
116    }
117}
118
119/// AggregateLogsError is a struct for typed errors of method [`LogsAPI::aggregate_logs`]
120#[derive(Debug, Clone, Serialize, Deserialize)]
121#[serde(untagged)]
122pub enum AggregateLogsError {
123    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
124    UnknownValue(serde_json::Value),
125}
126
127/// ListLogsError is a struct for typed errors of method [`LogsAPI::list_logs`]
128#[derive(Debug, Clone, Serialize, Deserialize)]
129#[serde(untagged)]
130pub enum ListLogsError {
131    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
132    UnknownValue(serde_json::Value),
133}
134
135/// ListLogsGetError is a struct for typed errors of method [`LogsAPI::list_logs_get`]
136#[derive(Debug, Clone, Serialize, Deserialize)]
137#[serde(untagged)]
138pub enum ListLogsGetError {
139    APIErrorResponse(crate::datadogV2::model::APIErrorResponse),
140    UnknownValue(serde_json::Value),
141}
142
143/// SubmitLogError is a struct for typed errors of method [`LogsAPI::submit_log`]
144#[derive(Debug, Clone, Serialize, Deserialize)]
145#[serde(untagged)]
146pub enum SubmitLogError {
147    HTTPLogErrors(crate::datadogV2::model::HTTPLogErrors),
148    UnknownValue(serde_json::Value),
149}
150
151/// Search your logs and send them to your Datadog platform over HTTP. See the [Log Management page](<https://docs.datadoghq.com/logs/>) for more information.
152#[derive(Debug, Clone)]
153pub struct LogsAPI {
154    config: datadog::Configuration,
155    client: reqwest_middleware::ClientWithMiddleware,
156}
157
158impl Default for LogsAPI {
159    fn default() -> Self {
160        Self::with_config(datadog::Configuration::default())
161    }
162}
163
164impl LogsAPI {
165    pub fn new() -> Self {
166        Self::default()
167    }
168    pub fn with_config(config: datadog::Configuration) -> Self {
169        let mut reqwest_client_builder = reqwest::Client::builder();
170
171        if let Some(proxy_url) = &config.proxy_url {
172            let proxy = reqwest::Proxy::all(proxy_url).expect("Failed to parse proxy URL");
173            reqwest_client_builder = reqwest_client_builder.proxy(proxy);
174        }
175
176        let mut middleware_client_builder =
177            reqwest_middleware::ClientBuilder::new(reqwest_client_builder.build().unwrap());
178
179        if config.enable_retry {
180            struct RetryableStatus;
181            impl reqwest_retry::RetryableStrategy for RetryableStatus {
182                fn handle(
183                    &self,
184                    res: &Result<reqwest::Response, reqwest_middleware::Error>,
185                ) -> Option<reqwest_retry::Retryable> {
186                    match res {
187                        Ok(success) => reqwest_retry::default_on_request_success(success),
188                        Err(_) => None,
189                    }
190                }
191            }
192            let backoff_policy = reqwest_retry::policies::ExponentialBackoff::builder()
193                .build_with_max_retries(config.max_retries);
194
195            let retry_middleware =
196                reqwest_retry::RetryTransientMiddleware::new_with_policy_and_strategy(
197                    backoff_policy,
198                    RetryableStatus,
199                );
200
201            middleware_client_builder = middleware_client_builder.with(retry_middleware);
202        }
203
204        let client = middleware_client_builder.build();
205
206        Self { config, client }
207    }
208
209    pub fn with_client_and_config(
210        config: datadog::Configuration,
211        client: reqwest_middleware::ClientWithMiddleware,
212    ) -> Self {
213        Self { config, client }
214    }
215
216    /// The API endpoint to aggregate events into buckets and compute metrics and timeseries.
217    pub async fn aggregate_logs(
218        &self,
219        body: crate::datadogV2::model::LogsAggregateRequest,
220    ) -> Result<crate::datadogV2::model::LogsAggregateResponse, datadog::Error<AggregateLogsError>>
221    {
222        match self.aggregate_logs_with_http_info(body).await {
223            Ok(response_content) => {
224                if let Some(e) = response_content.entity {
225                    Ok(e)
226                } else {
227                    Err(datadog::Error::Serde(serde::de::Error::custom(
228                        "response content was None",
229                    )))
230                }
231            }
232            Err(err) => Err(err),
233        }
234    }
235
236    /// The API endpoint to aggregate events into buckets and compute metrics and timeseries.
237    pub async fn aggregate_logs_with_http_info(
238        &self,
239        body: crate::datadogV2::model::LogsAggregateRequest,
240    ) -> Result<
241        datadog::ResponseContent<crate::datadogV2::model::LogsAggregateResponse>,
242        datadog::Error<AggregateLogsError>,
243    > {
244        let local_configuration = &self.config;
245        let operation_id = "v2.aggregate_logs";
246
247        let local_client = &self.client;
248
249        let local_uri_str = format!(
250            "{}/api/v2/logs/analytics/aggregate",
251            local_configuration.get_operation_host(operation_id)
252        );
253        let mut local_req_builder =
254            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
255
256        // build headers
257        let mut headers = HeaderMap::new();
258        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
259        headers.insert("Accept", HeaderValue::from_static("application/json"));
260
261        // build user agent
262        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
263            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
264            Err(e) => {
265                log::warn!("Failed to parse user agent header: {e}, falling back to default");
266                headers.insert(
267                    reqwest::header::USER_AGENT,
268                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
269                )
270            }
271        };
272
273        // build auth
274        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
275            headers.insert(
276                "DD-API-KEY",
277                HeaderValue::from_str(local_key.key.as_str())
278                    .expect("failed to parse DD-API-KEY header"),
279            );
280        };
281        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
282            headers.insert(
283                "DD-APPLICATION-KEY",
284                HeaderValue::from_str(local_key.key.as_str())
285                    .expect("failed to parse DD-APPLICATION-KEY header"),
286            );
287        };
288
289        // build body parameters
290        let output = Vec::new();
291        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
292        if body.serialize(&mut ser).is_ok() {
293            if let Some(content_encoding) = headers.get("Content-Encoding") {
294                match content_encoding.to_str().unwrap_or_default() {
295                    "gzip" => {
296                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
297                        let _ = enc.write_all(ser.into_inner().as_slice());
298                        match enc.finish() {
299                            Ok(buf) => {
300                                local_req_builder = local_req_builder.body(buf);
301                            }
302                            Err(e) => return Err(datadog::Error::Io(e)),
303                        }
304                    }
305                    "deflate" => {
306                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
307                        let _ = enc.write_all(ser.into_inner().as_slice());
308                        match enc.finish() {
309                            Ok(buf) => {
310                                local_req_builder = local_req_builder.body(buf);
311                            }
312                            Err(e) => return Err(datadog::Error::Io(e)),
313                        }
314                    }
315                    "zstd1" => {
316                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
317                        let _ = enc.write_all(ser.into_inner().as_slice());
318                        match enc.finish() {
319                            Ok(buf) => {
320                                local_req_builder = local_req_builder.body(buf);
321                            }
322                            Err(e) => return Err(datadog::Error::Io(e)),
323                        }
324                    }
325                    _ => {
326                        local_req_builder = local_req_builder.body(ser.into_inner());
327                    }
328                }
329            } else {
330                local_req_builder = local_req_builder.body(ser.into_inner());
331            }
332        }
333
334        local_req_builder = local_req_builder.headers(headers);
335        let local_req = local_req_builder.build()?;
336        log::debug!("request content: {:?}", local_req.body());
337        let local_resp = local_client.execute(local_req).await?;
338
339        let local_status = local_resp.status();
340        let local_content = local_resp.text().await?;
341        log::debug!("response content: {}", local_content);
342
343        if !local_status.is_client_error() && !local_status.is_server_error() {
344            match serde_json::from_str::<crate::datadogV2::model::LogsAggregateResponse>(
345                &local_content,
346            ) {
347                Ok(e) => {
348                    return Ok(datadog::ResponseContent {
349                        status: local_status,
350                        content: local_content,
351                        entity: Some(e),
352                    })
353                }
354                Err(e) => return Err(datadog::Error::Serde(e)),
355            };
356        } else {
357            let local_entity: Option<AggregateLogsError> =
358                serde_json::from_str(&local_content).ok();
359            let local_error = datadog::ResponseContent {
360                status: local_status,
361                content: local_content,
362                entity: local_entity,
363            };
364            Err(datadog::Error::ResponseError(local_error))
365        }
366    }
367
368    /// List endpoint returns logs that match a log search query.
369    /// [Results are paginated][1].
370    ///
371    /// Use this endpoint to search and filter your logs.
372    ///
373    /// **If you are considering archiving logs for your organization,
374    /// consider use of the Datadog archive capabilities instead of the log list API.
375    /// See [Datadog Logs Archive documentation][2].**
376    ///
377    /// [1]: /logs/guide/collect-multiple-logs-with-pagination
378    /// [2]: <https://docs.datadoghq.com/logs/archives>
379    pub async fn list_logs(
380        &self,
381        params: ListLogsOptionalParams,
382    ) -> Result<crate::datadogV2::model::LogsListResponse, datadog::Error<ListLogsError>> {
383        match self.list_logs_with_http_info(params).await {
384            Ok(response_content) => {
385                if let Some(e) = response_content.entity {
386                    Ok(e)
387                } else {
388                    Err(datadog::Error::Serde(serde::de::Error::custom(
389                        "response content was None",
390                    )))
391                }
392            }
393            Err(err) => Err(err),
394        }
395    }
396
397    pub fn list_logs_with_pagination(
398        &self,
399        mut params: ListLogsOptionalParams,
400    ) -> impl Stream<Item = Result<crate::datadogV2::model::Log, datadog::Error<ListLogsError>>> + '_
401    {
402        try_stream! {
403            let mut page_size: i32 = 10;
404            if params.body.is_none() {
405                params.body = Some(crate::datadogV2::model::LogsListRequest::new());
406            }
407            if params.body.as_ref().unwrap().page.is_none() {
408                params.body.as_mut().unwrap().page = Some(crate::datadogV2::model::LogsListRequestPage::new());
409            }
410            if params.body.as_ref().unwrap().page.as_ref().unwrap().limit.is_none() {
411                params.body.as_mut().unwrap().page.as_mut().unwrap().limit = Some(page_size);
412            } else {
413                page_size = params.body.as_ref().unwrap().page.as_ref().unwrap().limit.unwrap().clone();
414            }
415            loop {
416                let resp = self.list_logs(params.clone()).await?;
417                let Some(data) = resp.data else { break };
418
419                let r = data;
420                let count = r.len();
421                for team in r {
422                    yield team;
423                }
424
425                if count < page_size as usize {
426                    break;
427                }
428                let Some(meta) = resp.meta else { break };
429                let Some(page) = meta.page else { break };
430                let Some(after) = page.after else { break };
431
432                params.body.as_mut().unwrap().page.as_mut().unwrap().cursor = Some(after);
433            }
434        }
435    }
436
437    /// List endpoint returns logs that match a log search query.
438    /// [Results are paginated][1].
439    ///
440    /// Use this endpoint to search and filter your logs.
441    ///
442    /// **If you are considering archiving logs for your organization,
443    /// consider use of the Datadog archive capabilities instead of the log list API.
444    /// See [Datadog Logs Archive documentation][2].**
445    ///
446    /// [1]: /logs/guide/collect-multiple-logs-with-pagination
447    /// [2]: <https://docs.datadoghq.com/logs/archives>
448    pub async fn list_logs_with_http_info(
449        &self,
450        params: ListLogsOptionalParams,
451    ) -> Result<
452        datadog::ResponseContent<crate::datadogV2::model::LogsListResponse>,
453        datadog::Error<ListLogsError>,
454    > {
455        let local_configuration = &self.config;
456        let operation_id = "v2.list_logs";
457
458        // unbox and build optional parameters
459        let body = params.body;
460
461        let local_client = &self.client;
462
463        let local_uri_str = format!(
464            "{}/api/v2/logs/events/search",
465            local_configuration.get_operation_host(operation_id)
466        );
467        let mut local_req_builder =
468            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
469
470        // build headers
471        let mut headers = HeaderMap::new();
472        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
473        headers.insert("Accept", HeaderValue::from_static("application/json"));
474
475        // build user agent
476        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
477            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
478            Err(e) => {
479                log::warn!("Failed to parse user agent header: {e}, falling back to default");
480                headers.insert(
481                    reqwest::header::USER_AGENT,
482                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
483                )
484            }
485        };
486
487        // build auth
488        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
489            headers.insert(
490                "DD-API-KEY",
491                HeaderValue::from_str(local_key.key.as_str())
492                    .expect("failed to parse DD-API-KEY header"),
493            );
494        };
495        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
496            headers.insert(
497                "DD-APPLICATION-KEY",
498                HeaderValue::from_str(local_key.key.as_str())
499                    .expect("failed to parse DD-APPLICATION-KEY header"),
500            );
501        };
502
503        // build body parameters
504        let output = Vec::new();
505        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
506        if body.serialize(&mut ser).is_ok() {
507            if let Some(content_encoding) = headers.get("Content-Encoding") {
508                match content_encoding.to_str().unwrap_or_default() {
509                    "gzip" => {
510                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
511                        let _ = enc.write_all(ser.into_inner().as_slice());
512                        match enc.finish() {
513                            Ok(buf) => {
514                                local_req_builder = local_req_builder.body(buf);
515                            }
516                            Err(e) => return Err(datadog::Error::Io(e)),
517                        }
518                    }
519                    "deflate" => {
520                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
521                        let _ = enc.write_all(ser.into_inner().as_slice());
522                        match enc.finish() {
523                            Ok(buf) => {
524                                local_req_builder = local_req_builder.body(buf);
525                            }
526                            Err(e) => return Err(datadog::Error::Io(e)),
527                        }
528                    }
529                    "zstd1" => {
530                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
531                        let _ = enc.write_all(ser.into_inner().as_slice());
532                        match enc.finish() {
533                            Ok(buf) => {
534                                local_req_builder = local_req_builder.body(buf);
535                            }
536                            Err(e) => return Err(datadog::Error::Io(e)),
537                        }
538                    }
539                    _ => {
540                        local_req_builder = local_req_builder.body(ser.into_inner());
541                    }
542                }
543            } else {
544                local_req_builder = local_req_builder.body(ser.into_inner());
545            }
546        }
547
548        local_req_builder = local_req_builder.headers(headers);
549        let local_req = local_req_builder.build()?;
550        log::debug!("request content: {:?}", local_req.body());
551        let local_resp = local_client.execute(local_req).await?;
552
553        let local_status = local_resp.status();
554        let local_content = local_resp.text().await?;
555        log::debug!("response content: {}", local_content);
556
557        if !local_status.is_client_error() && !local_status.is_server_error() {
558            match serde_json::from_str::<crate::datadogV2::model::LogsListResponse>(&local_content)
559            {
560                Ok(e) => {
561                    return Ok(datadog::ResponseContent {
562                        status: local_status,
563                        content: local_content,
564                        entity: Some(e),
565                    })
566                }
567                Err(e) => return Err(datadog::Error::Serde(e)),
568            };
569        } else {
570            let local_entity: Option<ListLogsError> = serde_json::from_str(&local_content).ok();
571            let local_error = datadog::ResponseContent {
572                status: local_status,
573                content: local_content,
574                entity: local_entity,
575            };
576            Err(datadog::Error::ResponseError(local_error))
577        }
578    }
579
580    /// List endpoint returns logs that match a log search query.
581    /// [Results are paginated][1].
582    ///
583    /// Use this endpoint to search and filter your logs.
584    ///
585    /// **If you are considering archiving logs for your organization,
586    /// consider use of the Datadog archive capabilities instead of the log list API.
587    /// See [Datadog Logs Archive documentation][2].**
588    ///
589    /// [1]: /logs/guide/collect-multiple-logs-with-pagination
590    /// [2]: <https://docs.datadoghq.com/logs/archives>
591    pub async fn list_logs_get(
592        &self,
593        params: ListLogsGetOptionalParams,
594    ) -> Result<crate::datadogV2::model::LogsListResponse, datadog::Error<ListLogsGetError>> {
595        match self.list_logs_get_with_http_info(params).await {
596            Ok(response_content) => {
597                if let Some(e) = response_content.entity {
598                    Ok(e)
599                } else {
600                    Err(datadog::Error::Serde(serde::de::Error::custom(
601                        "response content was None",
602                    )))
603                }
604            }
605            Err(err) => Err(err),
606        }
607    }
608
609    pub fn list_logs_get_with_pagination(
610        &self,
611        mut params: ListLogsGetOptionalParams,
612    ) -> impl Stream<Item = Result<crate::datadogV2::model::Log, datadog::Error<ListLogsGetError>>> + '_
613    {
614        try_stream! {
615            let mut page_size: i32 = 10;
616            if params.page_limit.is_none() {
617                params.page_limit = Some(page_size);
618            } else {
619                page_size = params.page_limit.unwrap().clone();
620            }
621            loop {
622                let resp = self.list_logs_get(params.clone()).await?;
623                let Some(data) = resp.data else { break };
624
625                let r = data;
626                let count = r.len();
627                for team in r {
628                    yield team;
629                }
630
631                if count < page_size as usize {
632                    break;
633                }
634                let Some(meta) = resp.meta else { break };
635                let Some(page) = meta.page else { break };
636                let Some(after) = page.after else { break };
637
638                params.page_cursor = Some(after);
639            }
640        }
641    }
642
643    /// List endpoint returns logs that match a log search query.
644    /// [Results are paginated][1].
645    ///
646    /// Use this endpoint to search and filter your logs.
647    ///
648    /// **If you are considering archiving logs for your organization,
649    /// consider use of the Datadog archive capabilities instead of the log list API.
650    /// See [Datadog Logs Archive documentation][2].**
651    ///
652    /// [1]: /logs/guide/collect-multiple-logs-with-pagination
653    /// [2]: <https://docs.datadoghq.com/logs/archives>
654    pub async fn list_logs_get_with_http_info(
655        &self,
656        params: ListLogsGetOptionalParams,
657    ) -> Result<
658        datadog::ResponseContent<crate::datadogV2::model::LogsListResponse>,
659        datadog::Error<ListLogsGetError>,
660    > {
661        let local_configuration = &self.config;
662        let operation_id = "v2.list_logs_get";
663
664        // unbox and build optional parameters
665        let filter_query = params.filter_query;
666        let filter_indexes = params.filter_indexes;
667        let filter_from = params.filter_from;
668        let filter_to = params.filter_to;
669        let filter_storage_tier = params.filter_storage_tier;
670        let sort = params.sort;
671        let page_cursor = params.page_cursor;
672        let page_limit = params.page_limit;
673
674        let local_client = &self.client;
675
676        let local_uri_str = format!(
677            "{}/api/v2/logs/events",
678            local_configuration.get_operation_host(operation_id)
679        );
680        let mut local_req_builder =
681            local_client.request(reqwest::Method::GET, local_uri_str.as_str());
682
683        if let Some(ref local_query_param) = filter_query {
684            local_req_builder =
685                local_req_builder.query(&[("filter[query]", &local_query_param.to_string())]);
686        };
687        if let Some(ref local) = filter_indexes {
688            local_req_builder = local_req_builder.query(&[(
689                "filter[indexes]",
690                &local
691                    .iter()
692                    .map(|p| p.to_string())
693                    .collect::<Vec<String>>()
694                    .join(",")
695                    .to_string(),
696            )]);
697        };
698        if let Some(ref local_query_param) = filter_from {
699            local_req_builder = local_req_builder.query(&[(
700                "filter[from]",
701                &local_query_param.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
702            )]);
703        };
704        if let Some(ref local_query_param) = filter_to {
705            local_req_builder = local_req_builder.query(&[(
706                "filter[to]",
707                &local_query_param.to_rfc3339_opts(chrono::SecondsFormat::Millis, true),
708            )]);
709        };
710        if let Some(ref local_query_param) = filter_storage_tier {
711            local_req_builder = local_req_builder
712                .query(&[("filter[storage_tier]", &local_query_param.to_string())]);
713        };
714        if let Some(ref local_query_param) = sort {
715            local_req_builder =
716                local_req_builder.query(&[("sort", &local_query_param.to_string())]);
717        };
718        if let Some(ref local_query_param) = page_cursor {
719            local_req_builder =
720                local_req_builder.query(&[("page[cursor]", &local_query_param.to_string())]);
721        };
722        if let Some(ref local_query_param) = page_limit {
723            local_req_builder =
724                local_req_builder.query(&[("page[limit]", &local_query_param.to_string())]);
725        };
726
727        // build headers
728        let mut headers = HeaderMap::new();
729        headers.insert("Accept", HeaderValue::from_static("application/json"));
730
731        // build user agent
732        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
733            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
734            Err(e) => {
735                log::warn!("Failed to parse user agent header: {e}, falling back to default");
736                headers.insert(
737                    reqwest::header::USER_AGENT,
738                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
739                )
740            }
741        };
742
743        // build auth
744        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
745            headers.insert(
746                "DD-API-KEY",
747                HeaderValue::from_str(local_key.key.as_str())
748                    .expect("failed to parse DD-API-KEY header"),
749            );
750        };
751        if let Some(local_key) = local_configuration.auth_keys.get("appKeyAuth") {
752            headers.insert(
753                "DD-APPLICATION-KEY",
754                HeaderValue::from_str(local_key.key.as_str())
755                    .expect("failed to parse DD-APPLICATION-KEY header"),
756            );
757        };
758
759        local_req_builder = local_req_builder.headers(headers);
760        let local_req = local_req_builder.build()?;
761        log::debug!("request content: {:?}", local_req.body());
762        let local_resp = local_client.execute(local_req).await?;
763
764        let local_status = local_resp.status();
765        let local_content = local_resp.text().await?;
766        log::debug!("response content: {}", local_content);
767
768        if !local_status.is_client_error() && !local_status.is_server_error() {
769            match serde_json::from_str::<crate::datadogV2::model::LogsListResponse>(&local_content)
770            {
771                Ok(e) => {
772                    return Ok(datadog::ResponseContent {
773                        status: local_status,
774                        content: local_content,
775                        entity: Some(e),
776                    })
777                }
778                Err(e) => return Err(datadog::Error::Serde(e)),
779            };
780        } else {
781            let local_entity: Option<ListLogsGetError> = serde_json::from_str(&local_content).ok();
782            let local_error = datadog::ResponseContent {
783                status: local_status,
784                content: local_content,
785                entity: local_entity,
786            };
787            Err(datadog::Error::ResponseError(local_error))
788        }
789    }
790
791    /// Send your logs to your Datadog platform over HTTP. Limits per HTTP request are:
792    ///
793    /// - Maximum content size per payload (uncompressed): 5MB
794    /// - Maximum size for a single log: 1MB
795    /// - Maximum array size if sending multiple logs in an array: 1000 entries
796    ///
797    /// Any log exceeding 1MB is accepted and truncated by Datadog:
798    /// - For a single log request, the API truncates the log at 1MB and returns a 2xx.
799    /// - For a multi-logs request, the API processes all logs, truncates only logs larger than 1MB, and returns a 2xx.
800    ///
801    /// Datadog recommends sending your logs compressed.
802    /// Add the `Content-Encoding: gzip` header to the request when sending compressed logs.
803    /// Log events can be submitted with a timestamp that is up to 18 hours in the past.
804    ///
805    /// The status codes answered by the HTTP API are:
806    /// - 202: Accepted: the request has been accepted for processing
807    /// - 400: Bad request (likely an issue in the payload formatting)
808    /// - 401: Unauthorized (likely a missing API Key)
809    /// - 403: Permission issue (likely using an invalid API Key)
810    /// - 408: Request Timeout, request should be retried after some time
811    /// - 413: Payload too large (batch is above 5MB uncompressed)
812    /// - 429: Too Many Requests, request should be retried after some time
813    /// - 500: Internal Server Error, the server encountered an unexpected condition that prevented it from fulfilling the request, request should be retried after some time
814    /// - 503: Service Unavailable, the server is not ready to handle the request probably because it is overloaded, request should be retried after some time
815    pub async fn submit_log(
816        &self,
817        body: Vec<crate::datadogV2::model::HTTPLogItem>,
818        params: SubmitLogOptionalParams,
819    ) -> Result<std::collections::BTreeMap<String, serde_json::Value>, datadog::Error<SubmitLogError>>
820    {
821        match self.submit_log_with_http_info(body, params).await {
822            Ok(response_content) => {
823                if let Some(e) = response_content.entity {
824                    Ok(e)
825                } else {
826                    Err(datadog::Error::Serde(serde::de::Error::custom(
827                        "response content was None",
828                    )))
829                }
830            }
831            Err(err) => Err(err),
832        }
833    }
834
835    /// Send your logs to your Datadog platform over HTTP. Limits per HTTP request are:
836    ///
837    /// - Maximum content size per payload (uncompressed): 5MB
838    /// - Maximum size for a single log: 1MB
839    /// - Maximum array size if sending multiple logs in an array: 1000 entries
840    ///
841    /// Any log exceeding 1MB is accepted and truncated by Datadog:
842    /// - For a single log request, the API truncates the log at 1MB and returns a 2xx.
843    /// - For a multi-logs request, the API processes all logs, truncates only logs larger than 1MB, and returns a 2xx.
844    ///
845    /// Datadog recommends sending your logs compressed.
846    /// Add the `Content-Encoding: gzip` header to the request when sending compressed logs.
847    /// Log events can be submitted with a timestamp that is up to 18 hours in the past.
848    ///
849    /// The status codes answered by the HTTP API are:
850    /// - 202: Accepted: the request has been accepted for processing
851    /// - 400: Bad request (likely an issue in the payload formatting)
852    /// - 401: Unauthorized (likely a missing API Key)
853    /// - 403: Permission issue (likely using an invalid API Key)
854    /// - 408: Request Timeout, request should be retried after some time
855    /// - 413: Payload too large (batch is above 5MB uncompressed)
856    /// - 429: Too Many Requests, request should be retried after some time
857    /// - 500: Internal Server Error, the server encountered an unexpected condition that prevented it from fulfilling the request, request should be retried after some time
858    /// - 503: Service Unavailable, the server is not ready to handle the request probably because it is overloaded, request should be retried after some time
859    pub async fn submit_log_with_http_info(
860        &self,
861        body: Vec<crate::datadogV2::model::HTTPLogItem>,
862        params: SubmitLogOptionalParams,
863    ) -> Result<
864        datadog::ResponseContent<std::collections::BTreeMap<String, serde_json::Value>>,
865        datadog::Error<SubmitLogError>,
866    > {
867        let local_configuration = &self.config;
868        let operation_id = "v2.submit_log";
869
870        // unbox and build optional parameters
871        let content_encoding = params.content_encoding;
872        let ddtags = params.ddtags;
873
874        let local_client = &self.client;
875
876        let local_uri_str = format!(
877            "{}/api/v2/logs",
878            local_configuration.get_operation_host(operation_id)
879        );
880        let mut local_req_builder =
881            local_client.request(reqwest::Method::POST, local_uri_str.as_str());
882
883        if let Some(ref local_query_param) = ddtags {
884            local_req_builder =
885                local_req_builder.query(&[("ddtags", &local_query_param.to_string())]);
886        };
887
888        // build headers
889        let mut headers = HeaderMap::new();
890        headers.insert("Content-Type", HeaderValue::from_static("application/json"));
891        headers.insert("Accept", HeaderValue::from_static("application/json"));
892
893        if let Some(ref local) = content_encoding {
894            headers.insert(
895                "Content-Encoding",
896                local
897                    .to_string()
898                    .parse()
899                    .expect("failed to parse Content-Encoding header"),
900            );
901        }
902
903        // build user agent
904        match HeaderValue::from_str(local_configuration.user_agent.as_str()) {
905            Ok(user_agent) => headers.insert(reqwest::header::USER_AGENT, user_agent),
906            Err(e) => {
907                log::warn!("Failed to parse user agent header: {e}, falling back to default");
908                headers.insert(
909                    reqwest::header::USER_AGENT,
910                    HeaderValue::from_static(datadog::DEFAULT_USER_AGENT.as_str()),
911                )
912            }
913        };
914
915        // build auth
916        if let Some(local_key) = local_configuration.auth_keys.get("apiKeyAuth") {
917            headers.insert(
918                "DD-API-KEY",
919                HeaderValue::from_str(local_key.key.as_str())
920                    .expect("failed to parse DD-API-KEY header"),
921            );
922        };
923
924        // build body parameters
925        let output = Vec::new();
926        let mut ser = serde_json::Serializer::with_formatter(output, datadog::DDFormatter);
927        if body.serialize(&mut ser).is_ok() {
928            if let Some(content_encoding) = headers.get("Content-Encoding") {
929                match content_encoding.to_str().unwrap_or_default() {
930                    "gzip" => {
931                        let mut enc = GzEncoder::new(Vec::new(), Compression::default());
932                        let _ = enc.write_all(ser.into_inner().as_slice());
933                        match enc.finish() {
934                            Ok(buf) => {
935                                local_req_builder = local_req_builder.body(buf);
936                            }
937                            Err(e) => return Err(datadog::Error::Io(e)),
938                        }
939                    }
940                    "deflate" => {
941                        let mut enc = ZlibEncoder::new(Vec::new(), Compression::default());
942                        let _ = enc.write_all(ser.into_inner().as_slice());
943                        match enc.finish() {
944                            Ok(buf) => {
945                                local_req_builder = local_req_builder.body(buf);
946                            }
947                            Err(e) => return Err(datadog::Error::Io(e)),
948                        }
949                    }
950                    "zstd1" => {
951                        let mut enc = zstd::stream::Encoder::new(Vec::new(), 0).unwrap();
952                        let _ = enc.write_all(ser.into_inner().as_slice());
953                        match enc.finish() {
954                            Ok(buf) => {
955                                local_req_builder = local_req_builder.body(buf);
956                            }
957                            Err(e) => return Err(datadog::Error::Io(e)),
958                        }
959                    }
960                    _ => {
961                        local_req_builder = local_req_builder.body(ser.into_inner());
962                    }
963                }
964            } else {
965                local_req_builder = local_req_builder.body(ser.into_inner());
966            }
967        }
968
969        local_req_builder = local_req_builder.headers(headers);
970        let local_req = local_req_builder.build()?;
971        log::debug!("request content: {:?}", local_req.body());
972        let local_resp = local_client.execute(local_req).await?;
973
974        let local_status = local_resp.status();
975        let local_content = local_resp.text().await?;
976        log::debug!("response content: {}", local_content);
977
978        if !local_status.is_client_error() && !local_status.is_server_error() {
979            match serde_json::from_str::<std::collections::BTreeMap<String, serde_json::Value>>(
980                &local_content,
981            ) {
982                Ok(e) => {
983                    return Ok(datadog::ResponseContent {
984                        status: local_status,
985                        content: local_content,
986                        entity: Some(e),
987                    })
988                }
989                Err(e) => return Err(datadog::Error::Serde(e)),
990            };
991        } else {
992            let local_entity: Option<SubmitLogError> = serde_json::from_str(&local_content).ok();
993            let local_error = datadog::ResponseContent {
994                status: local_status,
995                content: local_content,
996                entity: local_entity,
997            };
998            Err(datadog::Error::ResponseError(local_error))
999        }
1000    }
1001}