diff --git a/.github/workflows/verify-proto-files.yml b/.github/workflows/verify-proto-files.yml index 2dddd0f53d..4f0e8c19db 100644 --- a/.github/workflows/verify-proto-files.yml +++ b/.github/workflows/verify-proto-files.yml @@ -3,7 +3,7 @@ on: pull_request: types: [ opened, synchronize, reopened ] env: - DATADOG_AGENT_TAG: "bdcdd8cf1ba4090a29b96d5669cfab5dd81814b1" + DATADOG_AGENT_TAG: "fdc29d4428db855950228a642c43a5595e56bb09" CARGO_TERM_COLOR: always CARGO_INCREMENTAL: 0 jobs: diff --git a/datadog-ipc/src/shm_stats.rs b/datadog-ipc/src/shm_stats.rs index a103d246a0..0a250692db 100644 --- a/datadog-ipc/src/shm_stats.rs +++ b/datadog-ipc/src/shm_stats.rs @@ -818,6 +818,7 @@ impl ShmSpanConcentrator { .unwrap_or_default(), service_source: read_str!(f.service_source), span_derived_primary_tags: vec![], + additional_metric_tags: vec![], } } } diff --git a/libdd-trace-protobuf/build.rs b/libdd-trace-protobuf/build.rs index 0aed6036ad..83d1b8a3c7 100644 --- a/libdd-trace-protobuf/build.rs +++ b/libdd-trace-protobuf/build.rs @@ -56,6 +56,19 @@ fn generate_protobuf() { // intake expects the name ContainerID rather than the PascalCase ContainerId config.type_attribute("TracerPayload", "#[derive(Deserialize, Serialize)]"); + config.field_attribute( + ".pb.TracerPayload.containerDebug", + "#[serde(skip_serializing_if = \"Option::is_none\")]", + ); + config.type_attribute( + "ContainerDebug", + "#[derive(Deserialize, Serialize, PartialOrd, Ord)]", + ); + config.field_attribute("ContainerDebug.error", "#[serde(default)]"); + config.field_attribute("ContainerDebug.latencyMs", "#[serde(default)]"); + config.field_attribute("ContainerDebug.wasBuffered", "#[serde(default)]"); + config.field_attribute("ContainerDebug.bufferMs", "#[serde(default)]"); + config.field_attribute("ContainerDebug.bufferEvictionReason", "#[serde(default)]"); config.type_attribute("TraceChunk", "#[derive(Deserialize, Serialize)]"); config.type_attribute("SpanLink", "#[derive(Deserialize, Serialize)]"); @@ -216,6 +229,10 @@ fn generate_protobuf() { "ClientGroupedStats.span_derived_primary_tags", "#[serde(default)]", ); + config.field_attribute( + "ClientGroupedStats.additional_metric_tags", + "#[serde(default)]", + ); config.field_attribute( "ClientGroupedStats.okSummary", diff --git a/libdd-trace-protobuf/src/pb.idx.rs b/libdd-trace-protobuf/src/pb.idx.rs index 35245295a8..a135f0a9a0 100644 --- a/libdd-trace-protobuf/src/pb.idx.rs +++ b/libdd-trace-protobuf/src/pb.idx.rs @@ -276,4 +276,32 @@ pub struct TracerPayload { /// chunks specifies list of containing trace chunks. #[prost(message, repeated, tag = "11")] pub chunks: ::prost::alloc::vec::Vec, + /// containerDebug holds debug information about the container tags resolution. + #[prost(message, optional, tag = "12")] + pub container_debug: ::core::option::Option, +} +/// ContainerDebug holds debug information about the container tags resolution process. +#[derive(Deserialize, Serialize, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ContainerDebug { + /// error specifies any error that occurred during container tag resolution. + #[prost(string, tag = "1")] + #[serde(default)] + pub error: ::prost::alloc::string::String, + /// latencyMs specifies the latency in milliseconds of the container tag resolution. + #[prost(int64, tag = "2")] + #[serde(default)] + pub latency_ms: i64, + /// wasBuffered specifies whether the payload was buffered while waiting for container tags. + #[prost(bool, tag = "3")] + #[serde(default)] + pub was_buffered: bool, + /// bufferMs specifies how long the payload was buffered in milliseconds. + #[prost(int64, tag = "4")] + #[serde(default)] + pub buffer_ms: i64, + /// bufferEvictionReason specifies why the payload was evicted from the buffer. + #[prost(string, tag = "5")] + #[serde(default)] + pub buffer_eviction_reason: ::prost::alloc::string::String, } diff --git a/libdd-trace-protobuf/src/pb.rs b/libdd-trace-protobuf/src/pb.rs index feae884fb7..a54b90126e 100644 --- a/libdd-trace-protobuf/src/pb.rs +++ b/libdd-trace-protobuf/src/pb.rs @@ -426,6 +426,41 @@ pub struct TracerPayload { /// @gotags: json:"app_version" msg:"app_version" #[prost(string, tag = "10")] pub app_version: ::prost::alloc::string::String, + /// containerDebug holds debug information about the container tags resolution. + /// @gotags: json:"container_debug,omitempty" msg:"container_debug,omitempty" + #[prost(message, optional, tag = "11")] + #[serde(skip_serializing_if = "Option::is_none")] + pub container_debug: ::core::option::Option, +} +/// ContainerDebug holds debug information about the container tags resolution process. +#[derive(Deserialize, Serialize, PartialOrd, Ord)] +#[derive(Clone, PartialEq, Eq, Hash, ::prost::Message)] +pub struct ContainerDebug { + /// error specifies any error that occurred during container tag resolution. + /// @gotags: json:"error,omitempty" msg:"error,omitempty" + #[prost(string, tag = "1")] + #[serde(default)] + pub error: ::prost::alloc::string::String, + /// latencyMs specifies the latency in milliseconds of the container tag resolution. + /// @gotags: json:"latency_ms,omitempty" msg:"latency_ms,omitempty" + #[prost(int64, tag = "2")] + #[serde(default)] + pub latency_ms: i64, + /// wasBuffered specifies whether the payload was buffered while waiting for container tags. + /// @gotags: json:"was_buffered,omitempty" msg:"was_buffered,omitempty" + #[prost(bool, tag = "3")] + #[serde(default)] + pub was_buffered: bool, + /// bufferMs specifies how long the payload was buffered in milliseconds. + /// @gotags: json:"buffer_ms,omitempty" msg:"buffer_ms,omitempty" + #[prost(int64, tag = "4")] + #[serde(default)] + pub buffer_ms: i64, + /// bufferEvictionReason specifies why the payload was evicted from the buffer. + /// @gotags: json:"buffer_eviction_reason,omitempty" msg:"buffer_eviction_reason,omitempty" + #[prost(string, tag = "5")] + #[serde(default)] + pub buffer_eviction_reason: ::prost::alloc::string::String, } /// AgentPayload represents payload the agent sends to the intake. #[derive(Clone, PartialEq, ::prost::Message)] @@ -659,13 +694,16 @@ pub struct ClientGroupedStats { #[serde(rename = "srv_src")] pub service_source: ::prost::alloc::string::String, /// used to identify service override origin - /// span_derived_primary_tags are user-configured tags that are extracted from spans and used for stats aggregation - /// E.g., `aws.s3.bucket`, `http.url`, or any custom tag + /// Deprecated: use additional_metric_tags (field 23) instead. #[prost(string, repeated, tag = "22")] #[serde(default)] pub span_derived_primary_tags: ::prost::alloc::vec::Vec< ::prost::alloc::string::String, >, + /// additional_metric_tags are tags sent by tracers to be used as additional dimensions for stats aggregation + #[prost(string, repeated, tag = "23")] + #[serde(default)] + pub additional_metric_tags: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, } /// Trilean is an expanded boolean type that is meant to differentiate between being unset and false. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)] diff --git a/libdd-trace-protobuf/src/pb/idx/tracer_payload.proto b/libdd-trace-protobuf/src/pb/idx/tracer_payload.proto index dbad7f339b..bf1da768e5 100644 --- a/libdd-trace-protobuf/src/pb/idx/tracer_payload.proto +++ b/libdd-trace-protobuf/src/pb/idx/tracer_payload.proto @@ -48,4 +48,20 @@ message TracerPayload { map attributes = 10; // chunks specifies list of containing trace chunks. repeated TraceChunk chunks = 11; + // containerDebug holds debug information about the container tags resolution. + ContainerDebug containerDebug = 12; +} + +// ContainerDebug holds debug information about the container tags resolution process. +message ContainerDebug { + // error specifies any error that occurred during container tag resolution. + string error = 1; + // latencyMs specifies the latency in milliseconds of the container tag resolution. + int64 latencyMs = 2; + // wasBuffered specifies whether the payload was buffered while waiting for container tags. + bool wasBuffered = 3; + // bufferMs specifies how long the payload was buffered in milliseconds. + int64 bufferMs = 4; + // bufferEvictionReason specifies why the payload was evicted from the buffer. + string bufferEvictionReason = 5; } diff --git a/libdd-trace-protobuf/src/pb/stats.proto b/libdd-trace-protobuf/src/pb/stats.proto index e5b5a24fca..15b5c4f61e 100644 --- a/libdd-trace-protobuf/src/pb/stats.proto +++ b/libdd-trace-protobuf/src/pb/stats.proto @@ -105,7 +105,8 @@ message ClientGroupedStats { string HTTP_endpoint = 20; // Http route or quantized/simplified URL path string service_source = 21; // @inject_tag: msg:"srv_src" // used to identify service override origin - // span_derived_primary_tags are user-configured tags that are extracted from spans and used for stats aggregation - // E.g., `aws.s3.bucket`, `http.url`, or any custom tag + // Deprecated: use additional_metric_tags (field 23) instead. repeated string span_derived_primary_tags = 22; + // additional_metric_tags are tags sent by tracers to be used as additional dimensions for stats aggregation + repeated string additional_metric_tags = 23; } diff --git a/libdd-trace-protobuf/src/pb/tracer_payload.proto b/libdd-trace-protobuf/src/pb/tracer_payload.proto index 7bc5cbe486..0f2c104f93 100644 --- a/libdd-trace-protobuf/src/pb/tracer_payload.proto +++ b/libdd-trace-protobuf/src/pb/tracer_payload.proto @@ -57,4 +57,26 @@ message TracerPayload { // version specifies `version` tag that set with the tracer. // @gotags: json:"app_version" msg:"app_version" string appVersion = 10; + // containerDebug holds debug information about the container tags resolution. + // @gotags: json:"container_debug,omitempty" msg:"container_debug,omitempty" + ContainerDebug containerDebug = 11; +} + +// ContainerDebug holds debug information about the container tags resolution process. +message ContainerDebug { + // error specifies any error that occurred during container tag resolution. + // @gotags: json:"error,omitempty" msg:"error,omitempty" + string error = 1; + // latencyMs specifies the latency in milliseconds of the container tag resolution. + // @gotags: json:"latency_ms,omitempty" msg:"latency_ms,omitempty" + int64 latencyMs = 2; + // wasBuffered specifies whether the payload was buffered while waiting for container tags. + // @gotags: json:"was_buffered,omitempty" msg:"was_buffered,omitempty" + bool wasBuffered = 3; + // bufferMs specifies how long the payload was buffered in milliseconds. + // @gotags: json:"buffer_ms,omitempty" msg:"buffer_ms,omitempty" + int64 bufferMs = 4; + // bufferEvictionReason specifies why the payload was evicted from the buffer. + // @gotags: json:"buffer_eviction_reason,omitempty" msg:"buffer_eviction_reason,omitempty" + string bufferEvictionReason = 5; } diff --git a/libdd-trace-protobuf/src/pb_test.rs b/libdd-trace-protobuf/src/pb_test.rs index 5d9cb68b84..d474cdd571 100644 --- a/libdd-trace-protobuf/src/pb_test.rs +++ b/libdd-trace-protobuf/src/pb_test.rs @@ -114,6 +114,7 @@ mod tests { http_method: "GET".to_string(), service_source: "".to_string(), span_derived_primary_tags: vec![], + additional_metric_tags: vec![], }], agent_time_shift: 0, }], @@ -133,4 +134,38 @@ mod tests { assert_eq!(deserialized_stats_json, client_stats_payload) } + + #[test] + fn test_deserialize_tracer_payload_partial_container_debug() { + use crate::pb::{ContainerDebug, TracerPayload}; + + let json = r#"{ + "container_id": "cid", + "language_name": "go", + "language_version": "1.22", + "tracer_version": "1.0", + "runtime_id": "runtime", + "chunks": [], + "tags": {}, + "env": "prod", + "hostname": "host", + "app_version": "2.0", + "container_debug": { + "latency_ms": 42, + "was_buffered": true + } + }"#; + + let decoded: TracerPayload = serde_json::from_str(json).unwrap(); + assert_eq!( + decoded.container_debug, + Some(ContainerDebug { + error: String::new(), + latency_ms: 42, + was_buffered: true, + buffer_ms: 0, + buffer_eviction_reason: String::new(), + }) + ); + } } diff --git a/libdd-trace-stats/src/span_concentrator/aggregation.rs b/libdd-trace-stats/src/span_concentrator/aggregation.rs index a76a90b248..97d358c05f 100644 --- a/libdd-trace-stats/src/span_concentrator/aggregation.rs +++ b/libdd-trace-stats/src/span_concentrator/aggregation.rs @@ -499,7 +499,8 @@ fn encode_grouped_stats(key: OwnedAggregationKey, group: GroupedStats) -> pb::Cl .map(|c| c.to_string()) .unwrap_or_default(), service_source: f.service_source, - span_derived_primary_tags: vec![], // Todo + span_derived_primary_tags: vec![], + additional_metric_tags: vec![], } } diff --git a/libdd-trace-utils/src/stats_utils.rs b/libdd-trace-utils/src/stats_utils.rs index 708b7ee883..60324f0ce7 100644 --- a/libdd-trace-utils/src/stats_utils.rs +++ b/libdd-trace-utils/src/stats_utils.rs @@ -191,6 +191,7 @@ mod mini_agent_tests { http_method: "GET".to_string(), service_source: "".to_string(), span_derived_primary_tags: vec![], + additional_metric_tags: vec![], }], agent_time_shift: 0, }], diff --git a/libdd-trace-utils/src/test_utils/mod.rs b/libdd-trace-utils/src/test_utils/mod.rs index 819999feed..cff7f8045b 100644 --- a/libdd-trace-utils/src/test_utils/mod.rs +++ b/libdd-trace-utils/src/test_utils/mod.rs @@ -498,6 +498,7 @@ pub fn create_send_data(size: usize, target_endpoint: &Endpoint) -> SendData { env: "test".to_owned(), hostname: "test_host".to_owned(), app_version: "2.0".to_owned(), + container_debug: None, }; SendData::new( diff --git a/libdd-trace-utils/src/trace_utils.rs b/libdd-trace-utils/src/trace_utils.rs index 851ac54beb..f790ec069c 100644 --- a/libdd-trace-utils/src/trace_utils.rs +++ b/libdd-trace-utils/src/trace_utils.rs @@ -318,6 +318,7 @@ pub(crate) fn construct_tracer_payload( language_version: tracer_tags.lang_version.to_string(), tags: HashMap::new(), tracer_version: tracer_tags.tracer_version.to_string(), + container_debug: None, } } @@ -331,6 +332,7 @@ pub(crate) fn cmp_send_data_payloads(a: &pb::TracerPayload, b: &pb::TracerPayloa .then(a.runtime_id.cmp(&b.runtime_id)) .then(a.env.cmp(&b.env)) .then(a.app_version.cmp(&b.app_version)) + .then(a.container_debug.cmp(&b.container_debug)) } pub fn coalesce_send_data(mut data: Vec) -> Vec { @@ -742,6 +744,7 @@ mod tests { env: "".to_string(), hostname: "".to_string(), app_version: "".to_string(), + container_debug: None, }]), TracerHeaderTags::default(), &Endpoint::default(), diff --git a/libdd-trace-utils/src/tracer_payload.rs b/libdd-trace-utils/src/tracer_payload.rs index 30752cabdf..035366fd80 100644 --- a/libdd-trace-utils/src/tracer_payload.rs +++ b/libdd-trace-utils/src/tracer_payload.rs @@ -264,6 +264,7 @@ mod tests { env: "".to_string(), hostname: "".to_string(), app_version: "".to_string(), + container_debug: None, }]) }