opentelemetry_otlp/exporter/http/
logs.rs

1use super::OtlpHttpClient;
2use http::header::CONTENT_ENCODING;
3use http::{header::CONTENT_TYPE, Method};
4use opentelemetry::otel_debug;
5use opentelemetry_sdk::error::{OTelSdkError, OTelSdkResult};
6use opentelemetry_sdk::logs::{LogBatch, LogExporter};
7use std::time;
8
9impl LogExporter for OtlpHttpClient {
10    async fn export(&self, batch: LogBatch<'_>) -> OTelSdkResult {
11        let client = self
12            .client
13            .lock()
14            .map_err(|e| OTelSdkError::InternalFailure(format!("Mutex lock failed: {e}")))?
15            .clone()
16            .ok_or(OTelSdkError::AlreadyShutdown)?;
17
18        let (body, content_type, content_encoding) = self
19            .build_logs_export_body(batch)
20            .map_err(OTelSdkError::InternalFailure)?;
21
22        let mut request_builder = http::Request::builder()
23            .method(Method::POST)
24            .uri(&self.collector_endpoint)
25            .header(CONTENT_TYPE, content_type);
26
27        if let Some(encoding) = content_encoding {
28            request_builder = request_builder.header(CONTENT_ENCODING, encoding);
29        }
30
31        let mut request = request_builder
32            .body(body.into())
33            .map_err(|e| OTelSdkError::InternalFailure(e.to_string()))?;
34
35        for (k, v) in &self.headers {
36            request.headers_mut().insert(k.clone(), v.clone());
37        }
38
39        let request_uri = request.uri().to_string();
40        otel_debug!(name: "HttpLogsClient.ExportStarted");
41        let response = client
42            .send_bytes(request)
43            .await
44            .map_err(|e| OTelSdkError::InternalFailure(format!("{e:?}")))?;
45
46        if !response.status().is_success() {
47            let error = format!(
48                "OpenTelemetry logs export failed. Url: {}, Status Code: {}, Response: {:?}",
49                request_uri,
50                response.status().as_u16(),
51                response.body()
52            );
53            otel_debug!(name: "HttpLogsClient.ExportFailed", error = &error);
54            return Err(OTelSdkError::InternalFailure(error));
55        }
56
57        otel_debug!(name: "HttpLogsClient.ExportSucceeded");
58        Ok(())
59    }
60
61    fn shutdown_with_timeout(&self, _timeout: time::Duration) -> OTelSdkResult {
62        let mut client_guard = self.client.lock().map_err(|e| {
63            OTelSdkError::InternalFailure(format!("Failed to acquire client lock: {e}"))
64        })?;
65
66        if client_guard.take().is_none() {
67            return Err(OTelSdkError::AlreadyShutdown);
68        }
69
70        Ok(())
71    }
72
73    fn set_resource(&mut self, resource: &opentelemetry_sdk::Resource) {
74        self.resource = resource.into();
75    }
76}