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 opentelemetry_sdk::{error::OTelSdkResult, logs::LogBatch};
8use std::fmt::Debug;
9use std::time;
10
11use crate::{ExporterBuildError, 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/// Builder for creating a new [LogExporter].
35#[derive(Debug, Default, Clone)]
36pub struct LogExporterBuilder<C> {
37    client: C,
38    endpoint: Option<String>,
39}
40
41impl LogExporterBuilder<NoExporterBuilderSet> {
42    /// Create a new [LogExporterBuilder] with default settings.
43    pub fn new() -> Self {
44        LogExporterBuilder::default()
45    }
46
47    /// With the gRPC Tonic transport.
48    #[cfg(feature = "grpc-tonic")]
49    pub fn with_tonic(self) -> LogExporterBuilder<TonicExporterBuilderSet> {
50        LogExporterBuilder {
51            client: TonicExporterBuilderSet(TonicExporterBuilder::default()),
52            endpoint: self.endpoint,
53        }
54    }
55
56    /// With the HTTP transport.
57    #[cfg(any(feature = "http-proto", feature = "http-json"))]
58    pub fn with_http(self) -> LogExporterBuilder<HttpExporterBuilderSet> {
59        LogExporterBuilder {
60            client: HttpExporterBuilderSet(HttpExporterBuilder::default()),
61            endpoint: self.endpoint,
62        }
63    }
64}
65
66#[cfg(feature = "grpc-tonic")]
67impl LogExporterBuilder<TonicExporterBuilderSet> {
68    /// Build the [LogExporter] with the gRPC Tonic transport.
69    pub fn build(self) -> Result<LogExporter, ExporterBuildError> {
70        let result = self.client.0.build_log_exporter();
71        otel_debug!(name: "LogExporterBuilt", result = format!("{:?}", &result));
72        result
73    }
74}
75
76#[cfg(any(feature = "http-proto", feature = "http-json"))]
77impl LogExporterBuilder<HttpExporterBuilderSet> {
78    /// Build the [LogExporter] with the HTTP transport.
79    pub fn build(self) -> Result<LogExporter, ExporterBuildError> {
80        self.client.0.build_log_exporter()
81    }
82}
83
84#[cfg(feature = "grpc-tonic")]
85impl HasExportConfig for LogExporterBuilder<TonicExporterBuilderSet> {
86    fn export_config(&mut self) -> &mut crate::ExportConfig {
87        &mut self.client.0.exporter_config
88    }
89}
90
91#[cfg(any(feature = "http-proto", feature = "http-json"))]
92impl HasExportConfig for LogExporterBuilder<HttpExporterBuilderSet> {
93    fn export_config(&mut self) -> &mut crate::ExportConfig {
94        &mut self.client.0.exporter_config
95    }
96}
97
98#[cfg(feature = "grpc-tonic")]
99impl HasTonicConfig for LogExporterBuilder<TonicExporterBuilderSet> {
100    fn tonic_config(&mut self) -> &mut crate::TonicConfig {
101        &mut self.client.0.tonic_config
102    }
103}
104
105#[cfg(any(feature = "http-proto", feature = "http-json"))]
106impl HasHttpConfig for LogExporterBuilder<HttpExporterBuilderSet> {
107    fn http_client_config(&mut self) -> &mut crate::exporter::http::HttpConfig {
108        &mut self.client.0.http_config
109    }
110}
111
112/// OTLP exporter that sends log data
113#[derive(Debug)]
114pub struct LogExporter {
115    client: SupportedTransportClient,
116}
117
118#[derive(Debug)]
119enum SupportedTransportClient {
120    #[cfg(feature = "grpc-tonic")]
121    Tonic(crate::exporter::tonic::logs::TonicLogsClient),
122    #[cfg(any(feature = "http-proto", feature = "http-json"))]
123    Http(crate::exporter::http::OtlpHttpClient),
124}
125
126impl LogExporter {
127    /// Obtain a builder to configure a [LogExporter].
128    pub fn builder() -> LogExporterBuilder<NoExporterBuilderSet> {
129        LogExporterBuilder::default()
130    }
131
132    #[cfg(any(feature = "http-proto", feature = "http-json"))]
133    pub(crate) fn from_http(client: crate::exporter::http::OtlpHttpClient) -> Self {
134        LogExporter {
135            client: SupportedTransportClient::Http(client),
136        }
137    }
138
139    #[cfg(feature = "grpc-tonic")]
140    pub(crate) fn from_tonic(client: crate::exporter::tonic::logs::TonicLogsClient) -> Self {
141        LogExporter {
142            client: SupportedTransportClient::Tonic(client),
143        }
144    }
145}
146
147impl opentelemetry_sdk::logs::LogExporter for LogExporter {
148    async fn export(&self, batch: LogBatch<'_>) -> OTelSdkResult {
149        match &self.client {
150            #[cfg(feature = "grpc-tonic")]
151            SupportedTransportClient::Tonic(client) => client.export(batch).await,
152            #[cfg(any(feature = "http-proto", feature = "http-json"))]
153            SupportedTransportClient::Http(client) => client.export(batch).await,
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
166    fn shutdown_with_timeout(&self, _timeout: time::Duration) -> OTelSdkResult {
167        match &self.client {
168            #[cfg(feature = "grpc-tonic")]
169            SupportedTransportClient::Tonic(client) => client.shutdown(),
170            #[cfg(any(feature = "http-proto", feature = "http-json"))]
171            SupportedTransportClient::Http(client) => client.shutdown(),
172        }
173    }
174}