From 90a29a7df2b9d8c54ea3bb0f8c572d57ecfe8be0 Mon Sep 17 00:00:00 2001 From: "ci.datadog-api-spec" Date: Fri, 21 Feb 2025 18:22:42 +0000 Subject: [PATCH] Regenerate client from commit 5de91bd6 of spec repo --- .apigentools-info | 8 +- .generator/schemas/v1/openapi.yaml | 40 ++++- ...pipelines_CreateLogsPipeline_2707101123.rs | 29 ++++ src/datadogV1/model/mod.rs | 4 + src/datadogV1/model/model_logs_processor.rs | 8 + .../model/model_logs_span_remapper.rs | 156 ++++++++++++++++++ .../model/model_logs_span_remapper_type.rs | 48 ++++++ ...pan-Id-Remapper-returns-OK-response.frozen | 1 + ...-Span-Id-Remapper-returns-OK-response.json | 67 ++++++++ .../features/v1/logs_pipelines.feature | 7 + 10 files changed, 363 insertions(+), 5 deletions(-) create mode 100644 examples/v1_logs-pipelines_CreateLogsPipeline_2707101123.rs create mode 100644 src/datadogV1/model/model_logs_span_remapper.rs create mode 100644 src/datadogV1/model/model_logs_span_remapper_type.rs create mode 100644 tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.frozen create mode 100644 tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.json diff --git a/.apigentools-info b/.apigentools-info index ef966c796..ec2a9e4a8 100644 --- a/.apigentools-info +++ b/.apigentools-info @@ -4,13 +4,13 @@ "spec_versions": { "v1": { "apigentools_version": "1.6.6", - "regenerated": "2025-02-21 08:00:35.115496", - "spec_repo_commit": "8f2d39c3" + "regenerated": "2025-02-21 18:16:27.438843", + "spec_repo_commit": "5de91bd6" }, "v2": { "apigentools_version": "1.6.6", - "regenerated": "2025-02-21 08:00:35.131024", - "spec_repo_commit": "8f2d39c3" + "regenerated": "2025-02-21 18:16:27.454329", + "spec_repo_commit": "5de91bd6" } } } \ No newline at end of file diff --git a/.generator/schemas/v1/openapi.yaml b/.generator/schemas/v1/openapi.yaml index ffdec05dc..3564cd239 100644 --- a/.generator/schemas/v1/openapi.yaml +++ b/.generator/schemas/v1/openapi.yaml @@ -6049,6 +6049,7 @@ components: - $ref: '#/components/schemas/LogsLookupProcessor' - $ref: '#/components/schemas/ReferenceTableLogsLookupProcessor' - $ref: '#/components/schemas/LogsTraceRemapper' + - $ref: '#/components/schemas/LogsSpanRemapper' LogsQueryCompute: description: Define computation for a log query. properties: @@ -6160,6 +6161,43 @@ components: x-enum-varnames: - TIME_ASCENDING - TIME_DESCENDING + LogsSpanRemapper: + description: "There are two ways to define correlation between application spans + and logs:\n\n 1. Follow the documentation on [how to inject a span ID in + the application logs](https://docs.datadoghq.com/tracing/connect_logs_and_traces).\n + \ Log integrations automatically handle all remaining setup steps by default.\n\n + \ 2. Use the span remapper processor to define a log attribute as its associated + span ID." + properties: + is_enabled: + default: false + description: Whether or not the processor is enabled. + type: boolean + name: + description: Name of the processor. + type: string + sources: + default: + - dd.span_id + description: Array of source attributes. + items: + description: Attribute to extract the span ID from. + type: string + type: array + type: + $ref: '#/components/schemas/LogsSpanRemapperType' + required: + - type + type: object + LogsSpanRemapperType: + default: span-id-remapper + description: Type of logs span remapper. + enum: + - span-id-remapper + example: span-id-remapper + type: string + x-enum-varnames: + - SPAN_ID_REMAPPER LogsStatusRemapper: description: "Use this Processor if you want to assign some attributes as the official status.\n\nEach incoming status value is mapped as follows.\n\n - @@ -6275,7 +6313,7 @@ components: - dd.trace_id description: Array of source attributes. items: - description: Attribute to extract the Trace ID from. + description: Attribute to extract the trace ID from. type: string type: array type: diff --git a/examples/v1_logs-pipelines_CreateLogsPipeline_2707101123.rs b/examples/v1_logs-pipelines_CreateLogsPipeline_2707101123.rs new file mode 100644 index 000000000..c22b27996 --- /dev/null +++ b/examples/v1_logs-pipelines_CreateLogsPipeline_2707101123.rs @@ -0,0 +1,29 @@ +// Create a pipeline with Span Id Remapper returns "OK" response +use datadog_api_client::datadog; +use datadog_api_client::datadogV1::api_logs_pipelines::LogsPipelinesAPI; +use datadog_api_client::datadogV1::model::LogsFilter; +use datadog_api_client::datadogV1::model::LogsPipeline; +use datadog_api_client::datadogV1::model::LogsProcessor; +use datadog_api_client::datadogV1::model::LogsSpanRemapper; +use datadog_api_client::datadogV1::model::LogsSpanRemapperType; + +#[tokio::main] +async fn main() { + let body = LogsPipeline::new("testPipeline".to_string()) + .filter(LogsFilter::new().query("source:python".to_string())) + .processors(vec![LogsProcessor::LogsSpanRemapper(Box::new( + LogsSpanRemapper::new(LogsSpanRemapperType::SPAN_ID_REMAPPER) + .is_enabled(true) + .name("test_filter".to_string()) + .sources(vec!["dd.span_id".to_string()]), + ))]) + .tags(vec![]); + let configuration = datadog::Configuration::new(); + let api = LogsPipelinesAPI::with_config(configuration); + let resp = api.create_logs_pipeline(body).await; + if let Ok(value) = resp { + println!("{:#?}", value); + } else { + println!("{:#?}", resp.unwrap_err()); + } +} diff --git a/src/datadogV1/model/mod.rs b/src/datadogV1/model/mod.rs index b3244463c..83ff7cd9b 100644 --- a/src/datadogV1/model/mod.rs +++ b/src/datadogV1/model/mod.rs @@ -900,6 +900,10 @@ pub mod model_logs_trace_remapper; pub use self::model_logs_trace_remapper::LogsTraceRemapper; pub mod model_logs_trace_remapper_type; pub use self::model_logs_trace_remapper_type::LogsTraceRemapperType; +pub mod model_logs_span_remapper; +pub use self::model_logs_span_remapper::LogsSpanRemapper; +pub mod model_logs_span_remapper_type; +pub use self::model_logs_span_remapper_type::LogsSpanRemapperType; pub mod model_logs_processor; pub use self::model_logs_processor::LogsProcessor; pub mod model_logs_pipeline_processor_type; diff --git a/src/datadogV1/model/model_logs_processor.rs b/src/datadogV1/model/model_logs_processor.rs index 01551d159..63c9a1188 100644 --- a/src/datadogV1/model/model_logs_processor.rs +++ b/src/datadogV1/model/model_logs_processor.rs @@ -26,6 +26,7 @@ pub enum LogsProcessor { Box, ), LogsTraceRemapper(Box), + LogsSpanRemapper(Box), UnparsedObject(crate::datadog::UnparsedObject), } @@ -150,6 +151,13 @@ impl<'de> Deserialize<'de> for LogsProcessor { return Ok(LogsProcessor::LogsTraceRemapper(_v)); } } + if let Ok(_v) = + serde_json::from_value::>(value.clone()) + { + if !_v._unparsed { + return Ok(LogsProcessor::LogsSpanRemapper(_v)); + } + } return Ok(LogsProcessor::UnparsedObject( crate::datadog::UnparsedObject { value }, diff --git a/src/datadogV1/model/model_logs_span_remapper.rs b/src/datadogV1/model/model_logs_span_remapper.rs new file mode 100644 index 000000000..ae94df57b --- /dev/null +++ b/src/datadogV1/model/model_logs_span_remapper.rs @@ -0,0 +1,156 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. +use serde::de::{Error, MapAccess, Visitor}; +use serde::{Deserialize, Deserializer, Serialize}; +use serde_with::skip_serializing_none; +use std::fmt::{self, Formatter}; + +/// There are two ways to define correlation between application spans and logs: +/// +/// 1. Follow the documentation on [how to inject a span ID in the application logs](). +/// Log integrations automatically handle all remaining setup steps by default. +/// +/// 2. Use the span remapper processor to define a log attribute as its associated span ID. +#[non_exhaustive] +#[skip_serializing_none] +#[derive(Clone, Debug, PartialEq, Serialize)] +pub struct LogsSpanRemapper { + /// Whether or not the processor is enabled. + #[serde(rename = "is_enabled")] + pub is_enabled: Option, + /// Name of the processor. + #[serde(rename = "name")] + pub name: Option, + /// Array of source attributes. + #[serde(rename = "sources")] + pub sources: Option>, + /// Type of logs span remapper. + #[serde(rename = "type")] + pub type_: crate::datadogV1::model::LogsSpanRemapperType, + #[serde(flatten)] + pub additional_properties: std::collections::BTreeMap, + #[serde(skip)] + #[serde(default)] + pub(crate) _unparsed: bool, +} + +impl LogsSpanRemapper { + pub fn new(type_: crate::datadogV1::model::LogsSpanRemapperType) -> LogsSpanRemapper { + LogsSpanRemapper { + is_enabled: None, + name: None, + sources: None, + type_, + additional_properties: std::collections::BTreeMap::new(), + _unparsed: false, + } + } + + pub fn is_enabled(mut self, value: bool) -> Self { + self.is_enabled = Some(value); + self + } + + pub fn name(mut self, value: String) -> Self { + self.name = Some(value); + self + } + + pub fn sources(mut self, value: Vec) -> Self { + self.sources = Some(value); + self + } + + pub fn additional_properties( + mut self, + value: std::collections::BTreeMap, + ) -> Self { + self.additional_properties = value; + self + } +} + +impl<'de> Deserialize<'de> for LogsSpanRemapper { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + struct LogsSpanRemapperVisitor; + impl<'a> Visitor<'a> for LogsSpanRemapperVisitor { + type Value = LogsSpanRemapper; + + fn expecting(&self, f: &mut Formatter<'_>) -> fmt::Result { + f.write_str("a mapping") + } + + fn visit_map(self, mut map: M) -> Result + where + M: MapAccess<'a>, + { + let mut is_enabled: Option = None; + let mut name: Option = None; + let mut sources: Option> = None; + let mut type_: Option = None; + let mut additional_properties: std::collections::BTreeMap< + String, + serde_json::Value, + > = std::collections::BTreeMap::new(); + let mut _unparsed = false; + + while let Some((k, v)) = map.next_entry::()? { + match k.as_str() { + "is_enabled" => { + if v.is_null() { + continue; + } + is_enabled = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "name" => { + if v.is_null() { + continue; + } + name = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "sources" => { + if v.is_null() { + continue; + } + sources = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + } + "type" => { + type_ = Some(serde_json::from_value(v).map_err(M::Error::custom)?); + if let Some(ref _type_) = type_ { + match _type_ { + crate::datadogV1::model::LogsSpanRemapperType::UnparsedObject(_type_) => { + _unparsed = true; + }, + _ => {} + } + } + } + &_ => { + if let Ok(value) = serde_json::from_value(v.clone()) { + additional_properties.insert(k, value); + } + } + } + } + let type_ = type_.ok_or_else(|| M::Error::missing_field("type_"))?; + + let content = LogsSpanRemapper { + is_enabled, + name, + sources, + type_, + additional_properties, + _unparsed, + }; + + Ok(content) + } + } + + deserializer.deserialize_any(LogsSpanRemapperVisitor) + } +} diff --git a/src/datadogV1/model/model_logs_span_remapper_type.rs b/src/datadogV1/model/model_logs_span_remapper_type.rs new file mode 100644 index 000000000..f2924dad4 --- /dev/null +++ b/src/datadogV1/model/model_logs_span_remapper_type.rs @@ -0,0 +1,48 @@ +// Unless explicitly stated otherwise all files in this repository are licensed under the Apache-2.0 License. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2019-Present Datadog, Inc. + +use serde::{Deserialize, Deserializer, Serialize, Serializer}; + +#[non_exhaustive] +#[derive(Clone, Debug, Eq, PartialEq)] +pub enum LogsSpanRemapperType { + SPAN_ID_REMAPPER, + UnparsedObject(crate::datadog::UnparsedObject), +} + +impl ToString for LogsSpanRemapperType { + fn to_string(&self) -> String { + match self { + Self::SPAN_ID_REMAPPER => String::from("span-id-remapper"), + Self::UnparsedObject(v) => v.value.to_string(), + } + } +} + +impl Serialize for LogsSpanRemapperType { + fn serialize(&self, serializer: S) -> Result + where + S: Serializer, + { + match self { + Self::UnparsedObject(v) => v.serialize(serializer), + _ => serializer.serialize_str(self.to_string().as_str()), + } + } +} + +impl<'de> Deserialize<'de> for LogsSpanRemapperType { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + let s: String = String::deserialize(deserializer)?; + Ok(match s.as_str() { + "span-id-remapper" => Self::SPAN_ID_REMAPPER, + _ => Self::UnparsedObject(crate::datadog::UnparsedObject { + value: serde_json::Value::String(s.into()), + }), + }) + } +} diff --git a/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.frozen b/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.frozen new file mode 100644 index 000000000..388fb50cc --- /dev/null +++ b/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.frozen @@ -0,0 +1 @@ +2025-02-20T15:44:02.905Z \ No newline at end of file diff --git a/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.json b/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.json new file mode 100644 index 000000000..ef1f652f6 --- /dev/null +++ b/tests/scenarios/cassettes/v1/logs_pipelines/Create-a-pipeline-with-Span-Id-Remapper-returns-OK-response.json @@ -0,0 +1,67 @@ +{ + "http_interactions": [ + { + "request": { + "body": { + "string": "{\"filter\":{\"query\":\"source:python\"},\"name\":\"testPipeline\",\"processors\":[{\"is_enabled\":true,\"name\":\"test_filter\",\"sources\":[\"dd.span_id\"],\"type\":\"span-id-remapper\"}],\"tags\":[]}", + "encoding": null + }, + "headers": { + "Accept": [ + "application/json" + ], + "Content-Type": [ + "application/json" + ] + }, + "method": "post", + "uri": "https://api.datadoghq.com/api/v1/logs/config/pipelines" + }, + "response": { + "body": { + "string": "{\"id\":\"duWU4bc3ROq5nz7GVi5TzA\",\"type\":\"pipeline\",\"name\":\"testPipeline\",\"is_enabled\":false,\"is_read_only\":false,\"filter\":{\"query\":\"source:python\"},\"processors\":[{\"name\":\"test_filter\",\"is_enabled\":true,\"sources\":[\"dd.span_id\"],\"type\":\"span-id-remapper\"}],\"tags\":[]}\n", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Thu, 20 Feb 2025 15:44:02 GMT" + }, + { + "request": { + "body": "", + "headers": { + "Accept": [ + "*/*" + ] + }, + "method": "delete", + "uri": "https://api.datadoghq.com/api/v1/logs/config/pipelines/duWU4bc3ROq5nz7GVi5TzA" + }, + "response": { + "body": { + "string": "{}\n", + "encoding": null + }, + "headers": { + "Content-Type": [ + "application/json" + ] + }, + "status": { + "code": 200, + "message": "OK" + } + }, + "recorded_at": "Thu, 20 Feb 2025 15:44:02 GMT" + } + ], + "recorded_with": "VCR 6.0.0" +} \ No newline at end of file diff --git a/tests/scenarios/features/v1/logs_pipelines.feature b/tests/scenarios/features/v1/logs_pipelines.feature index 001d0356d..6a895252e 100644 --- a/tests/scenarios/features/v1/logs_pipelines.feature +++ b/tests/scenarios/features/v1/logs_pipelines.feature @@ -35,6 +35,13 @@ Feature: Logs Pipelines When the request is sent Then the response status is 200 OK + @team:DataDog/event-platform-experience + Scenario: Create a pipeline with Span Id Remapper returns "OK" response + Given new "CreateLogsPipeline" request + And body with value {"filter": {"query": "source:python"}, "name": "testPipeline", "processors": [{"type": "span-id-remapper", "is_enabled" : true, "name" : "test_filter", "sources" : [ "dd.span_id"] }], "tags": []} + When the request is sent + Then the response status is 200 OK + @generated @skip @team:DataDog/event-platform-experience Scenario: Delete a pipeline returns "Bad Request" response Given new "DeleteLogsPipeline" request