Skip to content

Commit d526b14

Browse files
fix: stringify otel attributes of array types
1 parent 06293cc commit d526b14

File tree

2 files changed

+91
-48
lines changed

2 files changed

+91
-48
lines changed

src/otel/metrics.rs

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -193,25 +193,31 @@ fn flatten_histogram(histogram: &Histogram) -> Vec<Map<String, Value>> {
193193
Value::Number(data_point.count.into()),
194194
);
195195
insert_number_if_some(&mut data_point_json, "data_point_sum", &data_point.sum);
196+
let data_point_bucket_counts = Value::Array(
197+
data_point
198+
.bucket_counts
199+
.iter()
200+
.map(|&count| Value::Number(count.into()))
201+
.collect(),
202+
);
203+
let data_point_bucket_counts_string =
204+
serde_json::to_string(&data_point_bucket_counts).unwrap();
196205
data_point_json.insert(
197206
"data_point_bucket_counts".to_string(),
198-
Value::Array(
199-
data_point
200-
.bucket_counts
201-
.iter()
202-
.map(|&count| Value::Number(count.into()))
203-
.collect(),
204-
),
207+
Value::String(data_point_bucket_counts_string),
205208
);
209+
let data_point_explicit_bounds = Value::Array(
210+
data_point
211+
.explicit_bounds
212+
.iter()
213+
.map(|bound| Value::Number(serde_json::Number::from_f64(*bound).unwrap()))
214+
.collect(),
215+
);
216+
let data_point_explicit_bounds_string =
217+
serde_json::to_string(&data_point_explicit_bounds).unwrap();
206218
data_point_json.insert(
207219
"data_point_explicit_bounds".to_string(),
208-
Value::Array(
209-
data_point
210-
.explicit_bounds
211-
.iter()
212-
.map(|bound| Value::String(bound.to_string()))
213-
.collect(),
214-
),
220+
Value::String(data_point_explicit_bounds_string),
215221
);
216222
let exemplar_json = flatten_exemplar(&data_point.exemplars);
217223
for (key, value) in exemplar_json {

src/otel/otel_utils.rs

Lines changed: 71 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
*/
1818

1919
use chrono::DateTime;
20-
use opentelemetry_proto::tonic::common::v1::{any_value::Value as OtelValue, AnyValue, KeyValue};
20+
use opentelemetry_proto::tonic::common::v1::{
21+
any_value::Value as OtelValue, AnyValue, ArrayValue, KeyValue, KeyValueList,
22+
};
2123
use serde_json::{Map, Value};
2224

2325
// Value can be one of types - String, Bool, Int, Double, ArrayValue, AnyValue, KeyValueList, Byte
@@ -39,40 +41,17 @@ pub fn collect_json_from_value(key: &String, value: OtelValue) -> Map<String, Va
3941
}
4042
}
4143
OtelValue::ArrayValue(array_val) => {
42-
let values = &array_val.values;
43-
for value in values {
44-
let array_value_json = collect_json_from_anyvalue(key, value.clone());
45-
for key in array_value_json.keys() {
46-
value_json.insert(
47-
format!(
48-
"{}_{}",
49-
key.to_owned(),
50-
value_to_string(array_value_json[key].to_owned())
51-
),
52-
array_value_json[key].to_owned(),
53-
);
54-
}
55-
}
44+
let json_array_value = collect_json_from_array_value(array_val);
45+
// Convert the array to a JSON string
46+
let json_array_string = serde_json::to_string(&json_array_value).unwrap();
47+
// Insert the array into the result map
48+
value_json.insert(key.to_string(), Value::String(json_array_string));
5649
}
5750
OtelValue::KvlistValue(kv_list_val) => {
58-
for key_value in kv_list_val.values {
59-
let value = key_value.value;
60-
if value.is_some() {
61-
let value = value.unwrap();
62-
let key_value_json = collect_json_from_anyvalue(key, value.clone());
63-
64-
for key in key_value_json.keys() {
65-
value_json.insert(
66-
format!(
67-
"{}_{}_{}",
68-
key.to_owned(),
69-
key_value.key,
70-
value_to_string(key_value_json[key].to_owned())
71-
),
72-
key_value_json[key].to_owned(),
73-
);
74-
}
75-
}
51+
// Create a JSON object to store the key-value list
52+
let kv_object = collect_json_from_key_value_list(kv_list_val);
53+
for (key, value) in kv_object.iter() {
54+
value_json.insert(key.clone(), value.clone());
7655
}
7756
}
7857
OtelValue::BytesValue(bytes_val) => {
@@ -86,6 +65,52 @@ pub fn collect_json_from_value(key: &String, value: OtelValue) -> Map<String, Va
8665
value_json
8766
}
8867

68+
fn collect_json_from_array_value(array_value: ArrayValue) -> Value {
69+
let mut json_array = Vec::new();
70+
for value in array_value.values {
71+
if let Some(val) = &value.value {
72+
match val {
73+
OtelValue::StringValue(s) => json_array.push(Value::String(s.clone())),
74+
OtelValue::BoolValue(b) => json_array.push(Value::Bool(*b)),
75+
OtelValue::IntValue(i) => {
76+
json_array.push(Value::Number(serde_json::Number::from(*i)))
77+
}
78+
OtelValue::DoubleValue(d) => {
79+
if let Some(n) = serde_json::Number::from_f64(*d) {
80+
json_array.push(Value::Number(n));
81+
}
82+
}
83+
OtelValue::BytesValue(b) => {
84+
json_array.push(Value::String(String::from_utf8_lossy(b).to_string()));
85+
}
86+
OtelValue::ArrayValue(arr) => {
87+
// Recursively collect JSON from nested array values
88+
let nested_json = collect_json_from_array_value(arr.clone());
89+
json_array.push(nested_json);
90+
}
91+
OtelValue::KvlistValue(kv_list) => {
92+
// Recursively collect JSON from nested key-value lists
93+
let nested_json = collect_json_from_key_value_list(kv_list.clone());
94+
json_array.push(Value::Object(nested_json));
95+
}
96+
}
97+
}
98+
}
99+
Value::Array(json_array)
100+
}
101+
102+
fn collect_json_from_key_value_list(key_value_list: KeyValueList) -> Map<String, Value> {
103+
let mut kv_list_json: Map<String, Value> = Map::new();
104+
for key_value in key_value_list.values {
105+
if let Some(val) = key_value.value {
106+
let val = val.value.unwrap();
107+
let json_value = collect_json_from_value(&key_value.key, val);
108+
kv_list_json.extend(json_value);
109+
}
110+
}
111+
kv_list_json
112+
}
113+
89114
pub fn collect_json_from_anyvalue(key: &String, value: AnyValue) -> Map<String, Value> {
90115
collect_json_from_value(key, value.value.unwrap())
91116
}
@@ -142,11 +167,23 @@ pub fn insert_bool_if_some(map: &mut Map<String, Value>, key: &str, option: &Opt
142167
}
143168
}
144169

145-
pub fn insert_attributes(map: &mut Map<String, Value>, attributes: &Vec<KeyValue>) {
170+
pub fn insert_attributes(
171+
map: &mut Map<String, Value>,
172+
attributes: &Vec<KeyValue>,
173+
) -> Map<String, Value> {
146174
let attributes_json = flatten_attributes(attributes);
147175
for (key, value) in attributes_json {
148176
map.insert(key, value);
149177
}
178+
179+
let attributes_map = map.clone();
180+
if attributes_map.contains_key("process.command_args") {
181+
println!(
182+
"attributes value in attributes_map: {:?}",
183+
attributes_map["process.command_args"]
184+
);
185+
}
186+
attributes_map
150187
}
151188

152189
pub fn convert_epoch_nano_to_timestamp(epoch_ns: i64) -> String {

0 commit comments

Comments
 (0)