Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/ffi/profiles.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,15 @@ int main(void) {
exit(EXIT_FAILURE);
}

ddog_prof_Profile_Result omit_result =
ddog_prof_Profile_set_omit_local_root_span_id_when_serializing(&profile, true);
if (omit_result.tag != DDOG_PROF_PROFILE_RESULT_OK) {
ddog_CharSlice message = ddog_Error_message(&omit_result.err);
fprintf(stderr, "%.*s", (int)message.len, message.ptr);
ddog_Error_drop(&omit_result.err);
goto cleanup;
}

// Original API sample
ddog_prof_Location root_location = {
// yes, a zero-initialized mapping is valid
Expand Down
27 changes: 27 additions & 0 deletions libdd-profiling-ffi/src/profiles/datatypes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -682,6 +682,33 @@ pub unsafe extern "C" fn ddog_prof_Profile_add_endpoint_count(
.into()
}

/// Set whether "local root span id" labels should be omitted when serializing.
///
/// This is an experimental setting and defaults to false.
///
/// # Arguments
/// * `profile` - a reference to the profile being configured.
/// * `omit` - true to omit the label from serialized pprof samples.
///
/// # Safety
/// The `profile` ptr must point to a valid Profile object created by this
/// module.
/// This call is _NOT_ thread-safe.
#[no_mangle]
#[must_use]
pub unsafe extern "C" fn ddog_prof_Profile_set_omit_local_root_span_id_when_serializing(
profile: *mut Profile,
omit: bool,
) -> ProfileResult {
(|| {
let profile = profile_ptr_to_inner(profile)?;
profile.set_omit_local_root_span_id_when_serializing(omit);
anyhow::Ok(())
})()
.context("ddog_prof_Profile_set_omit_local_root_span_id_when_serializing failed")
.into()
}

/// Add a poisson-based upscaling rule which will be use to adjust values and make them
/// closer to reality.
///
Expand Down
56 changes: 55 additions & 1 deletion libdd-profiling/src/internal/profile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ pub struct Profile {
profiles_dictionary_translator: Option<ProfilesDictionaryTranslator>,
active_samples: AtomicU64,
endpoints: Endpoints,
experimental_omit_local_root_span_id_when_serializing: bool,
functions: FxIndexSet<Function>,
generation: interning_api::Generation,
labels: FxIndexSet<Label>,
Expand Down Expand Up @@ -122,6 +123,10 @@ impl Profile {
Ok(())
}

pub fn set_omit_local_root_span_id_when_serializing(&mut self, omit: bool) {
self.experimental_omit_local_root_span_id_when_serializing = omit;
}

pub fn try_add_sample(
&mut self,
sample: api::Sample,
Expand Down Expand Up @@ -543,6 +548,8 @@ impl Profile {
extended_label_sets.push(self.expand_label_set(&label_set)?);
}

let omit_local_root_span_id = self.experimental_omit_local_root_span_id_when_serializing;
let local_root_span_id_label = self.endpoints.local_root_span_id_label;
let iter = std::mem::take(&mut self.observations).try_into_iter()?;
for (sample, timestamp, mut values) in iter {
let off = sample.labels.to_offset();
Expand All @@ -564,7 +571,16 @@ impl Profile {
// The memory was reserved by `expand_label_set`.
labels.push(Label::num(self.timestamp_key, ts.get(), StringId::ZERO))
}
pprof_labels.extend(labels.iter().map(protobuf::Label::from));
if omit_local_root_span_id {
pprof_labels.extend(
labels
.iter()
.filter(|label| label.get_key() != local_root_span_id_label)
.map(protobuf::Label::from),
);
} else {
pprof_labels.extend(labels.iter().map(protobuf::Label::from));
}
if timestamp.is_some() {
labels.pop();
}
Expand Down Expand Up @@ -934,6 +950,7 @@ impl Profile {
profiles_dictionary_translator,
active_samples: Default::default(),
endpoints: Default::default(),
experimental_omit_local_root_span_id_when_serializing: false,
functions: Default::default(),
generation: Generation::new(),

Expand Down Expand Up @@ -1486,6 +1503,43 @@ mod api_tests {
Ok(())
}

#[test]
fn omit_local_root_span_id_when_serializing() -> anyhow::Result<()> {
let sample_types = [api::SampleType::CpuSamples, api::SampleType::WallTime];

let mut profile: Profile = Profile::new(&sample_types, None);
profile.set_omit_local_root_span_id_when_serializing(true);

let sample = api::Sample {
locations: vec![],
values: &[1, 10000],
labels: vec![api::Label {
key: "local root span id",
str: "",
num: 10,
num_unit: "",
}],
};

profile.try_add_sample(sample, None)?;
profile.add_endpoint(10, Cow::from("my endpoint"))?;

let serialized_profile = roundtrip_to_pprof(profile)?;
let sample = serialized_profile.samples.first().expect("sample");

assert_eq!(sample.labels.len(), 1);
Comment thread
ivoanjo marked this conversation as resolved.
Outdated
let endpoint_label = sample.labels.first().expect("label");
assert_eq!(
string_table_fetch(&serialized_profile, endpoint_label.key),
"trace endpoint"
);
assert_eq!(
string_table_fetch(&serialized_profile, endpoint_label.str),
"my endpoint"
);
Ok(())
}

#[test]
fn endpoint_counts_empty_test() {
let sample_types = [api::SampleType::CpuSamples, api::SampleType::WallTime];
Expand Down
Loading