servers/otlp/trace/
attributes.rs

1// Copyright 2023 Greptime Team
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::fmt::Display;
16
17use opentelemetry_proto::tonic::common::v1::any_value::Value::{
18    ArrayValue, BoolValue, BytesValue, DoubleValue, IntValue, KvlistValue, StringValue,
19};
20use opentelemetry_proto::tonic::common::v1::{AnyValue, KeyValue};
21use serde::ser::{SerializeMap, SerializeSeq};
22use serde::Serialize;
23
24use crate::otlp::utils::key_value_to_jsonb;
25
26#[derive(Clone, Debug)]
27pub struct OtlpAnyValue<'a>(&'a AnyValue);
28
29impl<'a> From<&'a AnyValue> for OtlpAnyValue<'a> {
30    fn from(any_val: &'a AnyValue) -> Self {
31        Self(any_val)
32    }
33}
34
35impl OtlpAnyValue<'_> {
36    pub fn none() -> Self {
37        Self(&AnyValue { value: None })
38    }
39}
40
41/// specialize Display when it's only a String
42impl Display for OtlpAnyValue<'_> {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        if let Some(StringValue(v)) = &self.0.value {
45            write!(f, "{v}")
46        } else {
47            write!(f, "{}", serde_json::to_string(self).unwrap_or_default())
48        }
49    }
50}
51
52impl Serialize for OtlpAnyValue<'_> {
53    fn serialize<S>(&self, zer: S) -> Result<S::Ok, S::Error>
54    where
55        S: serde::Serializer,
56    {
57        match &self.0.value {
58            Some(val) => match &val {
59                StringValue(v) => zer.serialize_str(v),
60                BoolValue(v) => zer.serialize_bool(*v),
61                IntValue(v) => zer.serialize_i64(*v),
62                DoubleValue(v) => zer.serialize_f64(*v),
63                ArrayValue(v) => {
64                    let mut seq = zer.serialize_seq(Some(v.values.len()))?;
65                    for val in &v.values {
66                        seq.serialize_element(&OtlpAnyValue::from(val))?;
67                    }
68                    seq.end()
69                }
70                KvlistValue(v) => {
71                    let mut map = zer.serialize_map(Some(v.values.len()))?;
72                    for kv in &v.values {
73                        match &kv.value {
74                            Some(val) => map.serialize_entry(&kv.key, &OtlpAnyValue::from(val))?,
75                            None => map.serialize_entry(&kv.key, &OtlpAnyValue::none())?,
76                        }
77                    }
78                    map.end()
79                }
80                BytesValue(v) => zer.serialize_bytes(v),
81            },
82            None => zer.serialize_none(),
83        }
84    }
85}
86
87#[derive(Debug, Clone)]
88pub struct Attributes(Vec<KeyValue>);
89
90impl Display for Attributes {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        write!(f, "{}", serde_json::to_string(self).unwrap_or_default())
93    }
94}
95
96impl Serialize for Attributes {
97    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
98    where
99        S: serde::Serializer,
100    {
101        let mut map = serializer.serialize_map(Some(self.0.len()))?;
102        for attr in &self.0 {
103            match &attr.value {
104                Some(val) => map.serialize_entry(&attr.key, &OtlpAnyValue::from(val))?,
105                None => map.serialize_entry(&attr.key, &OtlpAnyValue::none())?,
106            }
107        }
108        map.end()
109    }
110}
111
112impl From<Vec<KeyValue>> for Attributes {
113    fn from(attrs: Vec<KeyValue>) -> Self {
114        Self(attrs)
115    }
116}
117
118impl From<&[KeyValue]> for Attributes {
119    fn from(attrs: &[KeyValue]) -> Self {
120        Self(attrs.to_vec())
121    }
122}
123
124impl From<Attributes> for jsonb::Value<'static> {
125    fn from(attrs: Attributes) -> jsonb::Value<'static> {
126        key_value_to_jsonb(attrs.0)
127    }
128}
129
130impl Attributes {
131    pub fn take(self) -> Vec<KeyValue> {
132        self.0
133    }
134
135    pub fn get_ref(&self) -> &Vec<KeyValue> {
136        &self.0
137    }
138
139    pub fn get_mut(&mut self) -> &mut Vec<KeyValue> {
140        &mut self.0
141    }
142}
143
144#[cfg(test)]
145mod tests {
146    use opentelemetry_proto::tonic::common::v1::any_value::Value;
147    use opentelemetry_proto::tonic::common::v1::{AnyValue, ArrayValue, KeyValue, KeyValueList};
148
149    use crate::otlp::trace::attributes::{Attributes, OtlpAnyValue};
150
151    #[test]
152    fn test_null_value() {
153        let otlp_value = OtlpAnyValue::from(&AnyValue { value: None });
154        assert_eq!("null", serde_json::to_string(&otlp_value).unwrap())
155    }
156
157    #[test]
158    fn test_otlp_any_value_display() {
159        let values = vec![
160            (
161                "string value",
162                Value::StringValue(String::from("string value")),
163            ),
164            ("true", Value::BoolValue(true)),
165            ("1", Value::IntValue(1)),
166            ("1.1", Value::DoubleValue(1.1)),
167            ("[1,2,3]", Value::BytesValue(vec![1, 2, 3])),
168        ];
169
170        for (expect, val) in values {
171            let any_value = AnyValue { value: Some(val) };
172            let otlp_value = OtlpAnyValue::from(&any_value);
173            assert_eq!(expect, otlp_value.to_string());
174        }
175    }
176
177    #[test]
178    fn test_any_value_primitive_type_serialize() {
179        let values = vec![
180            (
181                r#""string value""#,
182                Value::StringValue(String::from("string value")),
183            ),
184            ("true", Value::BoolValue(true)),
185            ("1", Value::IntValue(1)),
186            ("1.1", Value::DoubleValue(1.1)),
187            ("[1,2,3]", Value::BytesValue(vec![1, 2, 3])),
188        ];
189
190        for (expect, val) in values {
191            let any_val = AnyValue { value: Some(val) };
192            let otlp_value = OtlpAnyValue::from(&any_val);
193            assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
194        }
195    }
196
197    #[test]
198    fn test_any_value_array_type_serialize() {
199        let values = vec![
200            ("[]", vec![]),
201            ("[null]", vec![AnyValue { value: None }]),
202            (
203                r#"["string1","string2","string3"]"#,
204                vec![
205                    AnyValue {
206                        value: Some(Value::StringValue(String::from("string1"))),
207                    },
208                    AnyValue {
209                        value: Some(Value::StringValue(String::from("string2"))),
210                    },
211                    AnyValue {
212                        value: Some(Value::StringValue(String::from("string3"))),
213                    },
214                ],
215            ),
216            (
217                "[1,2,3]",
218                vec![
219                    AnyValue {
220                        value: Some(Value::IntValue(1)),
221                    },
222                    AnyValue {
223                        value: Some(Value::IntValue(2)),
224                    },
225                    AnyValue {
226                        value: Some(Value::IntValue(3)),
227                    },
228                ],
229            ),
230            (
231                "[1.1,2.2,3.3]",
232                vec![
233                    AnyValue {
234                        value: Some(Value::DoubleValue(1.1)),
235                    },
236                    AnyValue {
237                        value: Some(Value::DoubleValue(2.2)),
238                    },
239                    AnyValue {
240                        value: Some(Value::DoubleValue(3.3)),
241                    },
242                ],
243            ),
244            (
245                "[true,false,true]",
246                vec![
247                    AnyValue {
248                        value: Some(Value::BoolValue(true)),
249                    },
250                    AnyValue {
251                        value: Some(Value::BoolValue(false)),
252                    },
253                    AnyValue {
254                        value: Some(Value::BoolValue(true)),
255                    },
256                ],
257            ),
258            (
259                r#"[1,1.1,"str_value",true,null]"#,
260                vec![
261                    AnyValue {
262                        value: Some(Value::IntValue(1)),
263                    },
264                    AnyValue {
265                        value: Some(Value::DoubleValue(1.1)),
266                    },
267                    AnyValue {
268                        value: Some(Value::StringValue("str_value".into())),
269                    },
270                    AnyValue {
271                        value: Some(Value::BoolValue(true)),
272                    },
273                    AnyValue { value: None },
274                ],
275            ),
276        ];
277
278        for (expect, values) in values {
279            let any_val = AnyValue {
280                value: Some(Value::ArrayValue(ArrayValue { values })),
281            };
282            let otlp_value = OtlpAnyValue::from(&any_val);
283            assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
284        }
285    }
286
287    #[test]
288    fn test_any_value_map_type_serialize() {
289        let cases = vec![
290            ("{}", vec![]),
291            (
292                r#"{"key1":null}"#,
293                vec![KeyValue {
294                    key: "key1".into(),
295                    value: None,
296                }],
297            ),
298            (
299                r#"{"key1":null}"#,
300                vec![KeyValue {
301                    key: "key1".into(),
302                    value: Some(AnyValue { value: None }),
303                }],
304            ),
305            (
306                r#"{"key1":"val1"}"#,
307                vec![KeyValue {
308                    key: "key1".into(),
309                    value: Some(AnyValue {
310                        value: Some(Value::StringValue(String::from("val1"))),
311                    }),
312                }],
313            ),
314        ];
315
316        for (expect, values) in cases {
317            let any_val = AnyValue {
318                value: Some(Value::KvlistValue(KeyValueList { values })),
319            };
320            let otlp_value = OtlpAnyValue::from(&any_val);
321            assert_eq!(expect, serde_json::to_string(&otlp_value).unwrap());
322        }
323    }
324
325    #[test]
326    fn test_attributes_serialize() {
327        let cases = vec![
328            ("{}", vec![]),
329            (
330                r#"{"key1":null}"#,
331                vec![KeyValue {
332                    key: "key1".into(),
333                    value: None,
334                }],
335            ),
336            (
337                r#"{"key1":null}"#,
338                vec![KeyValue {
339                    key: "key1".into(),
340                    value: Some(AnyValue { value: None }),
341                }],
342            ),
343            (
344                r#"{"key1":"val1"}"#,
345                vec![KeyValue {
346                    key: "key1".into(),
347                    value: Some(AnyValue {
348                        value: Some(Value::StringValue(String::from("val1"))),
349                    }),
350                }],
351            ),
352        ];
353
354        for (expect, values) in cases {
355            assert_eq!(expect, serde_json::to_string(&Attributes(values)).unwrap());
356        }
357    }
358}