Skip to content

Commit a81ad24

Browse files
lalitbcijothomas
andauthored
Enable reqwest and reqwest-blocking client creation with custom timeout (#2584)
Co-authored-by: Cijo Thomas <cijo.thomas@gmail.com>
1 parent 7c9447f commit a81ad24

File tree

2 files changed

+60
-52
lines changed

2 files changed

+60
-52
lines changed

opentelemetry-otlp/CHANGELOG.md

+9
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,15 @@
1313
- Remove unnecessarily public trait `opentelemetry_otlp::metrics::MetricsClient`
1414
and `MetricExporter::new(..)` method. Use
1515
`MetricExporter::builder()...build()` to obtain `MetricExporter`.
16+
- The HTTP clients (reqwest, reqwest-blocking, hyper) now support the
17+
timeout internal configured in below order
18+
- Signal specific env variable `OTEL_EXPORTER_OTLP_TRACES_TIMEOUT`,
19+
`OTEL_EXPORTER_OTLP_LOGS_TIMEOUT` or `OTEL_EXPORTER_OTLP_TIMEOUT`.
20+
- `OTEL_EXPORTER_OTLP_TIMEOUT` env variable.
21+
- `with_http().with_timeout()` API method of
22+
`LogExporterBuilder` and `SpanExporterBuilder` and `MetricsExporterBuilder`.
23+
- The default interval of 10sec is used if none is configured.
24+
1625

1726
## 0.27.0
1827

opentelemetry-otlp/src/exporter/http/mod.rs

+51-52
Original file line numberDiff line numberDiff line change
@@ -44,15 +44,7 @@ mod trace;
4444
use opentelemetry_http::hyper::HyperClient;
4545

4646
/// Configuration of the http transport
47-
#[derive(Debug)]
48-
#[cfg_attr(
49-
all(
50-
not(feature = "reqwest-client"),
51-
not(feature = "reqwest-blocking-client"),
52-
not(feature = "hyper-client")
53-
),
54-
derive(Default)
55-
)]
47+
#[derive(Debug, Default)]
5648
pub struct HttpConfig {
5749
/// Select the HTTP client
5850
client: Option<Arc<dyn HttpClient>>,
@@ -61,44 +53,6 @@ pub struct HttpConfig {
6153
headers: Option<HashMap<String, String>>,
6254
}
6355

64-
#[cfg(any(
65-
feature = "reqwest-blocking-client",
66-
feature = "reqwest-client",
67-
feature = "hyper-client"
68-
))]
69-
impl Default for HttpConfig {
70-
fn default() -> Self {
71-
#[cfg(feature = "reqwest-blocking-client")]
72-
let default_client = std::thread::spawn(|| {
73-
Some(Arc::new(reqwest::blocking::Client::new()) as Arc<dyn HttpClient>)
74-
})
75-
.join()
76-
.expect("creating reqwest::blocking::Client on a new thread not to fail");
77-
#[cfg(all(not(feature = "reqwest-blocking-client"), feature = "reqwest-client"))]
78-
let default_client = Some(Arc::new(reqwest::Client::new()) as Arc<dyn HttpClient>);
79-
#[cfg(all(
80-
not(feature = "reqwest-client"),
81-
not(feature = "reqwest-blocking-client"),
82-
feature = "hyper-client"
83-
))]
84-
// TODO - support configuring custom connector and executor
85-
let default_client = Some(Arc::new(HyperClient::with_default_connector(
86-
Duration::from_secs(10),
87-
None,
88-
)) as Arc<dyn HttpClient>);
89-
#[cfg(all(
90-
not(feature = "reqwest-client"),
91-
not(feature = "reqwest-blocking-client"),
92-
not(feature = "hyper-client")
93-
))]
94-
let default_client = None;
95-
HttpConfig {
96-
client: default_client,
97-
headers: None,
98-
}
99-
}
100-
}
101-
10256
/// Configuration for the OTLP HTTP exporter.
10357
///
10458
/// ## Examples
@@ -171,11 +125,56 @@ impl HttpExporterBuilder {
171125
},
172126
None => self.exporter_config.timeout,
173127
};
174-
let http_client = self
175-
.http_config
176-
.client
177-
.take()
178-
.ok_or(crate::Error::NoHttpClient)?;
128+
129+
#[allow(unused_mut)] // TODO - clippy thinks mut is not needed, but it is
130+
let mut http_client = self.http_config.client.take();
131+
132+
if http_client.is_none() {
133+
#[cfg(all(
134+
not(feature = "reqwest-client"),
135+
not(feature = "reqwest-blocking-client"),
136+
feature = "hyper-client"
137+
))]
138+
{
139+
// TODO - support configuring custom connector and executor
140+
http_client = Some(Arc::new(HyperClient::with_default_connector(timeout, None))
141+
as Arc<dyn HttpClient>);
142+
}
143+
#[cfg(all(
144+
not(feature = "hyper-client"),
145+
not(feature = "reqwest-blocking-client"),
146+
feature = "reqwest-client"
147+
))]
148+
{
149+
http_client = Some(Arc::new(
150+
reqwest::Client::builder()
151+
.timeout(timeout)
152+
.build()
153+
.unwrap_or_default(),
154+
) as Arc<dyn HttpClient>);
155+
}
156+
#[cfg(all(
157+
not(feature = "hyper-client"),
158+
not(feature = "reqwest-client"),
159+
feature = "reqwest-blocking-client"
160+
))]
161+
{
162+
let timeout_clone = timeout;
163+
http_client = Some(Arc::new(
164+
std::thread::spawn(move || {
165+
reqwest::blocking::Client::builder()
166+
.timeout(timeout_clone)
167+
.build()
168+
.unwrap_or_else(|_| reqwest::blocking::Client::new())
169+
})
170+
.join()
171+
.unwrap(), // Unwrap thread result
172+
) as Arc<dyn HttpClient>);
173+
}
174+
}
175+
176+
let http_client = http_client.ok_or(crate::Error::NoHttpClient)?;
177+
179178
#[allow(clippy::mutable_key_type)] // http headers are not mutated
180179
let mut headers: HashMap<HeaderName, HeaderValue> = self
181180
.http_config

0 commit comments

Comments
 (0)