1
1
// Copyright 2023-Present Datadog, Inc. https://www.datadoghq.com/
2
2
// SPDX-License-Identifier: Apache-2.0
3
3
4
+ //! All the mess here will go away once https://github.com/open-telemetry/opentelemetry-proto/pull/672/files is merged.
5
+
4
6
use crate :: collections:: identifiable:: Id ;
5
7
use crate :: internal:: Label as InternalLabel ;
6
- use anyhow:: { Result , Context } ;
8
+ use anyhow:: { Context , Result } ;
7
9
use std:: collections:: HashMap ;
8
10
9
11
/// Converts a datadog-profiling internal Label to an OpenTelemetry KeyValue
10
- ///
12
+ ///
11
13
/// # Arguments
12
14
/// * `label` - The internal label to convert
13
15
/// * `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
+ ///
16
19
/// # Returns
17
20
/// * `Ok(KeyValue)` if the conversion is successful
18
21
/// * `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(
25
28
let key_id = label. get_key ( ) . to_raw_id ( ) as usize ;
26
29
let key = string_table
27
30
. 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
+ } ) ?
29
38
. to_string ( ) ;
30
-
39
+
31
40
match label. get_value ( ) {
32
41
crate :: internal:: LabelValue :: Str ( str_id) => {
33
42
let str_value_id = str_id. to_raw_id ( ) as usize ;
34
43
let str_value = string_table
35
44
. 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
+ } ) ?
37
52
. to_string ( ) ;
38
-
53
+
39
54
Ok ( datadog_profiling_otel:: KeyValue {
40
55
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
+ ) ) ,
42
59
} )
43
60
}
44
61
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
47
64
let key_index = label. get_key ( ) . to_raw_id ( ) as usize ;
48
65
let unit_index = num_unit. to_raw_id ( ) as usize ;
49
-
66
+
50
67
// Only add to the map if the unit is not the default empty string (index 0)
51
68
if unit_index > 0 {
52
69
key_to_unit_map. insert ( key_index, unit_index) ;
53
70
}
54
-
71
+
55
72
Ok ( datadog_profiling_otel:: KeyValue {
56
73
key,
57
74
value : Some ( datadog_profiling_otel:: key_value:: Value :: IntValue ( * num) ) ,
@@ -68,20 +85,20 @@ mod tests {
68
85
#[ test]
69
86
fn test_convert_string_label ( ) {
70
87
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
74
91
] ;
75
-
92
+
76
93
let label = InternalLabel :: str (
77
94
StringId :: from_offset ( 1 ) , // "thread_id"
78
95
StringId :: from_offset ( 2 ) , // "main"
79
96
) ;
80
-
97
+
81
98
let mut key_to_unit_map = HashMap :: new ( ) ;
82
99
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
83
100
assert ! ( result. is_ok( ) ) ;
84
-
101
+
85
102
let key_value = result. unwrap ( ) ;
86
103
assert_eq ! ( key_value. key, "thread_id" ) ;
87
104
match key_value. value {
@@ -95,21 +112,21 @@ mod tests {
95
112
#[ test]
96
113
fn test_convert_numeric_label ( ) {
97
114
let string_table = vec ! [
98
- "" . to_string( ) , // index 0
115
+ "" . to_string( ) , // index 0
99
116
"allocation_size" . to_string( ) , // index 1
100
- "bytes" . to_string( ) , // index 2
117
+ "bytes" . to_string( ) , // index 2
101
118
] ;
102
-
119
+
103
120
let label = InternalLabel :: num (
104
121
StringId :: from_offset ( 1 ) , // "allocation_size"
105
122
1024 , // 1024 bytes
106
123
StringId :: from_offset ( 2 ) , // "bytes"
107
124
) ;
108
-
125
+
109
126
let mut key_to_unit_map = HashMap :: new ( ) ;
110
127
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
111
128
assert ! ( result. is_ok( ) ) ;
112
-
129
+
113
130
let key_value = result. unwrap ( ) ;
114
131
assert_eq ! ( key_value. key, "allocation_size" ) ;
115
132
match key_value. value {
@@ -123,12 +140,12 @@ mod tests {
123
140
#[ test]
124
141
fn test_convert_label_out_of_bounds ( ) {
125
142
let string_table = vec ! [ "" . to_string( ) ] ; // Only one string
126
-
143
+
127
144
let label = InternalLabel :: str (
128
145
StringId :: from_offset ( 1 ) , // This index doesn't exist
129
146
StringId :: from_offset ( 0 ) , // This index exists
130
147
) ;
131
-
148
+
132
149
let mut key_to_unit_map = HashMap :: new ( ) ;
133
150
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
134
151
assert ! ( result. is_err( ) ) ;
@@ -137,12 +154,12 @@ mod tests {
137
154
#[ test]
138
155
fn test_convert_label_empty_string_table ( ) {
139
156
let string_table: Vec < String > = vec ! [ ] ;
140
-
157
+
141
158
let label = InternalLabel :: str (
142
159
StringId :: from_offset ( 0 ) , // Even index 0 is out of bounds
143
160
StringId :: from_offset ( 0 ) ,
144
161
) ;
145
-
162
+
146
163
let mut key_to_unit_map = HashMap :: new ( ) ;
147
164
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
148
165
assert ! ( result. is_err( ) ) ;
@@ -151,21 +168,21 @@ mod tests {
151
168
#[ test]
152
169
fn test_convert_numeric_label_with_unit_mapping ( ) {
153
170
let string_table = vec ! [
154
- "" . to_string( ) , // index 0
171
+ "" . to_string( ) , // index 0
155
172
"memory_usage" . to_string( ) , // index 1
156
- "megabytes" . to_string( ) , // index 2
173
+ "megabytes" . to_string( ) , // index 2
157
174
] ;
158
-
175
+
159
176
let label = InternalLabel :: num (
160
177
StringId :: from_offset ( 1 ) , // "memory_usage"
161
- 512 , // 512 MB
178
+ 512 , // 512 MB
162
179
StringId :: from_offset ( 2 ) , // "megabytes"
163
180
) ;
164
-
181
+
165
182
let mut key_to_unit_map = HashMap :: new ( ) ;
166
183
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
167
184
assert ! ( result. is_ok( ) ) ;
168
-
185
+
169
186
// Verify the KeyValue conversion
170
187
let key_value = result. unwrap ( ) ;
171
188
assert_eq ! ( key_value. key, "memory_usage" ) ;
@@ -175,28 +192,28 @@ mod tests {
175
192
}
176
193
_ => panic ! ( "Expected IntValue" ) ,
177
194
}
178
-
195
+
179
196
// Verify the unit mapping was added
180
197
assert_eq ! ( key_to_unit_map. get( & 1 ) , Some ( & 2 ) ) ; // key index 1 maps to unit index 2
181
198
}
182
199
183
200
#[ test]
184
201
fn test_convert_numeric_label_without_unit_mapping ( ) {
185
202
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
188
205
] ;
189
-
206
+
190
207
let label = InternalLabel :: num (
191
208
StringId :: from_offset ( 1 ) , // "counter"
192
- 42 , // 42
209
+ 42 , // 42
193
210
StringId :: from_offset ( 0 ) , // empty string (default)
194
211
) ;
195
-
212
+
196
213
let mut key_to_unit_map = HashMap :: new ( ) ;
197
214
let result = convert_label_to_key_value ( & label, & string_table, & mut key_to_unit_map) ;
198
215
assert ! ( result. is_ok( ) ) ;
199
-
216
+
200
217
// Verify the KeyValue conversion
201
218
let key_value = result. unwrap ( ) ;
202
219
assert_eq ! ( key_value. key, "counter" ) ;
@@ -206,7 +223,7 @@ mod tests {
206
223
}
207
224
_ => panic ! ( "Expected IntValue" ) ,
208
225
}
209
-
226
+
210
227
// Verify no unit mapping was added for default empty string
211
228
assert ! ( key_to_unit_map. is_empty( ) ) ;
212
229
}
0 commit comments