Skip to content

Commit acd7f83

Browse files
committed
profiles for the samples
1 parent 2d5a8b5 commit acd7f83

File tree

9 files changed

+217
-119
lines changed

9 files changed

+217
-119
lines changed

datadog-profiling-otel/build.rs

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,26 @@ fn main() {
99
println!("cargo:rerun-if-changed=profiles.proto");
1010
println!("cargo:rerun-if-changed=opentelemetry/proto/common/v1/common.proto");
1111
println!("cargo:rerun-if-changed=opentelemetry/proto/resource/v1/resource.proto");
12-
12+
1313
// Create the output directory
1414
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
15-
15+
1616
// Configure prost-build
1717
let mut config = prost_build::Config::new();
1818
config.out_dir(&out_dir);
19-
19+
2020
// Compile the proto files - include all proto files so imports work correctly
2121
config
2222
.compile_protos(
2323
&[
2424
"opentelemetry/proto/common/v1/common.proto",
2525
"opentelemetry/proto/resource/v1/resource.proto",
26-
"profiles.proto"
26+
"profiles.proto",
2727
],
28-
&["."]
28+
&["."],
2929
)
3030
.expect("Failed to compile protobuf files");
31-
31+
3232
// Generate the module file with correct structure
3333
let module_content = r#"
3434
// Copyright 2025-Present Datadog, Inc. https://www.datadoghq.com/
@@ -61,7 +61,6 @@ pub use opentelemetry::proto::profiles::v1development::*;
6161
pub use opentelemetry::proto::common::v1::*;
6262
pub use opentelemetry::proto::resource::v1::*;
6363
"#;
64-
65-
std::fs::write(out_dir.join("mod.rs"), module_content)
66-
.expect("Failed to write module file");
64+
65+
std::fs::write(out_dir.join("mod.rs"), module_content).expect("Failed to write module file");
6766
}

datadog-profiling-otel/examples/basic_usage.rs

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,22 @@
66

