Skip to content

Commit 67d88eb

Browse files
authored
[profiling] Add support for process_tags (#1359)
Add support for process_tags Add unit tests Add test for FFI process_tags as a string instead of an object Co-authored-by: gregory.leocadie <[email protected]>
1 parent 897c25f commit 67d88eb

File tree

4 files changed

+93
-6
lines changed

4 files changed

+93
-6
lines changed

examples/ffi/exporter.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ int main(int argc, char *argv[]) {
140140
}
141141

142142
auto build_result = ddog_prof_Exporter_Request_build(
143-
exporter, encoded_profile, files_to_compress_and_export, files_to_export_unmodified, nullptr,
143+
exporter, encoded_profile, files_to_compress_and_export, files_to_export_unmodified, nullptr, nullptr,
144144
&internal_metadata_example, &info_example);
145145
ddog_prof_EncodedProfile_drop(encoded_profile);
146146

libdd-profiling-ffi/src/exporter.rs

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ pub unsafe extern "C" fn ddog_prof_Exporter_Request_build(
220220
files_to_compress_and_export: Slice<File>,
221221
files_to_export_unmodified: Slice<File>,
222222
optional_additional_tags: Option<&libdd_common_ffi::Vec<Tag>>,
223+
optional_process_tags: Option<&CharSlice>,
223224
optional_internal_metadata_json: Option<&CharSlice>,
224225
optional_info_json: Option<&CharSlice>,
225226
) -> Result<Handle<Request>> {
@@ -229,7 +230,10 @@ pub unsafe extern "C" fn ddog_prof_Exporter_Request_build(
229230
let files_to_compress_and_export = into_vec_files(files_to_compress_and_export);
230231
let files_to_export_unmodified = into_vec_files(files_to_export_unmodified);
231232
let tags = optional_additional_tags.map(|tags| tags.iter().cloned().collect());
232-
233+
// Convert CharSlice to &str without copying
234+
let process_tags_str = optional_process_tags
235+
.map(|cs| cs.try_to_utf8())
236+
.transpose()?;
233237
let internal_metadata = parse_json("internal_metadata", optional_internal_metadata_json)?;
234238
let info = parse_json("info", optional_info_json)?;
235239

@@ -238,6 +242,7 @@ pub unsafe extern "C" fn ddog_prof_Exporter_Request_build(
238242
files_to_compress_and_export.as_slice(),
239243
files_to_export_unmodified.as_slice(),
240244
tags.as_ref(),
245+
process_tags_str,
241246
internal_metadata,
242247
info,
243248
)?;
@@ -486,6 +491,7 @@ mod tests {
486491
None,
487492
None,
488493
None,
494+
None,
489495
)
490496
};
491497

@@ -571,6 +577,7 @@ mod tests {
571577
Slice::empty(),
572578
Slice::empty(),
573579
None,
580+
None,
574581
Some(&raw_internal_metadata),
575582
None,
576583
)
@@ -587,6 +594,51 @@ mod tests {
587594
assert_eq!(internal["libdatadog_version"], env!("CARGO_PKG_VERSION"));
588595
}
589596

597+
#[test]
598+
// This test invokes an external function SecTrustSettingsCopyCertificates
599+
// which Miri cannot evaluate.
600+
#[cfg_attr(miri, ignore)]
601+
fn test_build_with_process_tags() {
602+
let exporter_result = unsafe {
603+
ddog_prof_Exporter_new(
604+
profiling_library_name(),
605+
profiling_library_version(),
606+
family(),
607+
None,
608+
ddog_prof_Endpoint_agent(endpoint()),
609+
)
610+
};
611+
612+
let mut exporter = exporter_result.unwrap();
613+
614+
let profile = &mut EncodedProfile::test_instance().unwrap().into();
615+
let timeout_milliseconds = 90;
616+
unsafe {
617+
ddog_prof_Exporter_set_timeout(&mut exporter, timeout_milliseconds).unwrap();
618+
}
619+
620+
// Create process_tags as CharSlice
621+
let expected_process_tags_str = "entrypoint.basedir:net10.0,entrypoint.name:buggybits.program,entrypoint.workdir:this_folder,runtime_platform:x86_64-pc-windows-msvc";
622+
let expected_process_tags = CharSlice::from(expected_process_tags_str);
623+
624+
let build_result = unsafe {
625+
ddog_prof_Exporter_Request_build(
626+
&mut exporter,
627+
profile,
628+
Slice::empty(),
629+
Slice::empty(),
630+
None,
631+
Some(&expected_process_tags),
632+
None,
633+
None,
634+
)
635+
};
636+
637+
let parsed_event_json = parsed_event_json(build_result);
638+
639+
assert_eq!(parsed_event_json["process_tags"], expected_process_tags_str);
640+
}
641+
590642
#[test]
591643
// This test invokes an external function SecTrustSettingsCopyCertificates
592644
// which Miri cannot evaluate.
@@ -620,6 +672,7 @@ mod tests {
620672
Slice::empty(),
621673
Slice::empty(),
622674
None,
675+
None,
623676
Some(&raw_internal_metadata),
624677
None,
625678
)
@@ -693,6 +746,7 @@ mod tests {
693746
Slice::empty(),
694747
None,
695748
None,
749+
None,
696750
Some(&raw_info),
697751
)
698752
};
@@ -763,6 +817,7 @@ mod tests {
763817
Slice::empty(),
764818
None,
765819
None,
820+
None,
766821
Some(&raw_info),
767822
)
768823
};
@@ -786,6 +841,7 @@ mod tests {
786841
None,
787842
None,
788843
None,
844+
None,
789845
)
790846
};
791847

