diff --git a/opentelemetry-otlp/Cargo.toml b/opentelemetry-otlp/Cargo.toml index 7d376365f1..d4fa3b5c46 100644 --- a/opentelemetry-otlp/Cargo.toml +++ b/opentelemetry-otlp/Cargo.toml @@ -97,11 +97,25 @@ http-proto = ["prost", "opentelemetry-http", "opentelemetry-proto/gen-tonic-mess experimental-http-retry = ["opentelemetry_sdk/experimental_async_runtime", "opentelemetry_sdk/rt-tokio", "tokio", "httpdate"] http-json = ["serde_json", "prost", "opentelemetry-http", "opentelemetry-proto/gen-tonic-messages", "opentelemetry-proto/with-serde", "http", "trace", "metrics"] + +# +# HTTP clients +# +# Most users should use the default reqwest-blocking-client. It is compatible +# with the SDK's default BatchSpanProcessor, BatchLogProcessor, and +# PeriodicReader, including applications that run on Tokio. reqwest-blocking-client = ["reqwest/blocking", "opentelemetry-http/reqwest-blocking"] + +# Async HTTP clients. Do not enable these for the default SDK +# processors/readers; they require an export path that is driven by a Tokio +# runtime, such as the experimental async-runtime processors/readers. reqwest-client = ["reqwest", "opentelemetry-http/reqwest"] +hyper-client = ["opentelemetry-http/hyper"] + +# TLS options for reqwest-based HTTP clients, both blocking and async. Combine +# these with either reqwest-blocking-client or reqwest-client. reqwest-rustls = ["reqwest", "opentelemetry-http/reqwest-rustls"] reqwest-rustls-webpki-roots = ["reqwest", "opentelemetry-http/reqwest-rustls-webpki-roots"] -hyper-client = ["opentelemetry-http/hyper"] # test integration-testing = ["tonic", "prost", "tokio/full", "trace", "logs"] diff --git a/opentelemetry-otlp/src/lib.rs b/opentelemetry-otlp/src/lib.rs index a78643b616..d0d3d751e5 100644 --- a/opentelemetry-otlp/src/lib.rs +++ b/opentelemetry-otlp/src/lib.rs @@ -287,7 +287,8 @@ //! * `gzip-http`: Use gzip compression for HTTP transport. //! * `zstd-http`: Use zstd compression for HTTP transport. //! * `reqwest-blocking-client`: Use reqwest blocking http client. This feature is enabled by default. -//! * `reqwest-client`: Use reqwest http client. +//! * `reqwest-client`: Use reqwest async http client. +//! * `hyper-client`: Use hyper async http client. //! * `reqwest-rustls`: Use reqwest with TLS with system trust roots via `rustls-native-certs` crate. //! * `reqwest-rustls-webpki-roots`: Use reqwest with TLS with Mozilla's trust roots via `webpki-roots` crate. //! @@ -510,6 +511,16 @@ //! enabled by default). Supply your own client to control TLS, proxies, connection pooling, etc. //! The client must implement the [`opentelemetry_http::HttpClient`] trait. //! +//! The standard SDK path uses the default `BatchSpanProcessor`, +//! `BatchLogProcessor`, and `PeriodicReader`. These components run exports on +//! SDK-owned background threads, so OTLP/HTTP should use the default +//! `reqwest-blocking-client` with them. +//! +//! HTTP client selection is based on enabled crate features and is not aware of +//! the SDK processor or metric reader that will drive the exporter. If you enable +//! async HTTP clients such as `reqwest-client` or `hyper-client`, do not use them +//! with the default batch processors or periodic reader. +//! //! ```no_run //! # #[cfg(all(feature = "trace", feature = "http-proto", feature = "reqwest-client"))] //! # { diff --git a/opentelemetry-sdk/src/logs/batch_log_processor.rs b/opentelemetry-sdk/src/logs/batch_log_processor.rs index 4a7775ab50..f4fb3daf2b 100644 --- a/opentelemetry-sdk/src/logs/batch_log_processor.rs +++ b/opentelemetry-sdk/src/logs/batch_log_processor.rs @@ -87,7 +87,12 @@ type LogsData = Box<(SdkLogRecord, InstrumentationScope)>; /// - `grpc-tonic`: Requires `LoggerProvider` to be created within a tokio runtime. /// - `reqwest-blocking-client`: Works with a regular `main` or `tokio::main`. /// -/// In other words, other clients like `reqwest` and `hyper` are not supported. +/// In other words, async HTTP clients like `reqwest-client` and `hyper-client` +/// are not supported by this default processor. The OTLP HTTP exporter chooses +/// its default HTTP client from enabled crate features and cannot tell which +/// processor will drive it. If your dependency graph enables async HTTP client +/// features, either pass an explicit blocking client for this processor or use +/// the experimental async-runtime batch log processor. /// /// `BatchLogProcessor` buffers logs in memory and exports them in batches. An /// export is triggered when `max_export_batch_size` is reached or every diff --git a/opentelemetry-sdk/src/metrics/periodic_reader.rs b/opentelemetry-sdk/src/metrics/periodic_reader.rs index 70e78f9253..b93702857e 100644 --- a/opentelemetry-sdk/src/metrics/periodic_reader.rs +++ b/opentelemetry-sdk/src/metrics/periodic_reader.rs @@ -90,6 +90,13 @@ where /// - **`grpc-tonic`**: Requires [`MeterProvider`] to be initialized within a `tokio` runtime. /// - **`reqwest-blocking-client`**: Works with both a standard (`main`) function and `tokio::main`. /// +/// Async HTTP clients such as `reqwest-client` and `hyper-client` are not +/// supported by this default reader. The OTLP HTTP exporter chooses its default +/// HTTP client from enabled crate features and cannot tell which reader will +/// drive it. If your dependency graph enables async HTTP client features, either +/// pass an explicit blocking client for this reader or use the experimental +/// async-runtime periodic reader. +/// /// [`PeriodicReader`] does **not** enforce a timeout for exports either. Instead, /// the configured exporter is responsible for enforcing timeouts. If an export operation /// never returns, [`PeriodicReader`] will **stop exporting new metrics**, stalling diff --git a/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs b/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs index 066db5b340..9e94701a69 100644 --- a/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs +++ b/opentelemetry-sdk/src/metrics/periodic_reader_with_async_runtime.rs @@ -162,7 +162,8 @@ where /// The [runtime] can be selected based on feature flags set for this crate. /// /// The exporter can be any exporter that implements [PushMetricExporter] such -/// as [opentelemetry-otlp]. +/// as [opentelemetry-otlp]. Exporters that require a runtime should be used +/// with a compatible [runtime]. /// /// [collect]: MetricReader::collect /// [runtime]: crate::runtime diff --git a/opentelemetry-sdk/src/trace/span_processor.rs b/opentelemetry-sdk/src/trace/span_processor.rs index 472b04de54..895c4fdb49 100644 --- a/opentelemetry-sdk/src/trace/span_processor.rs +++ b/opentelemetry-sdk/src/trace/span_processor.rs @@ -148,6 +148,11 @@ pub trait SpanProcessor: Send + Sync + std::fmt::Debug { /// spans must be emitted from a non-tokio runtime thread. /// - `reqwest-client`: TracerProvider may be created anywhere, but spans must be /// emitted from a tokio runtime thread. +/// +/// The OTLP HTTP exporter chooses its default HTTP client from enabled crate +/// features. That choice is not processor-aware. If you enable async HTTP +/// clients such as `reqwest-client` or `hyper-client`, ensure this processor is +/// only used from a thread where those clients can run. #[derive(Debug)] pub struct SimpleSpanProcessor { exporter: Mutex, @@ -222,8 +227,14 @@ impl SpanProcessor for SimpleSpanProcessor { /// runtime. /// - `reqwest-blocking-client`: Works with a regular `main` or `tokio::main`. /// -/// In other words, other clients like `reqwest` and `hyper` are not supported. -/// /// # Example +/// In other words, async HTTP clients like `reqwest-client` and `hyper-client` +/// are not supported by this default processor. The OTLP HTTP exporter chooses +/// its default HTTP client from enabled crate features and cannot tell which +/// processor will drive it. If your dependency graph enables async HTTP client +/// features, either pass an explicit blocking client for this processor or use +/// the experimental async-runtime batch span processor. +/// +/// # Example /// /// This example demonstrates how to configure and use the `BatchSpanProcessor` /// with a custom configuration. Note that a dedicated thread is used internally @@ -301,7 +312,12 @@ enum BatchMessage { /// - `grpc-tonic`: Requires `TracerProvider` to be created within a tokio runtime. /// - `reqwest-blocking-client`: Works with a regular `main` or `tokio::main`. /// -/// In other words, other clients like `reqwest` and `hyper` are not supported. +/// In other words, async HTTP clients like `reqwest-client` and `hyper-client` +/// are not supported by this default processor. The OTLP HTTP exporter chooses +/// its default HTTP client from enabled crate features and cannot tell which +/// processor will drive it. If your dependency graph enables async HTTP client +/// features, either pass an explicit blocking client for this processor or use +/// the experimental async-runtime batch span processor. /// /// `BatchSpanProcessor` buffers spans in memory and exports them in batches. An /// export is triggered when `max_export_batch_size` is reached or every