77
fn main() {
88
use datadog_profiling_otel::*;
9-
9+
1010
// Create a simple profile with some basic data
1111
let mut profiles_dict = ProfilesDictionary::default();
12-
12+
1313
// Add some strings to the string table
1414
profiles_dict.string_table.push("cpu".to_string());
1515
profiles_dict.string_table.push("nanoseconds".to_string());
1616
profiles_dict.string_table.push("main".to_string());
17-
17+
1818
// Create a sample type
1919
let sample_type = ValueType {
2020
type_strindex: 0, // "cpu"
2121
unit_strindex: 1, // "nanoseconds"
2222
aggregation_temporality: AggregationTemporality::Delta.into(),
2323
};
24-
24+
2525
// Create a profile
2626
let profile = Profile {
2727
sample_type: Some(sample_type),
@@ -31,22 +31,28 @@ fn main() {
3131
.as_nanos() as i64,
3232
..Default::default()
3333
};
34-
34+
3535
// Create profiles data
3636
let mut profiles_data = ProfilesData {
3737
dictionary: Some(profiles_dict),
3838
..Default::default()
3939
};
40-
40+
4141
let mut scope_profiles = ScopeProfiles::default();
4242
scope_profiles.profiles.push(profile);
43-
43+
4444
let mut resource_profiles = ResourceProfiles::default();
4545
resource_profiles.scope_profiles.push(scope_profiles);
46-
46+
4747
profiles_data.resource_profiles.push(resource_profiles);
48-
48+
4949
println!("Successfully created OpenTelemetry profile data!");
50-
println!("Profile contains {} resource profiles", profiles_data.resource_profiles.len());
51-
println!("Time: {}", profiles_data.resource_profiles[0].scope_profiles[0].profiles[0].time_nanos);
50+
println!(
51+
"Profile contains {} resource profiles",
52+
profiles_data.resource_profiles.len()
53+
);
54+
println!(
55+
"Time: {}",
56+
profiles_data.resource_profiles[0].scope_profiles[0].profiles[0].time_nanos
57+
);
5258
}

datadog-profiling-otel/src/lib.rs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,19 +15,22 @@ pub use proto::*;
1515
#[cfg(test)]
1616
mod tests {
1717
use super::*;
18-
18+
1919
#[test]
2020
fn test_proto_generation() {
2121
// Test that we can create basic protobuf messages
2222
let mut profiles_dict = ProfilesDictionary::default();
2323
profiles_dict.string_table.push("test".to_string());
24-
24+
2525
let profiles_data = ProfilesData {
2626
dictionary: Some(profiles_dict),
2727
..Default::default()
2828
};
29-
29+
3030
// Verify the data was set correctly
31-
assert_eq!(profiles_data.dictionary.as_ref().unwrap().string_table[0], "test");
31+
assert_eq!(
32+
profiles_data.dictionary.as_ref().unwrap().string_table[0],
33+
"test"
34+
);
3235
}
3336
}

datadog-profiling/src/internal/profile/otel_emitter/label.rs

Lines changed: 59 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
// Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/
22
// SPDX-License-Identifier: Apache-2.0
33

4+
//! All the mess here will go away once https://github.com/open-telemetry/opentelemetry-proto/pull/672/files is merged.
5+
46
use crate::collections::identifiable::Id;
57
use crate::internal::Label as InternalLabel;
6-
use anyhow::{Result, Context};
8+
use anyhow::{Context, Result};
79
use std::collections::HashMap;
810

911
/// Converts a datadog-profiling internal Label to an OpenTelemetry KeyValue
10-
///
12+
///
1113
/// # Arguments
1214
/// * `label` - The internal label to convert
1315
/// * `string_table` - A slice of strings where StringIds index into
14-
/// * `key_to_unit_map` - A mutable map from key string index to unit string index for numeric labels
15-
///
16+
/// * `key_to_unit_map` - A mutable map from key string index to unit string index for numeric
17+
/// labels
18+
///
1619
/// # Returns
1720
/// * `Ok(KeyValue)` if the conversion is successful
1821
/// * `Err` with context if the StringIds are out of bounds of the string table
@@ -25,33 +28,47 @@ pub fn convert_label_to_key_value(
2528
let key_id = label.get_key().to_raw_id() as usize;
2629
let key = string_table
2730
.get(key_id)
28-
.with_context(|| format!("Key string index {} out of bounds (string table has {} elements)", key_id, string_table.len()))?
31+
.with_context(|| {
32+
format!(
33+
"Key string index {} out of bounds (string table has {} elements)",
34+
key_id,
35+
string_table.len()
36+
)
37+
})?
2938
.to_string();
30-
39+
3140
match label.get_value() {
3241
crate::internal::LabelValue::Str(str_id) => {
3342
let str_value_id = str_id.to_raw_id() as usize;
3443
let str_value = string_table
3544
.get(str_value_id)
36-
.with_context(|| format!("Value string index {} out of bounds (string table has {} elements)", str_value_id, string_table.len()))?
45+
.with_context(|| {
46+
format!(
47+
"Value string index {} out of bounds (string table has {} elements)",
48+
str_value_id,
49+
string_table.len()
50+
)
51+
})?
3752
.to_string();
38-
53+
3954
Ok(datadog_profiling_otel::KeyValue {
4055
key,
41-
value: Some(datadog_profiling_otel::key_value::Value::StringValue(str_value)),
56+
value: Some(datadog_profiling_otel::key_value::Value::StringValue(
57+
str_value,
58+
)),
4259
})
4360
}
4461
crate::internal::LabelValue::Num { num, num_unit } => {
45-
// Note: OpenTelemetry KeyValue doesn't support units, so we only store the numeric value
46-
// But we track the mapping for building the attribute_units table
62+
// Note: OpenTelemetry KeyValue doesn't support units, so we only store the numeric
63+
// value But we track the mapping for building the attribute_units table
4764
let key_index = label.get_key().to_raw_id() as usize;
4865
let unit_index = num_unit.to_raw_id() as usize;
49-
66+
5067
// Only add to the map if the unit is not the default empty string (index 0)
5168
if unit_index > 0 {
5269
key_to_unit_map.insert(key_index, unit_index);
5370
}
54-
71+
5572
Ok(datadog_profiling_otel::KeyValue {
5673
key,
5774
value: Some(datadog_profiling_otel::key_value::Value::IntValue(*num)),
@@ -68,20 +85,20 @@ mod tests {
6885
#[test]
6986
fn test_convert_string_label() {
7087
let string_table = vec![
71-
"".to_string(), // index 0
72-
"thread_id".to_string(), // index 1
73-
"main".to_string(), // index 2
88+
"".to_string(), // index 0
89+
"thread_id".to_string(), // index 1
90+
"main".to_string(), // index 2
7491
];
75-
92+
7693
let label = InternalLabel::str(
7794
StringId::from_offset(1), // "thread_id"
7895
StringId::from_offset(2), // "main"
7996
);
80-
97+
8198
let mut key_to_unit_map = HashMap::new();
8299
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
83100
assert!(result.is_ok());
84-
101+
85102
let key_value = result.unwrap();
86103
assert_eq!(key_value.key, "thread_id");
87104
match key_value.value {
@@ -95,21 +112,21 @@ mod tests {
95112
#[test]
96113
fn test_convert_numeric_label() {
97114
let string_table = vec![
98-
"".to_string(), // index 0
115+
"".to_string(), // index 0
99116
"allocation_size".to_string(), // index 1
100-
"bytes".to_string(), // index 2
117+
"bytes".to_string(), // index 2
101118
];
102-
119+
103120
let label = InternalLabel::num(
104121
StringId::from_offset(1), // "allocation_size"
105122
1024, // 1024 bytes
106123
StringId::from_offset(2), // "bytes"
107124
);
108-
125+
109126
let mut key_to_unit_map = HashMap::new();
110127
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
111128
assert!(result.is_ok());
112-
129+
113130
let key_value = result.unwrap();
114131
assert_eq!(key_value.key, "allocation_size");
115132
match key_value.value {
@@ -123,12 +140,12 @@ mod tests {
123140
#[test]
124141
fn test_convert_label_out_of_bounds() {
125142
let string_table = vec!["".to_string()]; // Only one string
126-
143+
127144
let label = InternalLabel::str(
128145
StringId::from_offset(1), // This index doesn't exist
129146
StringId::from_offset(0), // This index exists
130147
);
131-
148+
132149
let mut key_to_unit_map = HashMap::new();
133150
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
134151
assert!(result.is_err());
@@ -137,12 +154,12 @@ mod tests {
137154
#[test]
138155
fn test_convert_label_empty_string_table() {
139156
let string_table: Vec<String> = vec![];
140-
157+
141158
let label = InternalLabel::str(
142159
StringId::from_offset(0), // Even index 0 is out of bounds
143160
StringId::from_offset(0),
144161
);
145-
162+
146163
let mut key_to_unit_map = HashMap::new();
147164
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
148165
assert!(result.is_err());
@@ -151,21 +168,21 @@ mod tests {
151168
#[test]
152169
fn test_convert_numeric_label_with_unit_mapping() {
153170
let string_table = vec![
154-
"".to_string(), // index 0
171+
"".to_string(), // index 0
155172
"memory_usage".to_string(), // index 1
156-
"megabytes".to_string(), // index 2
173+
"megabytes".to_string(), // index 2
157174
];
158-
175+
159176
let label = InternalLabel::num(
160177
StringId::from_offset(1), // "memory_usage"
161-
512, // 512 MB
178+
512, // 512 MB
162179
StringId::from_offset(2), // "megabytes"
163180
);
164-
181+
165182
let mut key_to_unit_map = HashMap::new();
166183
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
167184
assert!(result.is_ok());
168-
185+
169186
// Verify the KeyValue conversion
170187
let key_value = result.unwrap();
171188
assert_eq!(key_value.key, "memory_usage");
@@ -175,28 +192,28 @@ mod tests {
175192
}
176193
_ => panic!("Expected IntValue"),
177194
}
178-
195+
179196
// Verify the unit mapping was added
180197
assert_eq!(key_to_unit_map.get(&1), Some(&2)); // key index 1 maps to unit index 2
181198
}
182199

183200
#[test]
184201
fn test_convert_numeric_label_without_unit_mapping() {
185202
let string_table = vec![
186-
"".to_string(), // index 0
187-
"counter".to_string(), // index 1
203+
"".to_string(), // index 0
204+
"counter".to_string(), // index 1
188205
];
189-
206+
190207
let label = InternalLabel::num(
191208
StringId::from_offset(1), // "counter"
192-
42, // 42
209+
42, // 42
193210
StringId::from_offset(0), // empty string (default)
194211
);
195-
212+
196213
let mut key_to_unit_map = HashMap::new();
197214
let result = convert_label_to_key_value(&label, &string_table, &mut key_to_unit_map);
198215
assert!(result.is_ok());
199-
216+
200217
// Verify the KeyValue conversion
201218
let key_value = result.unwrap();
202219
assert_eq!(key_value.key, "counter");
@@ -206,7 +223,7 @@ mod tests {
206223
}
207224
_ => panic!("Expected IntValue"),
208225
}
209-
226+
210227
// Verify no unit mapping was added for default empty string
211228
assert!(key_to_unit_map.is_empty());
212229
}

datadog-profiling/src/internal/profile/otel_emitter/location.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ use crate::internal::Location as InternalLocation;
77
impl From<&InternalLocation> for datadog_profiling_otel::Location {
88
fn from(internal_location: &InternalLocation) -> Self {
99
Self {
10-
mapping_index: internal_location.mapping_id
10+
mapping_index: internal_location
11+
.mapping_id
1112
.map(|id| id.to_raw_id() as i32)
1213
.unwrap_or(0), // 0 represents no mapping
1314
address: internal_location.address,
@@ -16,7 +17,7 @@ impl From<&InternalLocation> for datadog_profiling_otel::Location {
1617
line: internal_location.line,
1718
column: 0, // Not available in internal Location
1819
}],
19-
is_folded: false, // Not available in internal Location
20+
is_folded: false, // Not available in internal Location
2021
attribute_indices: vec![], // Not available in internal Location
2122
}
2223
}

0 commit comments

Comments
 (0)