@@ -25,7 +25,7 @@ use serde_json::{Map, Value};
2525/// Prefixes of attribute keys that should be preserved as individual fields in flattened output.
2626/// Other attributes will be collected in a separate JSON object under `other_attributes`.
2727const KNOWN_ATTRIBUTES_PREFIX : [ & str ; 6 ] = [ "http" , "url" , "service" , "os" , "host" , "telemetry" ] ;
28-
28+ pub const OTHER_ATTRIBUTES_KEY : & str = "other_attributes" ;
2929// Value can be one of types - String, Bool, Int, Double, ArrayValue, AnyValue, KeyValueList, Byte
3030pub fn collect_json_from_value ( key : & String , value : OtelValue ) -> Map < String , Value > {
3131 let mut value_json: Map < String , Value > = Map :: new ( ) ;
@@ -45,7 +45,7 @@ pub fn collect_json_from_value(key: &String, value: OtelValue) -> Map<String, Va
4545 }
4646 }
4747 OtelValue :: ArrayValue ( array_val) => {
48- let json_array_value = collect_json_from_array_value ( array_val) ;
48+ let json_array_value = collect_json_from_array_value ( & array_val) ;
4949 // Convert the array to a JSON string
5050 let json_array_string = match serde_json:: to_string ( & json_array_value) {
5151 Ok ( s) => s,
@@ -78,9 +78,9 @@ pub fn collect_json_from_value(key: &String, value: OtelValue) -> Map<String, Va
7878/// Recursively converts an ArrayValue into a JSON Value
7979/// This handles nested array values and key-value lists by recursively
8080/// converting them to JSON
81- fn collect_json_from_array_value ( array_value : ArrayValue ) -> Value {
81+ fn collect_json_from_array_value ( array_value : & ArrayValue ) -> Value {
8282 let mut json_array = Vec :: new ( ) ;
83- for value in array_value. values {
83+ for value in & array_value. values {
8484 if let Some ( val) = & value. value {
8585 match val {
8686 OtelValue :: StringValue ( s) => json_array. push ( Value :: String ( s. clone ( ) ) ) ,
@@ -98,7 +98,7 @@ fn collect_json_from_array_value(array_value: ArrayValue) -> Value {
9898 }
9999 OtelValue :: ArrayValue ( arr) => {
100100 // Recursively collect JSON from nested array values
101- let nested_json = collect_json_from_array_value ( arr. clone ( ) ) ;
101+ let nested_json = collect_json_from_array_value ( arr) ;
102102 json_array. push ( nested_json) ;
103103 }
104104 OtelValue :: KvlistValue ( kv_list) => {
@@ -162,14 +162,14 @@ pub fn flatten_attributes(
162162 let key = & attribute. key ;
163163 let value = & attribute. value ;
164164 let value_json = collect_json_from_values ( value, & key. to_string ( ) ) ;
165- for key in value_json. keys ( ) {
165+ for ( attr_key , attr_val ) in & value_json {
166166 if KNOWN_ATTRIBUTES_PREFIX
167167 . iter ( )
168- . any ( |prefix| key . starts_with ( prefix) )
168+ . any ( |prefix| attr_key . starts_with ( prefix) )
169169 {
170- attributes_json. insert ( key . to_owned ( ) , value_json [ key ] . to_owned ( ) ) ;
170+ attributes_json. insert ( attr_key . clone ( ) , attr_val . clone ( ) ) ;
171171 } else {
172- other_attributes_json. insert ( key . to_owned ( ) , value_json [ key ] . to_owned ( ) ) ;
172+ other_attributes_json. insert ( attr_key . clone ( ) , attr_val . clone ( ) ) ;
173173 }
174174 }
175175 }
@@ -219,46 +219,66 @@ pub fn merge_attributes_in_json(
219219 attributes : Map < String , Value > ,
220220 vec_json : & mut Vec < Map < String , Value > > ,
221221) {
222- if !attributes. is_empty ( ) {
223- for json in vec_json {
224- if let Some ( other_attrs) = json. get ( "other_attributes" ) {
225- if let Value :: String ( attrs_str) = other_attrs {
226- if let Ok ( mut existing_attrs) =
227- serde_json:: from_str :: < Map < String , Value > > ( attrs_str)
228- {
229- for ( key, value) in attributes. clone ( ) {
230- existing_attrs. insert ( key, value) ;
231- }
232- if let Ok ( merged_str) = serde_json:: to_string ( & existing_attrs) {
233- json. insert ( "other_attributes" . to_string ( ) , Value :: String ( merged_str) ) ;
234- }
235- } else if let Ok ( attrs_str) = serde_json:: to_string ( & attributes) {
236- json. insert ( "other_attributes" . to_string ( ) , Value :: String ( attrs_str) ) ;
237- }
238- } else if let Value :: Object ( existing_attrs) = other_attrs {
239- let mut merged_attrs = existing_attrs. clone ( ) ;
240- for ( key, value) in attributes. clone ( ) {
241- merged_attrs. insert ( key, value) ;
242- }
243- if let Ok ( merged_str) = serde_json:: to_string ( & merged_attrs) {
244- json. insert ( "other_attributes" . to_string ( ) , Value :: String ( merged_str) ) ;
245- }
246- }
247- } else if let Ok ( attrs_str) = serde_json:: to_string ( & attributes) {
248- json. insert ( "other_attributes" . to_string ( ) , Value :: String ( attrs_str) ) ;
222+ if attributes. is_empty ( ) {
223+ return ;
224+ }
225+
226+ for json in vec_json {
227+ let merged_attributes = match json. get ( OTHER_ATTRIBUTES_KEY ) {
228+ Some ( Value :: String ( attrs_str) ) => {
229+ merge_with_existing_attributes ( & attributes, attrs_str)
249230 }
231+ Some ( Value :: Object ( existing_attrs) ) => {
232+ merge_with_existing_object ( & attributes, existing_attrs)
233+ }
234+ _ => serialize_attributes ( & attributes) ,
235+ } ;
236+
237+ if let Some ( merged_str) = merged_attributes {
238+ json. insert ( OTHER_ATTRIBUTES_KEY . to_string ( ) , Value :: String ( merged_str) ) ;
250239 }
251240 }
252241}
253242
243+ /// Merge attributes with an existing JSON string of attributes
244+ fn merge_with_existing_attributes (
245+ attributes : & Map < String , Value > ,
246+ attrs_str : & str ,
247+ ) -> Option < String > {
248+ if let Ok ( mut existing_attrs) = serde_json:: from_str :: < Map < String , Value > > ( attrs_str) {
249+ for ( key, value) in attributes {
250+ existing_attrs. insert ( key. clone ( ) , value. clone ( ) ) ;
251+ }
252+ return serde_json:: to_string ( & existing_attrs) . ok ( ) ;
253+ }
254+ None
255+ }
256+
257+ /// Merge attributes with an existing JSON object of attributes
258+ fn merge_with_existing_object (
259+ attributes : & Map < String , Value > ,
260+ existing_attrs : & Map < String , Value > ,
261+ ) -> Option < String > {
262+ let mut merged_attrs = existing_attrs. clone ( ) ;
263+ for ( key, value) in attributes {
264+ merged_attrs. insert ( key. clone ( ) , value. clone ( ) ) ;
265+ }
266+ serde_json:: to_string ( & merged_attrs) . ok ( )
267+ }
268+
269+ /// Serialize attributes into a JSON string
270+ fn serialize_attributes ( attributes : & Map < String , Value > ) -> Option < String > {
271+ serde_json:: to_string ( attributes) . ok ( )
272+ }
273+
254274/// fetch `other_attributes` from array of JSON objects
255275/// and merge them into a single map
256276/// and return the merged map
257277pub fn fetch_attributes_from_json ( json_arr : & Vec < Map < String , Value > > ) -> Map < String , Value > {
258278 let mut merged_attributes = Map :: new ( ) ;
259279
260280 for json in json_arr {
261- if let Some ( Value :: String ( attrs_str) ) = json. get ( "other_attributes" ) {
281+ if let Some ( Value :: String ( attrs_str) ) = json. get ( OTHER_ATTRIBUTES_KEY ) {
262282 if let Ok ( attrs) = serde_json:: from_str :: < Map < String , Value > > ( attrs_str) {
263283 for ( key, value) in attrs {
264284 merged_attributes. insert ( key, value) ;
@@ -291,6 +311,6 @@ pub fn add_other_attributes_if_not_empty(
291311) {
292312 if !other_attributes. is_empty ( ) {
293313 let attrs_str = fetch_attributes_string ( other_attributes) ;
294- json. insert ( "other_attributes" . to_string ( ) , Value :: String ( attrs_str) ) ;
314+ json. insert ( OTHER_ATTRIBUTES_KEY . to_string ( ) , Value :: String ( attrs_str) ) ;
295315 }
296316}
0 commit comments