forked from mirror/reqwest-middleware
Include README in crate doctests and improve documentation (#8)
* chore: Improve docs and include some examples in doctestsreqwest-tracing-0.2
parent
e0b01383d6
commit
b8645f81eb
56
README.md
56
README.md
|
@ -8,11 +8,29 @@ to allow for client middleware chains.
|
||||||
[![CI](https://github.com/TrueLayer/reqwest-middleware/workflows/CI/badge.svg)](https://github.com/TrueLayer/reqwest-middleware/actions)
|
[![CI](https://github.com/TrueLayer/reqwest-middleware/workflows/CI/badge.svg)](https://github.com/TrueLayer/reqwest-middleware/actions)
|
||||||
[![Coverage Status](https://coveralls.io/repos/github/TrueLayer/reqwest-middleware/badge.svg?branch=main&t=YKhONc)](https://coveralls.io/github/TrueLayer/reqwest-middleware?branch=main)
|
[![Coverage Status](https://coveralls.io/repos/github/TrueLayer/reqwest-middleware/badge.svg?branch=main&t=YKhONc)](https://coveralls.io/github/TrueLayer/reqwest-middleware?branch=main)
|
||||||
|
|
||||||
|
This crate provides functionality for building and running middleware but no middleware
|
||||||
|
implementations. This repository also contains a couple of useful concrete middleware crates:
|
||||||
|
|
||||||
|
* [`reqwest-retry`](https://crates.io/crates/reqwest-retry): retry failed requests.
|
||||||
|
* [`reqwest-trcing`](https://crates.io/crates/reqwest-tracing):
|
||||||
|
[`tracing`](https://crates.io/crates/tracing) integration, optional opentelemetry support.
|
||||||
|
|
||||||
## Overview
|
## Overview
|
||||||
|
|
||||||
The `reqwest-middleware` client exposes the same interface as a plain `reqwest` client, but
|
The `reqwest-middleware` client exposes the same interface as a plain `reqwest` client, but
|
||||||
`ClientBuilder` exposes functionality to attach middleware:
|
`ClientBuilder` exposes functionality to attach middleware:
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# Cargo.toml
|
||||||
|
# ...
|
||||||
|
[dependencies]
|
||||||
|
reqwest = "0.11"
|
||||||
|
reqwest-middleware = "0.1.1"
|
||||||
|
reqwest-retry = "0.1.1"
|
||||||
|
reqwest-tracing = "0.1.2"
|
||||||
|
tokio = { version = "1.12.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
```
|
||||||
|
|
||||||
```rust
|
```rust
|
||||||
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
||||||
use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff};
|
use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff};
|
||||||
|
@ -20,35 +38,27 @@ use reqwest_tracing::TracingMiddleware;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
|
// Retry up to 3 times with increasing intervals between attempts.
|
||||||
let client = ClientBuilder::new(reqwest::Client::new())
|
let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
|
||||||
.with(TracingMiddleware)
|
let client = ClientBuilder::new(reqwest::Client::new())
|
||||||
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
|
// Trace HTTP requests. See the tracing crate to make use of these traces.
|
||||||
.build();
|
.with(TracingMiddleware)
|
||||||
run(client).await;
|
// Retry failed requests.
|
||||||
|
.with(RetryTransientMiddleware::new_with_policy(retry_policy))
|
||||||
|
.build();
|
||||||
|
run(client).await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run(client: ClientWithMiddleware) {
|
async fn run(client: ClientWithMiddleware) {
|
||||||
// free retries!
|
client
|
||||||
client
|
.get("https://truelayer.com")
|
||||||
.get("https://some-external-service.com")
|
.header("foo", "bar")
|
||||||
.header("foo", "bar")
|
.send()
|
||||||
.send()
|
.await
|
||||||
.await
|
.unwrap();
|
||||||
.unwrap();
|
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
## How to install
|
|
||||||
|
|
||||||
Add `reqwest-middleware` to your dependencies
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
# ...
|
|
||||||
reqwest-middleware = "0.1.0"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### License
|
#### License
|
||||||
|
|
||||||
<sup>
|
<sup>
|
||||||
|
|
|
@ -21,5 +21,8 @@ thiserror = "1"
|
||||||
truelayer-extensions = "0.1"
|
truelayer-extensions = "0.1"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
|
reqwest = "0.11"
|
||||||
|
reqwest-retry = { path = "../reqwest-retry" }
|
||||||
|
reqwest-tracing = { path = "../reqwest-tracing" }
|
||||||
wiremock = "0.5"
|
wiremock = "0.5"
|
||||||
tokio = { version = "1", features = ["macros"] }
|
tokio = { version = "1", features = ["macros", "rt-multi-thread"] }
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::middleware::{Middleware, Next};
|
||||||
|
|
||||||
/// A `ClientBuilder` is used to build a [`ClientWithMiddleware`].
|
/// A `ClientBuilder` is used to build a [`ClientWithMiddleware`].
|
||||||
///
|
///
|
||||||
/// [`ClientWithMiddleware`]: struct.ClientWithMiddleware.html
|
/// [`ClientWithMiddleware`]: crate::ClientWithMiddleware
|
||||||
pub struct ClientBuilder {
|
pub struct ClientBuilder {
|
||||||
client: Client,
|
client: Client,
|
||||||
middleware_stack: Vec<Arc<dyn Middleware>>,
|
middleware_stack: Vec<Arc<dyn Middleware>>,
|
||||||
|
@ -31,7 +31,7 @@ impl ClientBuilder {
|
||||||
///
|
///
|
||||||
/// If you need to keep a reference to the middleware after attaching, use [`with_arc`].
|
/// If you need to keep a reference to the middleware after attaching, use [`with_arc`].
|
||||||
///
|
///
|
||||||
/// [`with_arc`]: #method.with_arc
|
/// [`with_arc`]: Self::with_arc
|
||||||
pub fn with<M>(self, middleware: M) -> Self
|
pub fn with<M>(self, middleware: M) -> Self
|
||||||
where
|
where
|
||||||
M: Middleware,
|
M: Middleware,
|
||||||
|
@ -41,7 +41,7 @@ impl ClientBuilder {
|
||||||
|
|
||||||
/// Add middleware to the chain. [`with`] is more ergonomic if you don't need the `Arc`.
|
/// Add middleware to the chain. [`with`] is more ergonomic if you don't need the `Arc`.
|
||||||
///
|
///
|
||||||
/// [`with`]: #method.with
|
/// [`with`]: Self::with
|
||||||
pub fn with_arc(mut self, middleware: Arc<dyn Middleware>) -> Self {
|
pub fn with_arc(mut self, middleware: Arc<dyn Middleware>) -> Self {
|
||||||
self.middleware_stack.push(middleware);
|
self.middleware_stack.push(middleware);
|
||||||
self
|
self
|
||||||
|
@ -55,8 +55,6 @@ impl ClientBuilder {
|
||||||
|
|
||||||
/// `ClientWithMiddleware` is a wrapper around [`reqwest::Client`] which runs middleware on every
|
/// `ClientWithMiddleware` is a wrapper around [`reqwest::Client`] which runs middleware on every
|
||||||
/// request.
|
/// request.
|
||||||
///
|
|
||||||
/// [`reqwest::Client`]: https://docs.rs/reqwest/0.10.8/reqwest/struct.Client.html
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct ClientWithMiddleware {
|
pub struct ClientWithMiddleware {
|
||||||
inner: reqwest::Client,
|
inner: reqwest::Client,
|
||||||
|
@ -65,8 +63,6 @@ pub struct ClientWithMiddleware {
|
||||||
|
|
||||||
impl ClientWithMiddleware {
|
impl ClientWithMiddleware {
|
||||||
/// See [`ClientBuilder`] for a more ergonomic way to build `ClientWithMiddleware` instances.
|
/// See [`ClientBuilder`] for a more ergonomic way to build `ClientWithMiddleware` instances.
|
||||||
///
|
|
||||||
/// [`ClientBuilder`]: struct.ClientBuilder.html
|
|
||||||
pub fn new<T>(client: Client, middleware_stack: T) -> Self
|
pub fn new<T>(client: Client, middleware_stack: T) -> Self
|
||||||
where
|
where
|
||||||
T: Into<Box<[Arc<dyn Middleware>]>>,
|
T: Into<Box<[Arc<dyn Middleware>]>>,
|
||||||
|
@ -77,40 +73,37 @@ impl ClientWithMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [`Client::get`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.get)
|
/// See [`Client::get`]
|
||||||
pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn get<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::GET, url)
|
self.request(Method::GET, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [`Client::post`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.post)
|
/// See [`Client::post`]
|
||||||
pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn post<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::POST, url)
|
self.request(Method::POST, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [`Client::put`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.put)
|
/// See [`Client::put`]
|
||||||
pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn put<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::PUT, url)
|
self.request(Method::PUT, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See
|
/// See [`Client::patch`]
|
||||||
/// [`Client::patch`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.patch)
|
|
||||||
pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn patch<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::PATCH, url)
|
self.request(Method::PATCH, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See
|
/// See [`Client::delete`]
|
||||||
/// [`Client::delete`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.delete)
|
|
||||||
pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn delete<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::DELETE, url)
|
self.request(Method::DELETE, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See [`Client::head`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.head)
|
/// See [`Client::head`]
|
||||||
pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
pub fn head<U: IntoUrl>(&self, url: U) -> RequestBuilder {
|
||||||
self.request(Method::HEAD, url)
|
self.request(Method::HEAD, url)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See
|
/// See [`Client::request`]
|
||||||
/// [`Client::request`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.request)
|
|
||||||
pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
pub fn request<U: IntoUrl>(&self, method: Method, url: U) -> RequestBuilder {
|
||||||
RequestBuilder {
|
RequestBuilder {
|
||||||
inner: self.inner.request(method, url),
|
inner: self.inner.request(method, url),
|
||||||
|
@ -118,8 +111,7 @@ impl ClientWithMiddleware {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See
|
/// See [`Client::execute`]
|
||||||
/// [`Client::execute`](https://docs.rs/reqwest/latest/reqwest/struct.Client.html#method.execute)
|
|
||||||
pub async fn execute(&self, req: Request) -> Result<Response> {
|
pub async fn execute(&self, req: Request) -> Result<Response> {
|
||||||
let mut ext = Extensions::new();
|
let mut ext = Extensions::new();
|
||||||
self.execute_with_extensions(req, &mut ext).await
|
self.execute_with_extensions(req, &mut ext).await
|
||||||
|
@ -147,8 +139,6 @@ impl From<Client> for ClientWithMiddleware {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a wrapper around [`reqwest::RequestBuilder`] exposing the same API.
|
/// This is a wrapper around [`reqwest::RequestBuilder`] exposing the same API.
|
||||||
///
|
|
||||||
/// [`reqwest::RequestBuilder`]: https://docs.rs/reqwest/0.10.8/reqwest/struct.RequestBuilder.html
|
|
||||||
#[must_use = "RequestBuilder does nothing until you 'send' it"]
|
#[must_use = "RequestBuilder does nothing until you 'send' it"]
|
||||||
pub struct RequestBuilder {
|
pub struct RequestBuilder {
|
||||||
inner: reqwest::RequestBuilder,
|
inner: reqwest::RequestBuilder,
|
||||||
|
|
|
@ -37,11 +37,18 @@
|
||||||
//! }
|
//! }
|
||||||
//! ```
|
//! ```
|
||||||
//!
|
//!
|
||||||
//! [`build`]: struct.ClientBuilder.html#method.build
|
//! [`build`]: ClientBuilder::build
|
||||||
//! [`ClientBuilder`]: struct.ClientBuilder.html
|
//! [`ClientBuilder`]: ClientBuilder
|
||||||
//! [`ClientWithMiddleware`]: struct.ClientWithMiddleware.html
|
//! [`ClientWithMiddleware`]: ClientWithMiddleware
|
||||||
//! [`reqwest::Client`]: https://docs.rs/reqwest/0.10.8/reqwest/struct.Client.html
|
//! [`with`]: ClientBuilder::with
|
||||||
//! [`with`]: struct.ClientBuilder.html#method.with
|
|
||||||
|
// Test README examples without overriding module docs.
|
||||||
|
// We want to keep the in-code docs separate as those allow for automatic linking to crate
|
||||||
|
// documentation.
|
||||||
|
#[doc = include_str!("../../README.md")]
|
||||||
|
#[cfg(doctest)]
|
||||||
|
pub struct ReadmeDoctests;
|
||||||
|
|
||||||
mod client;
|
mod client;
|
||||||
mod error;
|
mod error;
|
||||||
mod middleware;
|
mod middleware;
|
||||||
|
|
|
@ -30,9 +30,8 @@ use crate::error::{Error, Result};
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
///
|
///
|
||||||
/// [`ClientWithMiddleware`]: struct.ClientWithMiddleware.html
|
/// [`ClientWithMiddleware`]: crate::ClientWithMiddleware
|
||||||
/// [`Extensions`]: TODO
|
/// [`with`]: crate::ClientBuilder::with
|
||||||
/// [`with`]: struct.ClientBuilder.html#method.with
|
|
||||||
#[async_trait::async_trait]
|
#[async_trait::async_trait]
|
||||||
pub trait Middleware: 'static + Send + Sync {
|
pub trait Middleware: 'static + Send + Sync {
|
||||||
/// Invoked with a request before sending it. If you want to continue processing the request,
|
/// Invoked with a request before sending it. If you want to continue processing the request,
|
||||||
|
@ -69,8 +68,8 @@ where
|
||||||
/// Next encapsulates the remaining middleware chain to run in [`Middleware::handle`]. You can
|
/// Next encapsulates the remaining middleware chain to run in [`Middleware::handle`]. You can
|
||||||
/// forward the request down the chain with [`run`].
|
/// forward the request down the chain with [`run`].
|
||||||
///
|
///
|
||||||
/// [`Middleware::handle`]: trait.Middleware.html#tymethod.handle
|
/// [`Middleware::handle`]: Middleware::handle
|
||||||
/// [`run`]: #method.run
|
/// [`run`]: Self::run
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Next<'a> {
|
pub struct Next<'a> {
|
||||||
client: &'a Client,
|
client: &'a Client,
|
||||||
|
|
|
@ -5,7 +5,8 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
||||||
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
- Re-export `RetryPolicy` from the crate root.
|
||||||
### Changed
|
### Changed
|
||||||
- Disabled default features on `reqwest`
|
- Disabled default features on `reqwest`
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,7 @@ Build `RetryTransientMiddleware` from a `RetryPolicy`, then attach it to a
|
||||||
[`retry-policies::policies`](https://crates.io/crates/retry-policies) is reexported under
|
[`retry-policies::policies`](https://crates.io/crates/retry-policies) is reexported under
|
||||||
`reqwest_retry::policies` for convenience.
|
`reqwest_retry::policies` for convenience.
|
||||||
|
|
||||||
## How to install
|
See [`reqwest_middleware`](https://docs.rs/reqwest_middleware) for usage with reqwest.
|
||||||
|
|
||||||
Add `reqwest-retry` to your dependencies
|
|
||||||
|
|
||||||
```toml
|
|
||||||
[dependencies]
|
|
||||||
# ...
|
|
||||||
reqwest-retry = "0.1.0"
|
|
||||||
```
|
|
||||||
|
|
||||||
#### License
|
#### License
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,34 @@
|
||||||
|
//! Middleware to retry failed HTTP requests built on [`reqwest_middleware`].
|
||||||
|
//!
|
||||||
|
//! Use [`RetryTransientMiddleware`] to retry failed HTTP requests. Retry control flow is managed
|
||||||
|
//! by a [`RetryPolicy`].
|
||||||
|
//!
|
||||||
|
//! ## Example
|
||||||
|
//!
|
||||||
|
//! ```
|
||||||
|
//! use reqwest_middleware::{ClientBuilder, ClientWithMiddleware};
|
||||||
|
//! use reqwest_retry::{RetryTransientMiddleware, policies::ExponentialBackoff};
|
||||||
|
//!
|
||||||
|
//! async fn run_retries() {
|
||||||
|
//! // Retry up to 3 times with increasing intervals between attempts.
|
||||||
|
//! let retry_policy = ExponentialBackoff::builder().build_with_max_retries(3);
|
||||||
|
//! let client = ClientBuilder::new(reqwest::Client::new())
|
||||||
|
//! .with(RetryTransientMiddleware::new_with_policy(retry_policy))
|
||||||
|
//! .build();
|
||||||
|
//!
|
||||||
|
//! client
|
||||||
|
//! .get("https://truelayer.com")
|
||||||
|
//! .header("foo", "bar")
|
||||||
|
//! .send()
|
||||||
|
//! .await
|
||||||
|
//! .unwrap();
|
||||||
|
//! }
|
||||||
|
//! ```
|
||||||
|
|
||||||
mod middleware;
|
mod middleware;
|
||||||
mod retryable;
|
mod retryable;
|
||||||
|
|
||||||
pub use retry_policies::policies;
|
pub use retry_policies::{policies, RetryPolicy};
|
||||||
|
|
||||||
pub use middleware::RetryTransientMiddleware;
|
pub use middleware::RetryTransientMiddleware;
|
||||||
pub use retryable::Retryable;
|
pub use retryable::Retryable;
|
||||||
|
|
|
@ -12,8 +12,23 @@ Opentracing middleware implementation for
|
||||||
|
|
||||||
Attach `TracingMiddleware` to your client to automatically trace HTTP requests:
|
Attach `TracingMiddleware` to your client to automatically trace HTTP requests:
|
||||||
|
|
||||||
```rust
|
```toml
|
||||||
use opentelemetry::exporter::trace::stdout;
|
# Cargo.toml
|
||||||
|
# ...
|
||||||
|
[dependencies]
|
||||||
|
opentelemetry = "0.16"
|
||||||
|
reqwest = "0.11"
|
||||||
|
reqwest-middleware = "0.1.1"
|
||||||
|
reqwest-retry = "0.1.1"
|
||||||
|
reqwest-tracing = { version = "0.1.2", features = ["opentelemetry_0_16"] }
|
||||||
|
tokio = { version = "1.12.0", features = ["macros", "rt-multi-thread"] }
|
||||||
|
tracing = "0.1"
|
||||||
|
tracing-opentelemetry = "0.15"
|
||||||
|
tracing-subscriber = "0.2"
|
||||||
|
```
|
||||||
|
|
||||||
|
```rust,skip
|
||||||
|
use opentelemetry::sdk::export::trace::stdout;
|
||||||
use reqwest_middleware::ClientBuilder;
|
use reqwest_middleware::ClientBuilder;
|
||||||
use reqwest_tracing::TracingMiddleware;
|
use reqwest_tracing::TracingMiddleware;
|
||||||
use tracing_subscriber::layer::SubscriberExt;
|
use tracing_subscriber::layer::SubscriberExt;
|
||||||
|
@ -21,7 +36,7 @@ use tracing_subscriber::Registry;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() {
|
async fn main() {
|
||||||
let (tracer, _) = stdout::new_pipeline().install();
|
let tracer = stdout::new_pipeline().install_simple();
|
||||||
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
|
let telemetry = tracing_opentelemetry::layer().with_tracer(tracer);
|
||||||
let subscriber = Registry::default().with(telemetry);
|
let subscriber = Registry::default().with(telemetry);
|
||||||
tracing::subscriber::set_global_default(subscriber).unwrap();
|
tracing::subscriber::set_global_default(subscriber).unwrap();
|
||||||
|
@ -29,15 +44,20 @@ async fn main() {
|
||||||
run().await;
|
run().await;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fun run() {
|
async fn run() {
|
||||||
let client = ClientBuilder::new(reqwest::Client::new())
|
let client = ClientBuilder::new(reqwest::Client::new())
|
||||||
.with(TracingMiddleware)
|
.with(TracingMiddleware)
|
||||||
.build();`
|
.build();
|
||||||
|
|
||||||
client.get("https://truelayer.com").send().await.unwrap();
|
client.get("https://truelayer.com").send().await.unwrap();
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
```terminal
|
||||||
|
$ cargo run
|
||||||
|
SpanData { span_context: SpanContext { trace_id: ...
|
||||||
|
```
|
||||||
|
|
||||||
See the [`tracing`](https://crates.io/crates/tracing) crate for more information on how to set up a
|
See the [`tracing`](https://crates.io/crates/tracing) crate for more information on how to set up a
|
||||||
tracing subscriber to make use of the spans.
|
tracing subscriber to make use of the spans.
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
//! Opentracing middleware implementation for [`reqwest-middleware`].
|
||||||
|
//!
|
||||||
|
//! Attach [`TracingMiddleware`] to your client to automatically trace HTTP requests.
|
||||||
|
|
||||||
mod middleware;
|
mod middleware;
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
feature = "opentelemetry_0_13",
|
feature = "opentelemetry_0_13",
|
||||||
|
|
Loading…
Reference in New Issue