opentelemetry_otlp/
logs.rs

1//! OTLP - Log Exporter
2//!
3//! Defines a [LogExporter] to send logs via the OpenTelemetry Protocol (OTLP)
4
5#[cfg(feature = "grpc-tonic")]
6use opentelemetry::otel_debug;
7use std::fmt::Debug;
8
9use opentelemetry_sdk::{error::OTelSdkResult, logs::LogBatch};
10
11use crate::{HasExportConfig, NoExporterBuilderSet};
12
13#[cfg(feature = "grpc-tonic")]
14use crate::{HasTonicConfig, TonicExporterBuilder, TonicExporterBuilderSet};
15
16#[cfg(any(feature = "http-proto", feature = "http-json"))]
17use crate::{HasHttpConfig, HttpExporterBuilder, HttpExporterBuilderSet};
18
19/// Compression algorithm to use, defaults to none.
20pub const OTEL_EXPORTER_OTLP_LOGS_COMPRESSION: &str = "OTEL_EXPORTER_OTLP_LOGS_COMPRESSION";
21
22/// Target to which the exporter is going to send logs
23pub const OTEL_EXPORTER_OTLP_LOGS_ENDPOINT: &str = "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT";
24
25/// Maximum time the OTLP exporter will wait for each batch logs export.
26pub const OTEL_EXPORTER_OTLP_LOGS_TIMEOUT: &str = "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT";
27
28/// Key-value pairs to be used as headers associated with gRPC or HTTP requests
29/// for sending logs.
30/// Example: `k1=v1,k2=v2`
31/// Note: this is only supported for HTTP.
32pub const OTEL_EXPORTER_OTLP_LOGS_HEADERS: &str = "OTEL_EXPORTER_OTLP_LOGS_HEADERS";
33
34#[derive(Debug, Default, Clone)]
35pub struct LogExporterBuilder<C> {
36    client: C,
37    endpoint: Option<String>,
38}
39
40impl LogExporterBuilder<NoExporterBuilderSet> {
41    pub fn new() -> Self {
42        LogExporterBuilder::default()
43    }
44
45    #[cfg(feature = "grpc-tonic")]
46    pub fn with_tonic(self) -> LogExporterBuilder<TonicExporterBuilderSet> {
47        LogExporterBuilder {
48            client: TonicExporterBuilderSet(TonicExporterBuilder::default()),
49            endpoint: self.endpoint,
50        }
51    }
52
53    #[cfg(any(feature = "http-proto", feature = "http-json"))]
54    pub fn with_http(self) -> LogExporterBuilder<HttpExporterBuilderSet> {
55        LogExporterBuilder {
56            client: HttpExporterBuilderSet(HttpExporterBuilder::default()),
57            endpoint: self.endpoint,
58        }
59    }
60}
61
62#[cfg(feature = "grpc-tonic")]
63impl LogExporterBuilder<TonicExporterBuilderSet> {
64    pub fn build(self) -> Result<LogExporter, opentelemetry_sdk::logs::LogError> {
65        let result = self.client.0.build_log_exporter();
66        otel_debug!(name: "LogExporterBuilt", result = format!("{:?}", &result));
67        result
68    }
69}
70
71#[cfg(any(feature = "http-proto", feature = "http-json"))]
72impl LogExporterBuilder<HttpExporterBuilderSet> {
73    pub fn build(self) -> Result<LogExporter, opentelemetry_sdk::logs::LogError> {
74        self.client.0.build_log_exporter()
75    }
76}
77
78#[cfg(feature = "grpc-tonic")]
79impl HasExportConfig for LogExporterBuilder<TonicExporterBuilderSet> {
80    fn export_config(&mut self) -> &mut crate::ExportConfig {
81        &mut self.client.0.exporter_config
82    }
83}
84
85#[cfg(any(feature = "http-proto", feature = "http-json"))]
86impl HasExportConfig for LogExporterBuilder<HttpExporterBuilderSet> {
87    fn export_config(&mut self) -> &mut crate::ExportConfig {
88        &mut self.client.0.exporter_config
89    }
90}
91
92#[cfg(feature = "grpc-tonic")]
93impl HasTonicConfig for LogExporterBuilder<TonicExporterBuilderSet> {
94    fn tonic_config(&mut self) -> &mut crate::TonicConfig {
95        &mut self.client.0.tonic_config
96    }
97}
98
99#[cfg(any(feature = "http-proto", feature = "http-json"))]
100impl HasHttpConfig for LogExporterBuilder<HttpExporterBuilderSet> {
101    fn http_client_config(&mut self) -> &mut crate::exporter::http::HttpConfig {
102        &mut self.client.0.http_config
103    }
104}
105
106/// OTLP exporter that sends log data
107#[derive(Debug)]
108pub struct LogExporter {
109    client: SupportedTransportClient,
110}
111
112#[derive(Debug)]
113enum SupportedTransportClient {
114    #[cfg(feature = "grpc-tonic")]
115    Tonic(crate::exporter::tonic::logs::TonicLogsClient),
116    #[cfg(any(feature = "http-proto", feature = "http-json"))]
117    Http(crate::exporter::http::OtlpHttpClient),
118}
119
120impl LogExporter {
121    /// Obtain a builder to configure a [LogExporter].
122    pub fn builder() -> LogExporterBuilder<NoExporterBuilderSet> {
123        LogExporterBuilder::default()
124    }
125
126    #[cfg(any(feature = "http-proto", feature = "http-json"))]
127    pub(crate) fn from_http(client: crate::exporter::http::OtlpHttpClient) -> Self {
128        LogExporter {
129            client: SupportedTransportClient::Http(client),
130        }
131    }
132
133    #[cfg(feature = "grpc-tonic")]
134    pub(crate) fn from_tonic(client: crate::exporter::tonic::logs::TonicLogsClient) -> Self {
135        LogExporter {
136            client: SupportedTransportClient::Tonic(client),
137        }
138    }
139}
140
141impl opentelemetry_sdk::logs::LogExporter for LogExporter {
142    #[allow(clippy::manual_async_fn)]
143    fn export(
144        &self,
145        batch: LogBatch<'_>,
146    ) -> impl std::future::Future<Output = OTelSdkResult> + Send {
147        async move {
148            match &self.client {
149                #[cfg(feature = "grpc-tonic")]
150                SupportedTransportClient::Tonic(client) => client.export(batch).await,
151                #[cfg(any(feature = "http-proto", feature = "http-json"))]
152                SupportedTransportClient::Http(client) => client.export(batch).await,
153            }
154        }
155    }
156
157    fn set_resource(&mut self, resource: &opentelemetry_sdk::Resource) {
158        match &mut self.client {
159            #[cfg(feature = "grpc-tonic")]
160            SupportedTransportClient::Tonic(client) => client.set_resource(resource),
161            #[cfg(any(feature = "http-proto", feature = "http-json"))]
162            SupportedTransportClient::Http(client) => client.set_resource(resource),
163        }
164    }
165}