libdd-profiling/src/exporter/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,7 @@ impl ProfileExporter {
187187
files_to_compress_and_export: &[File],
188188
files_to_export_unmodified: &[File],
189189
additional_tags: Option<&Vec<Tag>>,
190+
process_tags: Option<&str>,
190191
internal_metadata: Option<serde_json::Value>,
191192
info: Option<serde_json::Value>,
192193
) -> anyhow::Result<Request> {
@@ -200,6 +201,8 @@ impl ProfileExporter {
200201
tags_profiler.push(',');
201202
}
202203

204+
let tags_process = process_tags.unwrap_or("");
205+
203206
if let Some(aas_metadata) = &*azure_app_services::AAS_METADATA {
204207
let aas_tags = [
205208
("aas.resource.id", aas_metadata.get_resource_id()),
@@ -253,6 +256,7 @@ impl ProfileExporter {
253256
let event = json!({
254257
"attachments": attachments,
255258
"tags_profiler": tags_profiler,
259+
"process_tags": tags_process,
256260
"start": DateTime::<Utc>::from(profile.start).format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string(),
257261
"end": DateTime::<Utc>::from(profile.end).format("%Y-%m-%dT%H:%M:%S%.9fZ").to_string(),
258262
"family": self.family.as_ref(),

libdd-profiling/tests/form.rs

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ fn multipart(
88
exporter: &mut ProfileExporter,
99
internal_metadata: Option<serde_json::Value>,
1010
info: Option<serde_json::Value>,
11+
process_tags: Option<&str>,
1112
) -> Request {
1213
let profile = EncodedProfile::test_instance().expect("To get a profile");
1314

@@ -23,6 +24,7 @@ fn multipart(
2324
files_to_compress_and_export,
2425
files_to_export_unmodified,
2526
None,
27+
process_tags,
2628
internal_metadata,
2729
info,
2830
)
@@ -84,7 +86,7 @@ mod tests {
8486
)
8587
.expect("exporter to construct");
8688

87-
let request = multipart(&mut exporter, None, None);
89+
let request = multipart(&mut exporter, None, None, None);
8890

8991
assert_eq!(
9092
request.uri().to_string(),
@@ -154,12 +156,37 @@ mod tests {
154156
"extra object": {"key": [1, 2, true]},
155157
"libdatadog_version": env!("CARGO_PKG_VERSION"),
156158
});
157-
let request = multipart(&mut exporter, Some(internal_metadata.clone()), None);
159+
let request = multipart(&mut exporter, Some(internal_metadata.clone()), None, None);
158160
let parsed_event_json = parsed_event_json(request);
159161

160162
assert_eq!(parsed_event_json["internal"], internal_metadata);
161163
}
162164

165+
#[test]
166+
// This test invokes an external function SecTrustSettingsCopyCertificates
167+
// which Miri cannot evaluate.
168+
#[cfg_attr(miri, ignore)]
169+
fn including_process_tags() {
170+
let profiling_library_name = "dd-trace-foo";
171+
let profiling_library_version = "1.2.3";
172+
let base_url = "http://localhost:8126".parse().expect("url to parse");
173+
let endpoint = config::agent(base_url).expect("endpoint to construct");
174+
let mut exporter = ProfileExporter::new(
175+
profiling_library_name,
176+
profiling_library_version,
177+
"php",
178+
Some(default_tags()),
179+
endpoint,
180+
)
181+
.expect("exporter to construct");
182+
183+
let expected_process_tags = "entrypoint.basedir:net10.0,entrypoint.name:buggybits.program,entrypoint.workdir:this_folder,runtime_platform:x86_64-pc-windows-msvc";
184+
let request = multipart(&mut exporter, None, None, Some(expected_process_tags));
185+
let parsed_event_json = parsed_event_json(request);
186+
187+
assert_eq!(parsed_event_json["process_tags"], expected_process_tags);
188+
}
189+
163190
#[test]
164191
// This test invokes an external function SecTrustSettingsCopyCertificates
165192
// which Miri cannot evaluate.
@@ -194,7 +221,7 @@ mod tests {
194221
"settings": {}
195222
}
196223
});
197-
let request = multipart(&mut exporter, None, Some(info.clone()));
224+
let request = multipart(&mut exporter, None, Some(info.clone()), None);
198225
let parsed_event_json = parsed_event_json(request);
199226

200227
assert_eq!(parsed_event_json["info"], info);
@@ -218,7 +245,7 @@ mod tests {
218245
)
219246
.expect("exporter to construct");
220247

221-
let request = multipart(&mut exporter, None, None);
248+
let request = multipart(&mut exporter, None, None, None);
222249

223250
assert_eq!(
224251
request.uri().to_string(),

0 commit comments

Comments
 (0)