opentelemetry_otlp/exporter/http/
metrics.rs

1use std::sync::Arc;
2
3use crate::metric::MetricsClient;
4use async_trait::async_trait;
5use http::{header::CONTENT_TYPE, Method};
6use opentelemetry::otel_debug;
7use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
8use opentelemetry_sdk::metrics::data::ResourceMetrics;
9
10use super::OtlpHttpClient;
11
12#[async_trait]
13impl MetricsClient for OtlpHttpClient {
14    async fn export(&self, metrics: &mut ResourceMetrics) -> OTelSdkResult {
15        let client = self
16            .client
17            .lock()
18            .map_err(|e| OTelSdkError::InternalFailure(format!("Failed to acquire lock: {e:?}")))
19            .and_then(|g| match &*g {
20                Some(client) => Ok(Arc::clone(client)),
21                _ => Err(OTelSdkError::AlreadyShutdown),
22            })?;
23
24        let (body, content_type) = self.build_metrics_export_body(metrics).map_err(|e| {
25            OTelSdkError::InternalFailure(format!("Failed to serialize metrics: {e:?}"))
26        })?;
27        let mut request = http::Request::builder()
28            .method(Method::POST)
29            .uri(&self.collector_endpoint)
30            .header(CONTENT_TYPE, content_type)
31            .body(body.into())
32            .map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
33
34        for (k, v) in &self.headers {
35            request.headers_mut().insert(k.clone(), v.clone());
36        }
37
38        otel_debug!(name: "HttpMetricsClient.CallingExport");
39        client
40            .send_bytes(request)
41            .await
42            .map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
43
44        Ok(())
45    }
46
47    fn shutdown(&self) -> OTelSdkResult {
48        self.client
49            .lock()
50            .map_err(|e| OTelSdkError::InternalFailure(format!("Failed to acquire lock: {}", e)))?
51            .take();
52
53        Ok(())
54    }
55}