@@ -27,7 +27,7 @@ use serde_json::{Map, Value};
2727use super :: otel_utils:: convert_epoch_nano_to_timestamp;
2828use super :: otel_utils:: insert_attributes;
2929
30- pub const OTEL_TRACES_KNOWN_FIELD_LIST : [ & str ; 30 ] = [
30+ pub const OTEL_TRACES_KNOWN_FIELD_LIST : [ & str ; 32 ] = [
3131 "scope_name" ,
3232 "scope_version" ,
3333 "scope_schema_url" ,
@@ -43,8 +43,10 @@ pub const OTEL_TRACES_KNOWN_FIELD_LIST: [&str; 30] = [
4343 "span_kind_description" ,
4444 "span_start_time_unix_nano" ,
4545 "span_end_time_unix_nano" ,
46+ "span_duration_ms" ,
4647 "event_name" ,
4748 "event_time_unix_nano" ,
49+ "event_duration_ms" ,
4850 "event_dropped_attributes_count" ,
4951 "link_span_id" ,
5052 "link_trace_id" ,
@@ -169,7 +171,7 @@ pub fn flatten_otel_traces(message: &TracesData) -> Vec<Value> {
169171/// otel traces has json array of events
170172/// this function flattens the `Event` object
171173/// and returns a `Vec` of `Map` of the flattened json
172- fn flatten_events ( events : & [ Event ] ) -> Vec < Map < String , Value > > {
174+ fn flatten_events ( events : & [ Event ] , span_start_time_unix_nano : u64 ) -> Vec < Map < String , Value > > {
173175 events
174176 . iter ( )
175177 . map ( |event| {
@@ -181,6 +183,20 @@ fn flatten_events(events: &[Event]) -> Vec<Map<String, Value>> {
181183 ) ,
182184 ) ;
183185 event_json. insert ( "event_name" . to_string ( ) , Value :: String ( event. name . clone ( ) ) ) ;
186+
187+ // Calculate event duration in milliseconds from span start
188+ let duration_nanos = event
189+ . time_unix_nano
190+ . saturating_sub ( span_start_time_unix_nano) ;
191+ let duration_ms = duration_nanos as f64 / 1_000_000.0 ; // Convert nanoseconds to milliseconds
192+ event_json. insert (
193+ "event_duration_ms" . to_string ( ) ,
194+ Value :: Number (
195+ serde_json:: Number :: from_f64 ( duration_ms)
196+ . unwrap_or_else ( || serde_json:: Number :: from ( 0 ) ) ,
197+ ) ,
198+ ) ;
199+
184200 insert_attributes ( & mut event_json, & event. attributes ) ;
185201 event_json. insert (
186202 "event_dropped_attributes_count" . to_string ( ) ,
@@ -233,9 +249,9 @@ fn flatten_status(status: &Status) -> Map<String, Value> {
233249 Value :: Number ( status. code . into ( ) ) ,
234250 ) ;
235251 let description = match status. code {
236- 0 => "STATUS_CODE_UNSET " ,
237- 1 => "STATUS_CODE_OK " ,
238- 2 => "STATUS_CODE_ERROR " ,
252+ 0 => "UNSET " ,
253+ 1 => "OK " ,
254+ 2 => "ERROR " ,
239255 _ => "" ,
240256 } ;
241257 status_json. insert (
@@ -254,10 +270,10 @@ fn flatten_flags(flags: u32) -> Map<String, Value> {
254270 let mut flags_json = Map :: new ( ) ;
255271 flags_json. insert ( "span_flags" . to_string ( ) , Value :: Number ( flags. into ( ) ) ) ;
256272 let description = match flags {
257- 0 => "SPAN_FLAGS_DO_NOT_USE " ,
258- 255 => "SPAN_FLAGS_TRACE_FLAGS_MASK " ,
259- 256 => "SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK " ,
260- 512 => "SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK " ,
273+ 0 => "DO_NOT_USE " ,
274+ 255 => "TRACE_FLAGS_MASK " ,
275+ 256 => "CONTEXT_HAS_IS_REMOTE_MASK " ,
276+ 512 => "CONTEXT_IS_REMOTE_MASK " ,
261277 _ => "" ,
262278 } ;
263279 flags_json. insert (
@@ -276,12 +292,12 @@ fn flatten_kind(kind: i32) -> Map<String, Value> {
276292 let mut kind_json = Map :: new ( ) ;
277293 kind_json. insert ( "span_kind" . to_string ( ) , Value :: Number ( kind. into ( ) ) ) ;
278294 let description = match kind {
279- 0 => "SPAN_KIND_UNSPECIFIED " ,
280- 1 => "SPAN_KIND_INTERNAL " ,
281- 2 => "SPAN_KIND_SERVER " ,
282- 3 => "SPAN_KIND_CLIENT " ,
283- 4 => "SPAN_KIND_PRODUCER " ,
284- 5 => "SPAN_KIND_CONSUMER " ,
295+ 0 => "UNSPECIFIED " ,
296+ 1 => "INTERNAL " ,
297+ 2 => "SERVER " ,
298+ 3 => "CLIENT " ,
299+ 4 => "PRODUCER " ,
300+ 5 => "CONSUMER " ,
285301 _ => "" ,
286302 } ;
287303 kind_json. insert (
@@ -332,12 +348,26 @@ fn flatten_span_record(span_record: &Span) -> Vec<Map<String, Value>> {
332348 span_record. end_time_unix_nano as i64 ,
333349 ) ) ,
334350 ) ;
351+
352+ // Calculate span duration in milliseconds
353+ let duration_nanos = span_record
354+ . end_time_unix_nano
355+ . saturating_sub ( span_record. start_time_unix_nano ) ;
356+ let duration_ms = duration_nanos as f64 / 1_000_000.0 ; // Convert nanoseconds to milliseconds
357+ span_record_json. insert (
358+ "span_duration_ms" . to_string ( ) ,
359+ Value :: Number (
360+ serde_json:: Number :: from_f64 ( duration_ms)
361+ . unwrap_or_else ( || serde_json:: Number :: from ( 0 ) ) ,
362+ ) ,
363+ ) ;
364+
335365 insert_attributes ( & mut span_record_json, & span_record. attributes ) ;
336366 span_record_json. insert (
337367 "span_dropped_attributes_count" . to_string ( ) ,
338368 Value :: Number ( span_record. dropped_attributes_count . into ( ) ) ,
339369 ) ;
340- let events_json = flatten_events ( & span_record. events ) ;
370+ let events_json = flatten_events ( & span_record. events , span_record . start_time_unix_nano ) ;
341371 span_records_json. extend ( events_json) ;
342372 span_record_json. insert (
343373 "span_dropped_events_count" . to_string ( ) ,
@@ -414,9 +444,9 @@ mod tests {
414444 fn test_flatten_status_code_mapping ( ) {
415445 // Test that status codes are correctly mapped to descriptions
416446 let test_cases = vec ! [
417- ( 0 , "STATUS_CODE_UNSET " ) ,
418- ( 1 , "STATUS_CODE_OK " ) ,
419- ( 2 , "STATUS_CODE_ERROR " ) ,
447+ ( 0 , "UNSET " ) ,
448+ ( 1 , "OK " ) ,
449+ ( 2 , "ERROR " ) ,
420450 ( 999 , "" ) , // Unknown status code should return empty string
421451 ] ;
422452
@@ -451,12 +481,12 @@ mod tests {
451481 fn test_flatten_span_kind_mapping ( ) {
452482 // Test that span kinds are correctly mapped to descriptions
453483 let test_cases = vec ! [
454- ( 0 , "SPAN_KIND_UNSPECIFIED " ) ,
455- ( 1 , "SPAN_KIND_INTERNAL " ) ,
456- ( 2 , "SPAN_KIND_SERVER " ) ,
457- ( 3 , "SPAN_KIND_CLIENT " ) ,
458- ( 4 , "SPAN_KIND_PRODUCER " ) ,
459- ( 5 , "SPAN_KIND_CONSUMER " ) ,
484+ ( 0 , "UNSPECIFIED " ) ,
485+ ( 1 , "INTERNAL " ) ,
486+ ( 2 , "SERVER " ) ,
487+ ( 3 , "CLIENT " ) ,
488+ ( 4 , "PRODUCER " ) ,
489+ ( 5 , "CONSUMER " ) ,
460490 ( 999 , "" ) , // Unknown kind should return empty string
461491 ] ;
462492
@@ -481,10 +511,10 @@ mod tests {
481511 fn test_flatten_flags_mapping ( ) {
482512 // Test that flags are correctly mapped to descriptions
483513 let test_cases = vec ! [
484- ( 0 , "SPAN_FLAGS_DO_NOT_USE " ) ,
485- ( 255 , "SPAN_FLAGS_TRACE_FLAGS_MASK " ) ,
486- ( 256 , "SPAN_FLAGS_CONTEXT_HAS_IS_REMOTE_MASK " ) ,
487- ( 512 , "SPAN_FLAGS_CONTEXT_IS_REMOTE_MASK " ) ,
514+ ( 0 , "DO_NOT_USE " ) ,
515+ ( 255 , "TRACE_FLAGS_MASK " ) ,
516+ ( 256 , "CONTEXT_HAS_IS_REMOTE_MASK " ) ,
517+ ( 512 , "CONTEXT_IS_REMOTE_MASK " ) ,
488518 ( 999 , "" ) , // Unknown flag should return empty string
489519 ] ;
490520
@@ -523,7 +553,7 @@ mod tests {
523553 } ,
524554 ] ;
525555
526- let result = flatten_events ( & events) ;
556+ let result = flatten_events ( & events, 1640995200000000000 ) ;
527557
528558 assert_eq ! ( result. len( ) , 2 , "Should have two flattened events" ) ;
529559
@@ -656,7 +686,7 @@ mod tests {
656686 ) ;
657687 assert_eq ! (
658688 record. get( "span_kind_description" ) . unwrap( ) ,
659- & Value :: String ( "SPAN_KIND_SERVER " . to_string( ) ) ,
689+ & Value :: String ( "SERVER " . to_string( ) ) ,
660690 "All records should contain span kind description"
661691 ) ;
662692 assert ! (
@@ -897,7 +927,7 @@ mod tests {
897927 ) ;
898928 assert_eq ! (
899929 record. get( "span_kind_description" ) . unwrap( ) ,
900- & Value :: String ( "SPAN_KIND_CLIENT " . to_string( ) ) ,
930+ & Value :: String ( "CLIENT " . to_string( ) ) ,
901931 "Should contain span kind description"
902932 ) ;
903933 assert_eq ! (
@@ -907,7 +937,7 @@ mod tests {
907937 ) ;
908938 assert_eq ! (
909939 record. get( "span_status_description" ) . unwrap( ) ,
910- & Value :: String ( "STATUS_CODE_OK " . to_string( ) ) ,
940+ & Value :: String ( "OK " . to_string( ) ) ,
911941 "Should contain status description"
912942 ) ;
913943 }
@@ -934,12 +964,14 @@ mod tests {
934964 "event_name" ,
935965 "event_time_unix_nano" ,
936966 "event_dropped_attributes_count" ,
967+ "event_duration_ms" ,
937968 "link_span_id" ,
938969 "link_trace_id" ,
939970 "link_dropped_attributes_count" ,
940971 "span_dropped_events_count" ,
941972 "span_dropped_links_count" ,
942973 "span_dropped_attributes_count" ,
974+ "span_duration_ms" ,
943975 "span_trace_state" ,
944976 "span_flags" ,
945977 "span_flags_description" ,
0 commit comments