@@ -8,14 +8,23 @@ use crate::iter::{IntoLendingIterator, LendingIterator};
8
8
use anyhow:: { Context , Result } ;
9
9
use std:: collections:: HashMap ;
10
10
11
- impl TryFrom < InternalProfile > for datadog_profiling_otel:: ProfilesData {
12
- type Error = anyhow:: Error ;
13
-
14
- fn try_from ( mut internal_profile : InternalProfile ) -> Result < Self > {
11
+ impl InternalProfile {
12
+ /// Serializes the profile into OpenTelemetry format
13
+ ///
14
+ /// * `end_time` - Optional end time of the profile. Passing None will use the current time.
15
+ /// * `duration` - Optional duration of the profile. Passing None will try to calculate the
16
+ /// duration based on the end time minus the start time, but under anomalous conditions this
17
+ /// may fail as system clocks can be adjusted. The programmer may also accidentally pass an
18
+ /// earlier time. The duration will be set to zero these cases.
19
+ pub fn serialize_into_otel (
20
+ mut self ,
21
+ _end_time : Option < std:: time:: SystemTime > ,
22
+ _duration : Option < std:: time:: Duration > ,
23
+ ) -> anyhow:: Result < datadog_profiling_otel:: ProfilesData > {
15
24
// Create individual OpenTelemetry Profiles for each ValueType
16
- let mut profiles = Vec :: with_capacity ( internal_profile . sample_types . len ( ) ) ;
25
+ let mut profiles = Vec :: with_capacity ( self . sample_types . len ( ) ) ;
17
26
18
- for sample_type in internal_profile . sample_types . iter ( ) {
27
+ for sample_type in self . sample_types . iter ( ) {
19
28
// Convert the ValueType to OpenTelemetry format
20
29
let otel_sample_type = datadog_profiling_otel:: ValueType {
21
30
type_strindex : sample_type. r#type . value . to_raw_id ( ) as i32 ,
@@ -28,7 +37,7 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
28
37
let profile = datadog_profiling_otel:: Profile {
29
38
sample_type : Some ( otel_sample_type) ,
30
39
sample : vec ! [ ] , // TODO: Implement sample conversion
31
- time_nanos : internal_profile
40
+ time_nanos : self
32
41
. start_time
33
42
. duration_since ( std:: time:: UNIX_EPOCH )
34
43
. unwrap_or_default ( )
@@ -47,22 +56,18 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
47
56
profiles. push ( profile) ;
48
57
}
49
58
50
- for ( sample, timestamp, mut values) in
51
- std:: mem:: take ( & mut internal_profile. observations ) . into_iter ( )
52
- {
59
+ for ( sample, timestamp, mut values) in std:: mem:: take ( & mut self . observations ) . into_iter ( ) {
53
60
let stack_index = sample. stacktrace . to_raw_id ( ) as i32 ;
54
- let label_set = internal_profile . get_label_set ( sample. labels ) ?;
61
+ let label_set = self . get_label_set ( sample. labels ) ?;
55
62
let attribute_indicies: Vec < _ > =
56
63
label_set. iter ( ) . map ( |x| x. to_raw_id ( ) as i32 ) . collect ( ) ;
57
64
let labels = label_set
58
65
. iter ( )
59
- . map ( |l| internal_profile . get_label ( * l) . copied ( ) )
66
+ . map ( |l| self . get_label ( * l) . copied ( ) )
60
67
. collect :: < Result < Vec < _ > > > ( ) ?;
61
68
let link_index = 0 ; // TODO, handle links properly
62
69
let timestamps_unix_nano = timestamp. map_or ( vec ! [ ] , |ts| vec ! [ ts. get( ) as u64 ] ) ;
63
- internal_profile
64
- . upscaling_rules
65
- . upscale_values ( & mut values, & labels) ?;
70
+ self . upscaling_rules . upscale_values ( & mut values, & labels) ?;
66
71
67
72
for ( idx, value) in values. iter ( ) . enumerate ( ) {
68
73
if * value != 0 {
@@ -84,8 +89,8 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
84
89
// with lifetimes tied to the iterator itself, so we need to manually iterate and
85
90
// convert each string reference to an owned String.
86
91
let string_table = {
87
- let mut strings = Vec :: with_capacity ( internal_profile . strings . len ( ) ) ;
88
- let mut iter = internal_profile . strings . into_lending_iter ( ) ;
92
+ let mut strings = Vec :: with_capacity ( self . strings . len ( ) ) ;
93
+ let mut iter = self . strings . into_lending_iter ( ) ;
89
94
while let Some ( s) = iter. next ( ) {
90
95
strings. push ( s. to_string ( ) ) ;
91
96
}
@@ -94,9 +99,9 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
94
99
95
100
// Convert labels to KeyValues for the attribute table
96
101
let mut key_to_unit_map = HashMap :: new ( ) ;
97
- let mut attribute_table = Vec :: with_capacity ( internal_profile . labels . len ( ) ) ;
102
+ let mut attribute_table = Vec :: with_capacity ( self . labels . len ( ) ) ;
98
103
99
- for label in internal_profile . labels . iter ( ) {
104
+ for label in self . labels . iter ( ) {
100
105
let key_value = convert_label_to_key_value ( label, & string_table, & mut key_to_unit_map)
101
106
. with_context ( || {
102
107
format ! (
@@ -121,28 +126,24 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
121
126
// Convert the ProfilesDictionary components
122
127
let dictionary = datadog_profiling_otel:: ProfilesDictionary {
123
128
// Convert mappings
124
- mapping_table : internal_profile
125
- . mappings
126
- . iter ( )
127
- . map ( |mapping| mapping. into ( ) )
128
- . collect ( ) ,
129
+ mapping_table : self . mappings . iter ( ) . map ( |mapping| mapping. into ( ) ) . collect ( ) ,
129
130
130
131
// Convert locations
131
- location_table : internal_profile
132
+ location_table : self
132
133
. locations
133
134
. iter ( )
134
135
. map ( |location| location. into ( ) )
135
136
. collect ( ) ,
136
137
137
138
// Convert functions
138
- function_table : internal_profile
139
+ function_table : self
139
140
. functions
140
141
. iter ( )
141
142
. map ( |function| function. into ( ) )
142
143
. collect ( ) ,
143
144
144
145
// Convert stack traces
145
- stack_table : internal_profile
146
+ stack_table : self
146
147
. stack_traces
147
148
. iter ( )
148
149
. map ( |stack_trace| stack_trace. into ( ) )
@@ -168,7 +169,7 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
168
169
schema_url: String :: new( ) , // TODO: Implement when we handle schema URLs
169
170
} ] ;
170
171
171
- Ok ( Self {
172
+ Ok ( datadog_profiling_otel :: ProfilesData {
172
173
resource_profiles,
173
174
dictionary : Some ( dictionary) ,
174
175
} )
@@ -178,15 +179,14 @@ impl TryFrom<InternalProfile> for datadog_profiling_otel::ProfilesData {
178
179
#[ cfg( test) ]
179
180
mod tests {
180
181
use crate :: internal:: profile:: Profile as InternalProfile ;
181
- use datadog_profiling_otel:: ProfilesData ;
182
182
183
183
#[ test]
184
184
fn test_from_internal_profile_empty ( ) {
185
185
// Create an empty internal profile
186
186
let internal_profile = InternalProfile :: new ( & [ ] , None ) ;
187
187
188
188
// Convert to OpenTelemetry ProfilesData
189
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
189
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
190
190
191
191
// Verify the conversion
192
192
assert ! ( otel_profiles_data. dictionary. is_some( ) ) ;
@@ -225,7 +225,7 @@ mod tests {
225
225
let _function2_id = internal_profile. add_function ( & function2) ;
226
226
227
227
// Convert to OpenTelemetry ProfilesData
228
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
228
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
229
229
230
230
// Verify the conversion
231
231
assert ! ( otel_profiles_data. dictionary. is_some( ) ) ;
@@ -276,7 +276,7 @@ mod tests {
276
276
let _ = internal_profile. add_sample ( sample, None ) ;
277
277
278
278
// Convert to OpenTelemetry ProfilesData
279
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
279
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
280
280
281
281
// Verify the conversion
282
282
assert ! ( otel_profiles_data. dictionary. is_some( ) ) ;
@@ -326,7 +326,7 @@ mod tests {
326
326
let internal_profile = InternalProfile :: new ( & sample_types, None ) ;
327
327
328
328
// Convert to OpenTelemetry ProfilesData
329
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
329
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
330
330
331
331
// Verify that individual profiles are created for each sample type
332
332
assert_eq ! ( otel_profiles_data. resource_profiles. len( ) , 1 ) ;
@@ -400,7 +400,7 @@ mod tests {
400
400
let _ = internal_profile. add_sample ( sample, None ) ;
401
401
402
402
// Convert to OpenTelemetry ProfilesData
403
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
403
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
404
404
405
405
// Verify the conversion
406
406
assert ! ( otel_profiles_data. dictionary. is_some( ) ) ;
@@ -487,7 +487,7 @@ mod tests {
487
487
let _ = internal_profile. add_sample ( sample, None ) ;
488
488
489
489
// Convert to OpenTelemetry ProfilesData
490
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
490
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
491
491
492
492
// Verify the conversion
493
493
let _dictionary = otel_profiles_data. dictionary . unwrap ( ) ;
@@ -556,7 +556,7 @@ mod tests {
556
556
let _ = internal_profile. add_sample ( sample, Some ( timestamp) ) ;
557
557
558
558
// Convert to OpenTelemetry ProfilesData
559
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
559
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
560
560
561
561
// Verify the conversion
562
562
let profile = & otel_profiles_data. resource_profiles [ 0 ] . scope_profiles [ 0 ] . profiles [ 0 ] ;
@@ -616,7 +616,7 @@ mod tests {
616
616
let _ = internal_profile. add_sample ( sample, None ) ;
617
617
618
618
// Convert to OpenTelemetry ProfilesData
619
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
619
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
620
620
621
621
// Verify the conversion
622
622
let profile0 = & otel_profiles_data. resource_profiles [ 0 ] . scope_profiles [ 0 ] . profiles [ 0 ] ;
@@ -687,7 +687,7 @@ mod tests {
687
687
let _ = internal_profile. add_sample ( sample3, None ) ;
688
688
689
689
// Convert to OpenTelemetry ProfilesData
690
- let otel_profiles_data = ProfilesData :: try_from ( internal_profile) . unwrap ( ) ;
690
+ let otel_profiles_data = internal_profile. serialize_into_otel ( None , None ) . unwrap ( ) ;
691
691
692
692
// Verify the conversion
693
693
let profile = & otel_profiles_data. resource_profiles [ 0 ] . scope_profiles [ 0 ] . profiles [ 0 ] ;
0 commit comments