opentelemetry_otlp/exporter/http/
metrics.rs1use 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}