1use crate::wasi;
2use std::borrow::Cow;
3
4impl From<wasi::otel::metrics::ResourceMetrics>
5 for opentelemetry_sdk::metrics::data::ResourceMetrics
6{
7 fn from(value: wasi::otel::metrics::ResourceMetrics) -> Self {
8 Self {
9 resource: value.resource.into(),
10 scope_metrics: value.scope_metrics.into_iter().map(Into::into).collect(),
11 }
12 }
13}
14
15impl From<wasi::otel::metrics::Resource> for opentelemetry_sdk::Resource {
16 fn from(value: wasi::otel::metrics::Resource) -> Self {
17 let attributes: Vec<opentelemetry::KeyValue> =
18 value.attributes.into_iter().map(Into::into).collect();
19 let schema_url: Option<String> = value.schema_url;
20 match schema_url {
21 Some(url) => opentelemetry_sdk::resource::Resource::builder()
22 .with_schema_url(attributes, url)
23 .build(),
24 None => opentelemetry_sdk::resource::Resource::builder()
25 .with_attributes(attributes)
26 .build(),
27 }
28 }
29}
30
31impl From<wasi::otel::metrics::ScopeMetrics> for opentelemetry_sdk::metrics::data::ScopeMetrics {
32 fn from(value: wasi::otel::metrics::ScopeMetrics) -> Self {
33 Self {
34 scope: value.scope.into(),
35 metrics: value.metrics.into_iter().map(Into::into).collect(),
36 }
37 }
38}
39
40impl From<wasi::otel::metrics::Metric> for opentelemetry_sdk::metrics::data::Metric {
41 fn from(value: wasi::otel::metrics::Metric) -> Self {
42 Self {
43 name: Cow::Owned(value.name),
44 description: Cow::Owned(value.description),
45 unit: Cow::Owned(value.unit),
46 data: value.data.into(),
47 }
48 }
49}
50
51macro_rules! exemplars_to_otel {
53 (
54 $wasi_exemplar_list:expr,
55 $exemplar_type:ty
56 ) => {
57 $wasi_exemplar_list
58 .into_iter()
59 .map(|e| {
60 let span_id: [u8; 8] = e
61 .span_id
62 .as_bytes()
63 .try_into()
64 .expect("failed to parse span ID");
65 let trace_id: [u8; 16] = e
66 .trace_id
67 .as_bytes()
68 .try_into()
69 .expect("failed to parse trace ID");
70 opentelemetry_sdk::metrics::data::Exemplar::<$exemplar_type> {
71 filtered_attributes: e
72 .filtered_attributes
73 .into_iter()
74 .map(Into::into)
75 .collect(),
76 time: e.time.into(),
77 value: e.value.into(),
78 span_id,
79 trace_id,
80 }
81 })
82 .collect()
83 };
84}
85
86macro_rules! wasi_gauge_to_otel {
88 ($gauge:expr, $number_type:ty) => {
89 Box::new(opentelemetry_sdk::metrics::data::Gauge {
90 data_points: $gauge
91 .data_points
92 .into_iter()
93 .map(|dp| opentelemetry_sdk::metrics::data::GaugeDataPoint {
94 attributes: dp.attributes.into_iter().map(Into::into).collect(),
95 value: dp.value.into(),
96 exemplars: exemplars_to_otel!(dp.exemplars, $number_type),
97 })
98 .collect(),
99 start_time: match $gauge.start_time {
100 Some(t) => Some(t.into()),
101 None => None,
102 },
103 time: $gauge.time.into(),
104 })
105 };
106}
107
108macro_rules! wasi_sum_to_otel {
110 ($sum:expr, $number_type:ty) => {
111 Box::new(opentelemetry_sdk::metrics::data::Sum {
112 data_points: $sum
113 .data_points
114 .into_iter()
115 .map(|dp| opentelemetry_sdk::metrics::data::SumDataPoint {
116 attributes: dp.attributes.into_iter().map(Into::into).collect(),
117 exemplars: exemplars_to_otel!(dp.exemplars, $number_type),
118 value: dp.value.into(),
119 })
120 .collect(),
121 start_time: $sum.start_time.into(),
122 time: $sum.time.into(),
123 temporality: $sum.temporality.into(),
124 is_monotonic: $sum.is_monotonic,
125 })
126 };
127}
128
129macro_rules! wasi_histogram_to_otel {
131 ($histogram:expr, $number_type:ty) => {
132 Box::new(opentelemetry_sdk::metrics::data::Histogram {
133 data_points: $histogram
134 .data_points
135 .into_iter()
136 .map(|dp| opentelemetry_sdk::metrics::data::HistogramDataPoint {
137 attributes: dp.attributes.into_iter().map(Into::into).collect(),
138 bounds: dp.bounds,
139 bucket_counts: dp.bucket_counts,
140 exemplars: exemplars_to_otel!(dp.exemplars, $number_type),
141 count: dp.count,
142 max: match dp.max {
143 Some(m) => Some(m.into()),
144 None => None,
145 },
146 min: match dp.min {
147 Some(m) => Some(m.into()),
148 None => None,
149 },
150 sum: dp.sum.into(),
151 })
152 .collect(),
153 start_time: $histogram.start_time.into(),
154 time: $histogram.time.into(),
155 temporality: $histogram.temporality.into(),
156 })
157 };
158}
159
160macro_rules! wasi_exponential_histogram_to_otel {
162 ($histogram:expr, $number_type:ty) => {
163 Box::new(opentelemetry_sdk::metrics::data::ExponentialHistogram {
164 data_points: $histogram
165 .data_points
166 .into_iter()
167 .map(
168 |dp| opentelemetry_sdk::metrics::data::ExponentialHistogramDataPoint {
169 attributes: dp.attributes.into_iter().map(Into::into).collect(),
170 exemplars: exemplars_to_otel!(dp.exemplars, $number_type),
171 count: dp.count as usize,
172 max: match dp.max {
173 Some(m) => Some(m.into()),
174 None => None,
175 },
176 min: match dp.min {
177 Some(m) => Some(m.into()),
178 None => None,
179 },
180 sum: dp.sum.into(),
181 scale: dp.scale,
182 zero_count: dp.zero_count,
183 positive_bucket: dp.positive_bucket.into(),
184 negative_bucket: dp.negative_bucket.into(),
185 zero_threshold: dp.zero_threshold,
186 },
187 )
188 .collect(),
189 start_time: $histogram.start_time.into(),
190 time: $histogram.time.into(),
191 temporality: $histogram.temporality.into(),
192 })
193 };
194}
195
196impl From<wasi::otel::metrics::MetricData>
197 for Box<dyn opentelemetry_sdk::metrics::data::Aggregation>
198{
199 fn from(value: wasi::otel::metrics::MetricData) -> Self {
200 match value {
201 wasi::otel::metrics::MetricData::F64Sum(s) => wasi_sum_to_otel!(s, f64),
202 wasi::otel::metrics::MetricData::S64Sum(s) => wasi_sum_to_otel!(s, i64),
203 wasi::otel::metrics::MetricData::U64Sum(s) => wasi_sum_to_otel!(s, u64),
204 wasi::otel::metrics::MetricData::F64Gauge(g) => wasi_gauge_to_otel!(g, f64),
205 wasi::otel::metrics::MetricData::S64Gauge(g) => wasi_gauge_to_otel!(g, i64),
206 wasi::otel::metrics::MetricData::U64Gauge(g) => wasi_gauge_to_otel!(g, u64),
207 wasi::otel::metrics::MetricData::F64Histogram(h) => wasi_histogram_to_otel!(h, f64),
208 wasi::otel::metrics::MetricData::S64Histogram(h) => wasi_histogram_to_otel!(h, i64),
209 wasi::otel::metrics::MetricData::U64Histogram(h) => wasi_histogram_to_otel!(h, u64),
210 wasi::otel::metrics::MetricData::F64ExponentialHistogram(h) => {
211 wasi_exponential_histogram_to_otel!(h, f64)
212 }
213 wasi::otel::metrics::MetricData::S64ExponentialHistogram(h) => {
214 wasi_exponential_histogram_to_otel!(h, i64)
215 }
216 wasi::otel::metrics::MetricData::U64ExponentialHistogram(h) => {
217 wasi_exponential_histogram_to_otel!(h, u64)
218 }
219 }
220 }
221}
222
223impl From<wasi::otel::metrics::MetricNumber> for f64 {
224 fn from(value: wasi::otel::metrics::MetricNumber) -> Self {
225 match value {
226 wasi::otel::metrics::MetricNumber::F64(n) => n,
227 _ => panic!("error converting WASI MetricNumber to f64"),
228 }
229 }
230}
231
232impl From<wasi::otel::metrics::MetricNumber> for u64 {
233 fn from(value: wasi::otel::metrics::MetricNumber) -> Self {
234 match value {
235 wasi::otel::metrics::MetricNumber::U64(n) => n,
236 _ => panic!("error converting WASI MetricNumber to u64"),
237 }
238 }
239}
240
241impl From<wasi::otel::metrics::MetricNumber> for i64 {
242 fn from(value: wasi::otel::metrics::MetricNumber) -> Self {
243 match value {
244 wasi::otel::metrics::MetricNumber::S64(n) => n,
245 _ => panic!("error converting WASI MetricNumber to i64"),
246 }
247 }
248}
249
250impl From<wasi::otel::metrics::ExponentialBucket>
251 for opentelemetry_sdk::metrics::data::ExponentialBucket
252{
253 fn from(value: wasi::otel::metrics::ExponentialBucket) -> Self {
254 Self {
255 offset: value.offset,
256 counts: value.counts,
257 }
258 }
259}
260
261impl From<wasi::otel::metrics::Temporality> for opentelemetry_sdk::metrics::Temporality {
262 fn from(value: wasi::otel::metrics::Temporality) -> Self {
263 use opentelemetry_sdk::metrics::Temporality;
264 match value {
265 wasi::otel::metrics::Temporality::Cumulative => Temporality::Cumulative,
266 wasi::otel::metrics::Temporality::Delta => Temporality::Delta,
267 wasi::otel::metrics::Temporality::LowMemory => Temporality::LowMemory,
268 }
269 }
270}