From f9581f545f9205a6502eeeb6001c815e2c10a3ad Mon Sep 17 00:00:00 2001 From: Utkarsh Umesan Pillai <66651184+utpilla@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:05:26 -0800 Subject: [PATCH] Add internal logging for OTLP Exporter tonic client (#2415) --- opentelemetry-otlp/src/exporter/tonic/logs.rs | 5 ++ .../src/exporter/tonic/metrics.rs | 5 ++ opentelemetry-otlp/src/exporter/tonic/mod.rs | 53 ++++++++++++------- .../src/exporter/tonic/trace.rs | 6 ++- opentelemetry-otlp/src/logs.rs | 5 +- opentelemetry-otlp/src/metric.rs | 1 + opentelemetry-otlp/src/span.rs | 1 + 7 files changed, 56 insertions(+), 20 deletions(-) diff --git a/opentelemetry-otlp/src/exporter/tonic/logs.rs b/opentelemetry-otlp/src/exporter/tonic/logs.rs index f0b52abf1b..2737c2bd99 100644 --- a/opentelemetry-otlp/src/exporter/tonic/logs.rs +++ b/opentelemetry-otlp/src/exporter/tonic/logs.rs @@ -1,5 +1,6 @@ use async_trait::async_trait; use core::fmt; +use opentelemetry::otel_debug; use opentelemetry_proto::tonic::collector::logs::v1::{ logs_service_client::LogsServiceClient, ExportLogsServiceRequest, }; @@ -43,6 +44,8 @@ impl TonicLogsClient { .accept_compressed(compression); } + otel_debug!(name: "TonicsLogsClientBuilt"); + TonicLogsClient { inner: Some(ClientInner { client, @@ -72,6 +75,8 @@ impl LogExporter for TonicLogsClient { let resource_logs = group_logs_by_resource_and_scope(batch, &self.resource); + otel_debug!(name: "TonicsLogsClient.CallingExport"); + client .export(Request::from_parts( metadata, diff --git a/opentelemetry-otlp/src/exporter/tonic/metrics.rs b/opentelemetry-otlp/src/exporter/tonic/metrics.rs index 4159222cd5..8a938885a3 100644 --- a/opentelemetry-otlp/src/exporter/tonic/metrics.rs +++ b/opentelemetry-otlp/src/exporter/tonic/metrics.rs @@ -2,6 +2,7 @@ use core::fmt; use std::sync::Mutex; use async_trait::async_trait; +use opentelemetry::otel_debug; use opentelemetry_proto::tonic::collector::metrics::v1::{ metrics_service_client::MetricsServiceClient, ExportMetricsServiceRequest, }; @@ -40,6 +41,8 @@ impl TonicMetricsClient { .accept_compressed(compression); } + otel_debug!(name: "TonicsMetricsClientBuilt"); + TonicMetricsClient { inner: Mutex::new(Some(ClientInner { client, @@ -72,6 +75,8 @@ impl MetricsClient for TonicMetricsClient { None => Err(MetricError::Other("exporter is already shut down".into())), })?; + otel_debug!(name: "TonicsMetricsClient.CallingExport"); + client .export(Request::from_parts( metadata, diff --git a/opentelemetry-otlp/src/exporter/tonic/mod.rs b/opentelemetry-otlp/src/exporter/tonic/mod.rs index f041eeee2d..99d2e8fa15 100644 --- a/opentelemetry-otlp/src/exporter/tonic/mod.rs +++ b/opentelemetry-otlp/src/exporter/tonic/mod.rs @@ -4,6 +4,7 @@ use std::str::FromStr; use std::time::Duration; use http::{HeaderMap, HeaderName, HeaderValue}; +use opentelemetry::otel_debug; use tonic::codec::CompressionEncoding; use tonic::metadata::{KeyAndValueRef, MetadataMap}; use tonic::service::Interceptor; @@ -153,7 +154,7 @@ impl TonicExporterBuilder { ) -> Result<(Channel, BoxInterceptor, Option), crate::Error> { let compression = self.resolve_compression(signal_compression_var)?; - let headers_from_env = parse_headers_from_env(signal_headers_var); + let (headers_from_env, headers_for_logging) = parse_headers_from_env(signal_headers_var); let metadata = merge_metadata_with_headers_from_env( self.tonic_config.metadata.unwrap_or_default(), headers_from_env, @@ -190,6 +191,9 @@ impl TonicExporterBuilder { let endpoint = Self::resolve_endpoint(signal_endpoint_var, config.endpoint); + // Used for logging the endpoint + let endpoint_clone = endpoint.clone(); + let endpoint = Channel::from_shared(endpoint).map_err(crate::Error::from)?; let timeout = match env::var(signal_timeout_var) .ok() @@ -215,6 +219,7 @@ impl TonicExporterBuilder { #[cfg(not(feature = "tls"))] let channel = endpoint.timeout(timeout).connect_lazy(); + otel_debug!(name: "TonicChannelBuilt", endpoint = endpoint_clone, timeout_in_millisecs = timeout.as_millis(), compression = format!("{:?}", compression), headers = format!("{:?}", headers_for_logging)); Ok((channel, interceptor, compression)) } @@ -257,6 +262,8 @@ impl TonicExporterBuilder { ) -> Result { use crate::exporter::tonic::logs::TonicLogsClient; + otel_debug!(name: "LogsTonicChannelBuilding"); + let (channel, interceptor, compression) = self.build_channel( crate::logs::OTEL_EXPORTER_OTLP_LOGS_ENDPOINT, crate::logs::OTEL_EXPORTER_OTLP_LOGS_TIMEOUT, @@ -278,6 +285,8 @@ impl TonicExporterBuilder { use crate::MetricExporter; use metrics::TonicMetricsClient; + otel_debug!(name: "MetricsTonicChannelBuilding"); + let (channel, interceptor, compression) = self.build_channel( crate::metric::OTEL_EXPORTER_OTLP_METRICS_ENDPOINT, crate::metric::OTEL_EXPORTER_OTLP_METRICS_TIMEOUT, @@ -297,6 +306,8 @@ impl TonicExporterBuilder { ) -> Result { use crate::exporter::tonic::trace::TonicTracesClient; + otel_debug!(name: "TracesTonicChannelBuilding"); + let (channel, interceptor, compression) = self.build_channel( crate::span::OTEL_EXPORTER_OTLP_TRACES_ENDPOINT, crate::span::OTEL_EXPORTER_OTLP_TRACES_TIMEOUT, @@ -324,20 +335,26 @@ fn merge_metadata_with_headers_from_env( } } -fn parse_headers_from_env(signal_headers_var: &str) -> HeaderMap { - env::var(signal_headers_var) - .or_else(|_| env::var(OTEL_EXPORTER_OTLP_HEADERS)) - .map(|input| { - parse_header_string(&input) - .filter_map(|(key, value)| { - Some(( - HeaderName::from_str(key).ok()?, - HeaderValue::from_str(&value).ok()?, - )) - }) - .collect::() - }) - .unwrap_or_default() +fn parse_headers_from_env(signal_headers_var: &str) -> (HeaderMap, Vec<(String, String)>) { + let mut headers = Vec::new(); + + ( + env::var(signal_headers_var) + .or_else(|_| env::var(OTEL_EXPORTER_OTLP_HEADERS)) + .map(|input| { + parse_header_string(&input) + .filter_map(|(key, value)| { + headers.push((key.to_owned(), value.clone())); + Some(( + HeaderName::from_str(key).ok()?, + HeaderValue::from_str(&value).ok()?, + )) + }) + .collect::() + }) + .unwrap_or_default(), + headers, + ) } /// Expose interface for modifying [TonicConfig] fields within the exporter builders. @@ -516,7 +533,7 @@ mod tests { ], || { assert_eq!( - super::parse_headers_from_env(OTEL_EXPORTER_OTLP_TRACES_HEADERS), + super::parse_headers_from_env(OTEL_EXPORTER_OTLP_TRACES_HEADERS).0, HeaderMap::from_iter([ ( HeaderName::from_static("k1"), @@ -530,7 +547,7 @@ mod tests { ); assert_eq!( - super::parse_headers_from_env("EMPTY_ENV"), + super::parse_headers_from_env("EMPTY_ENV").0, HeaderMap::from_iter([( HeaderName::from_static("k3"), HeaderValue::from_static("v3") @@ -553,7 +570,7 @@ mod tests { metadata.insert("k1", "v0".parse().unwrap()); let result = - super::merge_metadata_with_headers_from_env(metadata, headers_from_env); + super::merge_metadata_with_headers_from_env(metadata, headers_from_env.0); assert_eq!( result.get("foo").unwrap(), diff --git a/opentelemetry-otlp/src/exporter/tonic/trace.rs b/opentelemetry-otlp/src/exporter/tonic/trace.rs index a4d12ebde7..998acafad5 100644 --- a/opentelemetry-otlp/src/exporter/tonic/trace.rs +++ b/opentelemetry-otlp/src/exporter/tonic/trace.rs @@ -1,7 +1,7 @@ use core::fmt; use futures_core::future::BoxFuture; -use opentelemetry::trace::TraceError; +use opentelemetry::{otel_debug, trace::TraceError}; use opentelemetry_proto::tonic::collector::trace::v1::{ trace_service_client::TraceServiceClient, ExportTraceServiceRequest, }; @@ -43,6 +43,8 @@ impl TonicTracesClient { .accept_compressed(compression); } + otel_debug!(name: "TonicsTracesClientBuilt"); + TonicTracesClient { inner: Some(ClientInner { client, @@ -74,6 +76,8 @@ impl SpanExporter for TonicTracesClient { let resource_spans = group_spans_by_resource_and_scope(batch, &self.resource); + otel_debug!(name: "TonicsTracesClient.CallingExport"); + Box::pin(async move { client .export(Request::from_parts( diff --git a/opentelemetry-otlp/src/logs.rs b/opentelemetry-otlp/src/logs.rs index 8ae10afb06..bb643cb095 100644 --- a/opentelemetry-otlp/src/logs.rs +++ b/opentelemetry-otlp/src/logs.rs @@ -3,6 +3,7 @@ //! Defines a [LogExporter] to send logs via the OpenTelemetry Protocol (OTLP) use async_trait::async_trait; +use opentelemetry::otel_debug; use std::fmt::Debug; use opentelemetry_sdk::logs::LogResult; @@ -63,7 +64,9 @@ impl LogExporterBuilder { #[cfg(feature = "grpc-tonic")] impl LogExporterBuilder { pub fn build(self) -> Result { - self.client.0.build_log_exporter() + let result = self.client.0.build_log_exporter(); + otel_debug!(name: "LogExporterBuilt", result = format!("{:?}", &result)); + result } } diff --git a/opentelemetry-otlp/src/metric.rs b/opentelemetry-otlp/src/metric.rs index d2ba22e4c0..c8bdb38d9e 100644 --- a/opentelemetry-otlp/src/metric.rs +++ b/opentelemetry-otlp/src/metric.rs @@ -78,6 +78,7 @@ impl MetricExporterBuilder { impl MetricExporterBuilder { pub fn build(self) -> MetricResult { let exporter = self.client.0.build_metrics_exporter(self.temporality)?; + opentelemetry::otel_debug!(name: "MetricExporterBuilt"); Ok(exporter) } } diff --git a/opentelemetry-otlp/src/span.rs b/opentelemetry-otlp/src/span.rs index 6cf40a3d99..190e3fdfce 100644 --- a/opentelemetry-otlp/src/span.rs +++ b/opentelemetry-otlp/src/span.rs @@ -64,6 +64,7 @@ impl SpanExporterBuilder { impl SpanExporterBuilder { pub fn build(self) -> Result { let span_exporter = self.client.0.build_span_exporter()?; + opentelemetry::otel_debug!(name: "SpanExporterBuilt"); Ok(SpanExporter::new(span_exporter)) } }