diff --git a/libdd-data-pipeline-ffi/src/trace_exporter.rs b/libdd-data-pipeline-ffi/src/trace_exporter.rs index 20a3f380f0..4aaa719298 100644 --- a/libdd-data-pipeline-ffi/src/trace_exporter.rs +++ b/libdd-data-pipeline-ffi/src/trace_exporter.rs @@ -98,6 +98,7 @@ pub struct TraceExporterConfig { client_computed_stats: bool, telemetry_cfg: Option, health_metrics_enabled: bool, + process_tags: Option, test_session_token: Option, connection_timeout: Option, } @@ -389,6 +390,26 @@ pub unsafe extern "C" fn ddog_trace_exporter_config_set_client_computed_stats( ) } +/// Sets the process tags to be included in the stats payload. +#[no_mangle] +pub unsafe extern "C" fn ddog_trace_exporter_config_set_process_tags( + config: Option<&mut TraceExporterConfig>, + process_tags: CharSlice, +) -> Option> { + catch_panic!( + if let Option::Some(handle) = config { + handle.process_tags = match sanitize_string(process_tags) { + Ok(s) => Some(s), + Err(e) => return Some(e), + }; + None + } else { + gen_error!(ErrorCode::InvalidArgument) + }, + gen_error!(ErrorCode::Panic) + ) +} + /// Sets the `X-Datadog-Test-Session-Token` header. Only used for testing with the test agent. #[no_mangle] pub unsafe extern "C" fn ddog_trace_exporter_config_set_test_session_token( @@ -456,6 +477,7 @@ pub unsafe extern "C" fn ddog_trace_exporter_new( .set_env(config.env.as_ref().unwrap_or(&"".to_string())) .set_app_version(config.version.as_ref().unwrap_or(&"".to_string())) .set_service(config.service.as_ref().unwrap_or(&"".to_string())) + .set_process_tags(config.process_tags.as_deref().unwrap_or("")) .set_input_format(config.input_format) .set_output_format(config.output_format) .set_connection_timeout(config.connection_timeout); @@ -570,6 +592,7 @@ mod tests { assert!(!cfg.compute_stats); assert!(cfg.telemetry_cfg.is_none()); assert!(!cfg.health_metrics_enabled); + assert!(cfg.process_tags.is_none()); assert!(cfg.test_session_token.is_none()); assert!(cfg.connection_timeout.is_none()); @@ -759,6 +782,27 @@ mod tests { } } + #[test] + fn config_process_tags_test() { + unsafe { + let error = ddog_trace_exporter_config_set_process_tags(None, CharSlice::from("k:v")); + assert_eq!(error.as_ref().unwrap().code, ErrorCode::InvalidArgument); + + ddog_trace_exporter_error_free(error); + + let mut config = Some(TraceExporterConfig::default()); + let error = ddog_trace_exporter_config_set_process_tags( + config.as_mut(), + CharSlice::from("key1:val1,key2:val2"), + ); + + assert_eq!(error, None); + + let cfg = config.unwrap(); + assert_eq!(cfg.process_tags.as_ref().unwrap(), "key1:val1,key2:val2"); + } + } + #[test] fn config_client_computed_stats_test() { unsafe { diff --git a/libdd-data-pipeline/src/stats_exporter.rs b/libdd-data-pipeline/src/stats_exporter.rs index 6b64c09ecc..8e2768dbec 100644 --- a/libdd-data-pipeline/src/stats_exporter.rs +++ b/libdd-data-pipeline/src/stats_exporter.rs @@ -168,13 +168,13 @@ fn encode_stats_payload( sequence, stats: buckets, git_commit_sha: meta.git_commit_sha.clone(), + process_tags: meta.process_tags.clone(), // These fields are unused or will be set by the Agent service: String::new(), container_id: String::new(), tags: Vec::new(), agent_aggregation: String::new(), image_tag: String::new(), - process_tags: String::new(), process_tags_hash: 0, } } @@ -217,6 +217,7 @@ mod tests { language: "rust".into(), tracer_version: "0.0.0".into(), runtime_id: "e39d6d12-0752-489f-b488-cf80006c0378".into(), + process_tags: "key1:value1,key2:value2".into(), ..Default::default() } } @@ -257,7 +258,8 @@ mod tests { when.method(POST) .header("Content-type", "application/msgpack") .path("/v0.6/stats") - .body_includes("libdatadog-test"); + .body_includes("libdatadog-test") + .body_includes("key1:value1,key2:value2"); then.status(200).body(""); }) .await; @@ -318,7 +320,8 @@ mod tests { when.method(POST) .header("Content-type", "application/msgpack") .path("/v0.6/stats") - .body_includes("libdatadog-test"); + .body_includes("libdatadog-test") + .body_includes("key1:value1,key2:value2"); then.status(200).body(""); }) .await; @@ -356,7 +359,8 @@ mod tests { when.method(POST) .header("Content-type", "application/msgpack") .path("/v0.6/stats") - .body_includes("libdatadog-test"); + .body_includes("libdatadog-test") + .body_includes("key1:value1,key2:value2"); then.status(200).body(""); }) .await; diff --git a/libdd-data-pipeline/src/trace_exporter/builder.rs b/libdd-data-pipeline/src/trace_exporter/builder.rs index f9833fa668..4c96161bf8 100644 --- a/libdd-data-pipeline/src/trace_exporter/builder.rs +++ b/libdd-data-pipeline/src/trace_exporter/builder.rs @@ -34,6 +34,7 @@ pub struct TraceExporterBuilder { language_interpreter: String, language_interpreter_vendor: String, git_commit_sha: String, + process_tags: String, input_format: TraceExporterInputFormat, output_format: TraceExporterOutputFormat, dogstatsd_url: Option, @@ -111,6 +112,11 @@ impl TraceExporterBuilder { self } + pub fn set_process_tags(&mut self, process_tags: &str) -> &mut Self { + process_tags.clone_into(&mut self.process_tags); + self + } + /// Set the `Datadog-Meta-Tracer-Version` header pub fn set_tracer_version(&mut self, tracer_version: &str) -> &mut Self { tracer_version.clone_into(&mut self.tracer_version); @@ -309,6 +315,7 @@ impl TraceExporterBuilder { language_interpreter_vendor: self.language_interpreter_vendor, language: self.language, git_commit_sha: self.git_commit_sha, + process_tags: self.process_tags, client_computed_stats: self.client_computed_stats, client_computed_top_level: self.client_computed_top_level, hostname: self.hostname, diff --git a/libdd-data-pipeline/src/trace_exporter/mod.rs b/libdd-data-pipeline/src/trace_exporter/mod.rs index 02320a684d..4169a89323 100644 --- a/libdd-data-pipeline/src/trace_exporter/mod.rs +++ b/libdd-data-pipeline/src/trace_exporter/mod.rs @@ -128,6 +128,7 @@ pub struct TracerMetadata { pub language_interpreter: String, pub language_interpreter_vendor: String, pub git_commit_sha: String, + pub process_tags: String, pub client_computed_stats: bool, pub client_computed_top_level: bool, }