opentelemetry_proto/
proto.rs

1/// provide serde support for proto traceIds and spanIds.
2/// Those are hex encoded strings in the jsons but they are byte arrays in the proto.
3/// See https://opentelemetry.io/docs/specs/otlp/#json-protobuf-encoding for more details
4#[cfg(all(feature = "with-serde", feature = "gen-tonic-messages"))]
5pub(crate) mod serializers {
6    use crate::tonic::common::v1::any_value::{self, Value};
7    use crate::tonic::common::v1::AnyValue;
8    use serde::de::{self, MapAccess, Visitor};
9    use serde::ser::SerializeStruct;
10    use serde::{Deserialize, Deserializer, Serialize, Serializer};
11    use std::fmt;
12
13    // hex string <-> bytes conversion
14
15    pub fn serialize_to_hex_string<S>(bytes: &[u8], serializer: S) -> Result<S::Ok, S::Error>
16    where
17        S: Serializer,
18    {
19        let hex_string = hex::encode(bytes);
20        serializer.serialize_str(&hex_string)
21    }
22
23    pub fn deserialize_from_hex_string<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error>
24    where
25        D: Deserializer<'de>,
26    {
27        struct BytesVisitor;
28
29        impl<'de> Visitor<'de> for BytesVisitor {
30            type Value = Vec<u8>;
31
32            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
33                formatter.write_str("a string representing hex-encoded bytes")
34            }
35
36            fn visit_str<E>(self, value: &str) -> Result<Vec<u8>, E>
37            where
38                E: de::Error,
39            {
40                hex::decode(value).map_err(E::custom)
41            }
42        }
43
44        deserializer.deserialize_str(BytesVisitor)
45    }
46
47    // AnyValue <-> KeyValue conversion
48    pub fn serialize_to_value<S>(value: &Option<AnyValue>, serializer: S) -> Result<S::Ok, S::Error>
49    where
50        S: Serializer,
51    {
52        match value {
53            Some(any_value) => match &any_value.value {
54                Some(Value::IntValue(i)) => {
55                    // Attempt to create a struct to wrap the intValue
56                    let mut state = match serializer.serialize_struct("Value", 1) {
57                        Ok(s) => s,
58                        Err(e) => return Err(e), // Handle the error or return it
59                    };
60    
61                    // Attempt to serialize the intValue field
62                    if let Err(e) = state.serialize_field("intValue", &i.to_string()) {
63                        return Err(e); // Handle the error or return it
64                    }
65    
66                    // Finalize the struct serialization
67                    state.end()
68                },
69                Some(value) => value.serialize(serializer),
70                None => serializer.serialize_none(),
71            },
72            None => serializer.serialize_none(),
73        }
74    }
75
76    pub fn deserialize_from_value<'de, D>(deserializer: D) -> Result<Option<AnyValue>, D::Error>
77where
78    D: Deserializer<'de>,
79{
80    struct ValueVisitor;
81
82    impl<'de> de::Visitor<'de> for ValueVisitor {
83        type Value = AnyValue;
84
85        fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
86            formatter.write_str("a JSON object for AnyValue")
87        }
88
89        fn visit_map<V>(self, mut map: V) -> Result<AnyValue, V::Error>
90        where
91            V: de::MapAccess<'de>,
92        {
93            let mut value: Option<any_value::Value> = None;
94
95            while let Some(key) = map.next_key::<String>()? {
96                let key_str = key.as_str();
97                match key_str {
98                    "stringValue" => {
99                        let s = map.next_value()?;
100                        value = Some(any_value::Value::StringValue(s));
101                    },
102                    "boolValue" => {
103                        let b = map.next_value()?;
104                        value = Some(any_value::Value::BoolValue(b));
105                    },
106                    "intValue" => {
107                        let value_str = map.next_value::<String>()?;
108                        let int_value = value_str.parse::<i64>()
109                            .map_err(de::Error::custom)?;
110                        value = Some(any_value::Value::IntValue(int_value));
111                    },
112                    "doubleValue" => {
113                        let d = map.next_value()?;
114                        value = Some(any_value::Value::DoubleValue(d));
115                    },
116                    "arrayValue" => {
117                        let a = map.next_value()?;
118                        value = Some(any_value::Value::ArrayValue(a));
119                    },
120                    "kvlistValue" => {
121                        let kv = map.next_value()?;
122                        value = Some(any_value::Value::KvlistValue(kv));
123                    },
124                    "bytesValue" => {
125                        let bytes = map.next_value()?;
126                        value = Some(any_value::Value::BytesValue(bytes));
127                    },
128                    _ => {
129                        //skip unknown keys, and handle error later.
130                        continue
131                    }
132                }
133            }
134
135            if let Some(v) = value {
136                Ok(AnyValue { value: Some(v) })
137            } else {
138                Err(de::Error::custom("Invalid data for AnyValue, no known keys found"))
139            }
140        }
141    }
142
143    let value = deserializer.deserialize_map(ValueVisitor)?;
144    Ok(Some(value))
145}
146    
147    pub fn serialize_u64_to_string<S>(value: &u64, serializer: S) -> Result<S::Ok, S::Error>
148    where
149        S: Serializer,
150    {
151        let s = value.to_string();
152        serializer.serialize_str(&s)
153    }
154
155    pub fn deserialize_string_to_u64<'de, D>(deserializer: D) -> Result<u64, D::Error>
156    where
157        D: Deserializer<'de>,
158    {
159        let s: String = Deserialize::deserialize(deserializer)?;
160        s.parse::<u64>().map_err(de::Error::custom)
161    }
162
163    pub fn serialize_i64_to_string<S>(value: &i64, serializer: S) -> Result<S::Ok, S::Error>
164    where
165        S: Serializer,
166    {
167        let s = value.to_string();
168        serializer.serialize_str(&s)
169    }
170    
171    pub fn deserialize_string_to_i64<'de, D>(deserializer: D) -> Result<i64, D::Error>
172    where
173        D: Deserializer<'de>,
174    {
175        let s: String = Deserialize::deserialize(deserializer)?;
176        s.parse::<i64>().map_err(de::Error::custom)
177    }
178}
179
180#[cfg(feature = "gen-tonic-messages")]
181#[path = "proto/tonic"]
182/// Generated files using [`tonic`](https://docs.rs/crate/tonic) and [`prost`](https://docs.rs/crate/prost)
183pub mod tonic {
184    /// Service stub and clients
185    #[path = ""]
186    pub mod collector {
187        #[cfg(feature = "logs")]
188        #[path = ""]
189        pub mod logs {
190            #[path = "opentelemetry.proto.collector.logs.v1.rs"]
191            pub mod v1;
192        }
193
194        #[cfg(feature = "metrics")]
195        #[path = ""]
196        pub mod metrics {
197            #[path = "opentelemetry.proto.collector.metrics.v1.rs"]
198            pub mod v1;
199        }
200
201        #[cfg(feature = "trace")]
202        #[path = ""]
203        pub mod trace {
204            #[path = "opentelemetry.proto.collector.trace.v1.rs"]
205            pub mod v1;
206        }
207    }
208
209    /// Common types used across all signals
210    #[path = ""]
211    pub mod common {
212        #[path = "opentelemetry.proto.common.v1.rs"]
213        pub mod v1;
214    }
215
216    /// Generated types used in logging.
217    #[cfg(feature = "logs")]
218    #[path = ""]
219    pub mod logs {
220        #[path = "opentelemetry.proto.logs.v1.rs"]
221        pub mod v1;
222    }
223
224    /// Generated types used in metrics.
225    #[cfg(feature = "metrics")]
226    #[path = ""]
227    pub mod metrics {
228        #[path = "opentelemetry.proto.metrics.v1.rs"]
229        pub mod v1;
230    }
231
232    /// Generated types used in resources.
233    #[path = ""]
234    pub mod resource {
235        #[path = "opentelemetry.proto.resource.v1.rs"]
236        pub mod v1;
237    }
238
239    /// Generated types used in traces.
240    #[cfg(feature = "trace")]
241    #[path = ""]
242    pub mod trace {
243        #[path = "opentelemetry.proto.trace.v1.rs"]
244        pub mod v1;
245    }
246
247    /// Generated types used in zpages.
248    #[cfg(feature = "zpages")]
249    #[path = ""]
250    pub mod tracez {
251        #[path = "opentelemetry.proto.tracez.v1.rs"]
252        pub mod v1;
253    }
254
255    pub use crate::transform::common::tonic::Attributes;
256}