From 8fd5e99a15914b5b82eeb2bdc666fcc2f1adc806 Mon Sep 17 00:00:00 2001 From: Dirkjan Ochtman Date: Tue, 5 Jan 2021 15:45:24 +0100 Subject: [PATCH] opentelemetry-http: move HTTP-related code into a separate crate --- .github/workflows/ci.yml | 2 +- Cargo.toml | 1 + examples/aws-xray/Cargo.toml | 3 +- examples/aws-xray/src/client.rs | 3 +- examples/aws-xray/src/server.rs | 6 +- examples/http/Cargo.toml | 3 +- examples/http/src/client.rs | 3 +- examples/http/src/server.rs | 5 +- opentelemetry-contrib/Cargo.toml | 13 +- .../src/trace/exporter/datadog/mod.rs | 5 +- opentelemetry-http/Cargo.toml | 17 ++ opentelemetry-http/src/lib.rs | 192 ++++++++++++++++++ opentelemetry-jaeger/Cargo.toml | 9 +- .../src/exporter/collector.rs | 2 +- opentelemetry-jaeger/src/exporter/mod.rs | 11 +- opentelemetry-zipkin/Cargo.toml | 9 +- opentelemetry-zipkin/src/exporter/mod.rs | 6 +- opentelemetry-zipkin/src/exporter/uploader.rs | 3 +- opentelemetry-zipkin/src/lib.rs | 3 +- opentelemetry/Cargo.toml | 3 - opentelemetry/src/api/propagation/mod.rs | 53 ----- opentelemetry/src/sdk/export/trace/mod.rs | 69 +------ 22 files changed, 268 insertions(+), 153 deletions(-) create mode 100644 opentelemetry-http/Cargo.toml create mode 100644 opentelemetry-http/src/lib.rs diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a887ff9bf69..bbca9092ddf 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -52,7 +52,7 @@ jobs: override: true - name: Run tests run: cargo --version && - cargo test --verbose --manifest-path=opentelemetry/Cargo.toml --features trace,metrics,serialize,tokio,serde,http,tonic,reqwest,testing && + cargo test --verbose --manifest-path=opentelemetry/Cargo.toml --features trace,metrics,serialize,tokio,serde,tonic,testing && cargo test --manifest-path=opentelemetry-jaeger/Cargo.toml && cargo test --manifest-path=opentelemetry-zipkin/Cargo.toml meta: diff --git a/Cargo.toml b/Cargo.toml index f85ebdab7af..cfb231260a2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -2,6 +2,7 @@ members = [ "opentelemetry", "opentelemetry-contrib", + "opentelemetry-http", "opentelemetry-jaeger", "opentelemetry-otlp", "opentelemetry-prometheus", diff --git a/examples/aws-xray/Cargo.toml b/examples/aws-xray/Cargo.toml index 5b7d2302c73..d8d9cb45852 100644 --- a/examples/aws-xray/Cargo.toml +++ b/examples/aws-xray/Cargo.toml @@ -16,5 +16,6 @@ path = "src/client.rs" [dependencies] hyper = "0.13" tokio = { version = "0.2", features = ["full"] } -opentelemetry = { path = "../../opentelemetry", features = ["http"] } +opentelemetry = { path = "../../opentelemetry" } opentelemetry-contrib = { path = "../../opentelemetry-contrib", features = ["aws-xray"] } +opentelemetry-http = { path = "../../opentelemetry-http" } diff --git a/examples/aws-xray/src/client.rs b/examples/aws-xray/src/client.rs index 1023162ffa7..4bd469e52cc 100644 --- a/examples/aws-xray/src/client.rs +++ b/examples/aws-xray/src/client.rs @@ -7,6 +7,7 @@ use opentelemetry::{ Context, KeyValue, }; use opentelemetry_contrib::trace::propagator::XrayPropagator; +use opentelemetry_http::HeaderInjector; fn init_tracer() -> (sdktrace::Tracer, stdout::Uninstall) { global::set_text_map_propagator(XrayPropagator::new()); @@ -34,7 +35,7 @@ async fn main() -> std::result::Result<(), Box) -> Result, Infallible> { - let parent_context = - global::get_text_map_propagator(|propagator| propagator.extract(req.headers())); + let parent_context = global::get_text_map_propagator(|propagator| { + propagator.extract(&HeaderExtractor(req.headers())) + }); let x_amzn_trace_id = req .headers() diff --git a/examples/http/Cargo.toml b/examples/http/Cargo.toml index 87c8eabaddb..9d61e623290 100644 --- a/examples/http/Cargo.toml +++ b/examples/http/Cargo.toml @@ -14,4 +14,5 @@ path = "src/client.rs" [dependencies] hyper = "0.13" tokio = { version = "0.2", features = ["full"] } -opentelemetry = { path = "../../opentelemetry", features = ["http"] } +opentelemetry = { path = "../../opentelemetry" } +opentelemetry-http = { path = "../../opentelemetry-http" } diff --git a/examples/http/src/client.rs b/examples/http/src/client.rs index aa80392a841..a8832829ff1 100644 --- a/examples/http/src/client.rs +++ b/examples/http/src/client.rs @@ -9,6 +9,7 @@ use opentelemetry::{ trace::{TraceContextExt, Tracer}, Context, KeyValue, }; +use opentelemetry_http::HeaderInjector; fn init_tracer() -> (impl Tracer, stdout::Uninstall) { global::set_text_map_propagator(TraceContextPropagator::new()); @@ -33,7 +34,7 @@ async fn main() -> std::result::Result<(), Box) -> Result, Infallible> { - let parent_cx = global::get_text_map_propagator(|propagator| propagator.extract(req.headers())); + let parent_cx = global::get_text_map_propagator(|propagator| { + propagator.extract(&HeaderExtractor(req.headers())) + }); let span = global::tracer("example/server").start_with_context("hello", parent_cx); span.add_event("handling this...".to_string(), Vec::new()); diff --git a/opentelemetry-contrib/Cargo.toml b/opentelemetry-contrib/Cargo.toml index 607ddc723b5..b004abd5198 100644 --- a/opentelemetry-contrib/Cargo.toml +++ b/opentelemetry-contrib/Cargo.toml @@ -22,16 +22,17 @@ rustdoc-args = ["--cfg", "docsrs"] default = [] base64_format = ["base64", "binary_propagator"] binary_propagator = [] -datadog = ["indexmap", "rmp", "async-trait", "thiserror"] -reqwest-blocking-client = ["reqwest/blocking", "opentelemetry/reqwest"] -reqwest-client = ["reqwest", "opentelemetry/reqwest"] -surf-client = ["surf", "opentelemetry/surf"] +datadog = ["indexmap", "rmp", "async-trait", "thiserror", "opentelemetry-http"] +reqwest-blocking-client = ["reqwest/blocking", "opentelemetry-http/reqwest"] +reqwest-client = ["reqwest", "opentelemetry-http/reqwest"] +surf-client = ["surf", "opentelemetry-http/surf"] aws-xray = [] [dependencies] async-trait = { version = "0.1", optional = true } indexmap = { version = "1.6", optional = true } -opentelemetry = { version = "0.11", path = "../opentelemetry", features = ["trace", "http"] } +opentelemetry = { version = "0.11", path = "../opentelemetry", features = ["trace"] } +opentelemetry-http = { version = "0.1", path = "../opentelemetry-http", optional = true } rmp = { version = "0.8", optional = true } lazy_static = "1.4" reqwest = { version = "0.10", optional = true } @@ -43,4 +44,4 @@ thiserror = { version = "1.0", optional = true } [dev-dependencies] base64 = "0.13" isahc = "0.9" -opentelemetry = { path = "../opentelemetry", features = ["trace", "http", "testing"] } +opentelemetry = { path = "../opentelemetry", features = ["trace", "testing"] } diff --git a/opentelemetry-contrib/src/trace/exporter/datadog/mod.rs b/opentelemetry-contrib/src/trace/exporter/datadog/mod.rs index e7ee4b4b9a7..b47077ed5f0 100644 --- a/opentelemetry-contrib/src/trace/exporter/datadog/mod.rs +++ b/opentelemetry-contrib/src/trace/exporter/datadog/mod.rs @@ -73,8 +73,8 @@ //! use opentelemetry::{KeyValue, trace::Tracer}; //! use opentelemetry::sdk::{trace::{self, IdGenerator, Sampler}, Resource}; //! use opentelemetry::sdk::export::trace::ExportResult; -//! use opentelemetry::sdk::export::trace::HttpClient; //! use opentelemetry_contrib::trace::exporter::datadog::{new_pipeline, ApiVersion}; +//! use opentelemetry_http::HttpClient; //! use async_trait::async_trait; //! use opentelemetry_contrib::trace::exporter::datadog::Error; //! @@ -128,9 +128,10 @@ pub use model::Error; use async_trait::async_trait; use http::{Method, Request, Uri}; use opentelemetry::sdk::export::trace; -use opentelemetry::sdk::export::trace::{HttpClient, SpanData}; +use opentelemetry::sdk::export::trace::SpanData; use opentelemetry::trace::TraceError; use opentelemetry::{global, sdk, trace::TracerProvider}; +use opentelemetry_http::HttpClient; /// Default Datadog collector endpoint const DEFAULT_AGENT_ENDPOINT: &str = "http://127.0.0.1:8126"; diff --git a/opentelemetry-http/Cargo.toml b/opentelemetry-http/Cargo.toml new file mode 100644 index 00000000000..80d37ec1728 --- /dev/null +++ b/opentelemetry-http/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "opentelemetry-http" +version = "0.1.0" +authors = ["OpenTelemetry Authors "] +description = "Helper implementations for exchange of traces and metrics over HTTP" +homepage = "https://github.com/open-telemetry/opentelemetry-rust" +repository = "https://github.com/open-telemetry/opentelemetry-rust" +keywords = ["opentelemetry", "tracing", "metrics"] +license = "Apache-2.0" +edition = "2018" + +[dependencies] +async-trait = "0.1.42" +http = "0.2.2" +opentelemetry = { version = "0.11.2", path = "../opentelemetry", features = ["trace"] } +reqwest = { version = "0.10", default-features = false, features = ["blocking"], optional = true } +surf = { version = "2.0", default-features = false, optional = true } diff --git a/opentelemetry-http/src/lib.rs b/opentelemetry-http/src/lib.rs new file mode 100644 index 00000000000..c4537148bf5 --- /dev/null +++ b/opentelemetry-http/src/lib.rs @@ -0,0 +1,192 @@ +#[cfg(feature = "reqwest")] +use std::convert::TryInto; +#[cfg(any(feature = "surf", feature = "reqwest"))] +use std::fmt::{Debug, Display, Formatter}; + +use async_trait::async_trait; +use http::Request; +use opentelemetry::propagation::{Extractor, Injector}; +#[cfg(any(feature = "surf", feature = "reqwest"))] +use opentelemetry::sdk::export::ExportError; +use opentelemetry::trace::TraceError; + +pub struct HeaderInjector<'a>(pub &'a mut http::HeaderMap); + +impl<'a> Injector for HeaderInjector<'a> { + /// Set a key and value in the HeaderMap. Does nothing if the key or value are not valid inputs. + fn set(&mut self, key: &str, value: String) { + if let Ok(name) = http::header::HeaderName::from_bytes(key.as_bytes()) { + if let Ok(val) = http::header::HeaderValue::from_str(&value) { + self.0.insert(name, val); + } + } + } +} + +pub struct HeaderExtractor<'a>(pub &'a http::HeaderMap); + +impl<'a> Extractor for HeaderExtractor<'a> { + /// Get a value for a key from the HeaderMap. If the value is not valid ASCII, returns None. + fn get(&self, key: &str) -> Option<&str> { + self.0.get(key).and_then(|value| value.to_str().ok()) + } + + /// Collect all the keys from the HeaderMap. + fn keys(&self) -> Vec<&str> { + self.0 + .keys() + .map(|value| value.as_str()) + .collect::>() + } +} + +/// A minimal interface necessary for export spans over HTTP. +/// +/// Users sometime choose http clients that relay on certain runtime. This trait +/// allows users to bring their choice of http clients. +#[async_trait] +pub trait HttpClient: Debug + Send + Sync { + /// Send a batch of spans to collectors + async fn send(&self, request: Request>) -> Result<(), TraceError>; +} + +#[cfg(feature = "reqwest")] +#[derive(Debug)] +struct ReqwestError(reqwest::Error); + +#[cfg(feature = "reqwest")] +impl Display for ReqwestError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.to_string()) + } +} + +#[cfg(feature = "reqwest")] +impl std::error::Error for ReqwestError {} + +#[cfg(feature = "reqwest")] +impl From for ReqwestError { + fn from(err: reqwest::Error) -> Self { + ReqwestError(err) + } +} + +#[cfg(feature = "reqwest")] +impl ExportError for ReqwestError { + fn exporter_name(&self) -> &'static str { + "reqwest" + } +} + +#[cfg(feature = "surf")] +impl ExportError for SurfError { + fn exporter_name(&self) -> &'static str { + "surf" + } +} + +#[cfg(feature = "surf")] +#[derive(Debug)] +struct SurfError(surf::Error); + +#[cfg(feature = "surf")] +impl Display for SurfError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + write!(f, "{}", self.0.to_string()) + } +} + +#[cfg(feature = "surf")] +impl std::error::Error for SurfError {} + +#[cfg(feature = "surf")] +impl From for SurfError { + fn from(err: surf::Error) -> Self { + SurfError(err) + } +} + +#[cfg(feature = "reqwest")] +#[async_trait] +impl HttpClient for reqwest::Client { + async fn send(&self, request: Request>) -> Result<(), TraceError> { + let request = request.try_into().map_err(|e| ReqwestError::from(e))?; + let _ = self + .execute(request) + .await + .and_then(|rsp| rsp.error_for_status()) + .map_err(|e| ReqwestError::from(e))?; + Ok(()) + } +} + +#[cfg(feature = "reqwest")] +#[async_trait] +impl HttpClient for reqwest::blocking::Client { + async fn send(&self, request: Request>) -> Result<(), TraceError> { + let _ = request + .try_into() + .and_then(|req| self.execute(req)) + .and_then(|rsp| rsp.error_for_status()) + .map_err(|e| ReqwestError::from(e))?; + Ok(()) + } +} + +#[cfg(feature = "surf")] +#[async_trait] +impl HttpClient for surf::Client { + async fn send(&self, request: Request>) -> Result<(), TraceError> { + let (parts, body) = request.into_parts(); + let uri = parts + .uri + .to_string() + .parse() + .map_err(|_err: surf::http::url::ParseError| TraceError::from("error parse url"))?; + + let req = surf::Request::builder(surf::http::Method::Post, uri) + .content_type("application/json") + .body(body); + let result = self.send(req).await.map_err::(Into::into)?; + + if result.status().is_success() { + Ok(()) + } else { + Err(SurfError(surf::Error::from_str( + result.status(), + result.status().canonical_reason(), + )) + .into()) + } + } +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn http_headers_get() { + let mut carrier = http::HeaderMap::new(); + HeaderInjector(&mut carrier).set("headerName", "value".to_string()); + + assert_eq!( + HeaderExtractor(&carrier).get("HEADERNAME"), + Some("value"), + "case insensitive extraction" + ) + } + + #[test] + fn http_headers_keys() { + let mut carrier = http::HeaderMap::new(); + HeaderInjector(&mut carrier).set("headerName1", "value1".to_string()); + HeaderInjector(&mut carrier).set("headerName2", "value2".to_string()); + + let extractor = HeaderExtractor(&carrier); + let got = extractor.keys(); + assert_eq!(got.len(), 2); + assert!(got.contains(&"headername1")); + assert!(got.contains(&"headername2")); + } +} diff --git a/opentelemetry-jaeger/Cargo.toml b/opentelemetry-jaeger/Cargo.toml index a5de3ede696..dfad3147a98 100644 --- a/opentelemetry-jaeger/Cargo.toml +++ b/opentelemetry-jaeger/Cargo.toml @@ -28,6 +28,7 @@ http = { version = "0.2", optional = true } isahc = { version = "0.9", default-features = false, optional = true } js-sys = { version = "0.3", optional = true } opentelemetry = { version = "0.11", default-features = false, features = ["trace"], path = "../opentelemetry" } +opentelemetry-http = { version = "0.1", path = "../opentelemetry-http", optional = true } pin-project = { version = "1.0", optional = true } thrift = "0.13" tokio = { version = "0.2", features = ["udp", "sync"], optional = true } @@ -58,11 +59,11 @@ optional = true [features] default = [] -collector_client = ["http", "opentelemetry/http"] +collector_client = ["http", "opentelemetry-http"] isahc_collector_client = ["isahc", "collector_client"] -reqwest_blocking_collector_client = ["reqwest/blocking", "collector_client", "headers", "opentelemetry/reqwest"] -reqwest_collector_client = ["reqwest", "collector_client", "headers", "opentelemetry/reqwest"] -surf_collector_client = ["surf", "collector_client", "opentelemetry/surf"] +reqwest_blocking_collector_client = ["reqwest/blocking", "collector_client", "headers", "opentelemetry-http/reqwest"] +reqwest_collector_client = ["reqwest", "collector_client", "headers", "opentelemetry-http/reqwest"] +surf_collector_client = ["surf", "collector_client", "opentelemetry-http/surf"] wasm_collector_client = [ "base64", "futures-util", diff --git a/opentelemetry-jaeger/src/exporter/collector.rs b/opentelemetry-jaeger/src/exporter/collector.rs index 1653ac23f90..fd8ae350d04 100644 --- a/opentelemetry-jaeger/src/exporter/collector.rs +++ b/opentelemetry-jaeger/src/exporter/collector.rs @@ -1,7 +1,7 @@ //! # HTTP Jaeger Collector Client use http::Uri; #[cfg(feature = "collector_client")] -use opentelemetry::sdk::export::trace::HttpClient; +use opentelemetry_http::HttpClient; use std::sync::atomic::AtomicUsize; /// `CollectorAsyncClientHttp` implements an async version of the diff --git a/opentelemetry-jaeger/src/exporter/mod.rs b/opentelemetry-jaeger/src/exporter/mod.rs index 989f1621ba2..221952ef327 100644 --- a/opentelemetry-jaeger/src/exporter/mod.rs +++ b/opentelemetry-jaeger/src/exporter/mod.rs @@ -19,8 +19,6 @@ use collector::CollectorAsyncClientHttp; #[cfg(feature = "isahc_collector_client")] use isahc::prelude::Configurable; -#[cfg(feature = "collector_client")] -use opentelemetry::sdk::export::trace::HttpClient; use opentelemetry::sdk::export::ExportError; use opentelemetry::trace::TraceError; use opentelemetry::{ @@ -29,6 +27,8 @@ use opentelemetry::{ trace::{Event, Link, SpanKind, StatusCode, TracerProvider}, Key, KeyValue, Value, }; +#[cfg(feature = "collector_client")] +use opentelemetry_http::HttpClient; use std::{ net, time::{Duration, SystemTime}, @@ -134,7 +134,7 @@ pub struct PipelineBuilder { #[cfg(any(feature = "collector_client", feature = "wasm_collector_client"))] collector_password: Option, #[cfg(feature = "collector_client")] - client: Option>, + client: Option>, export_instrument_library: bool, process: Process, config: Option, @@ -441,7 +441,7 @@ struct IsahcHttpClient(isahc::HttpClient); #[async_trait] #[cfg(feature = "isahc_collector_client")] -impl opentelemetry::sdk::export::trace::HttpClient for IsahcHttpClient { +impl HttpClient for IsahcHttpClient { async fn send( &self, request: http::Request>, @@ -735,8 +735,9 @@ mod collector_client_tests { mod test_http_client { use async_trait::async_trait; use http::Request; - use opentelemetry::sdk::export::trace::{ExportResult, HttpClient}; + use opentelemetry::sdk::export::trace::ExportResult; use opentelemetry::trace::TraceError; + use opentelemetry_http::HttpClient; use std::fmt::Debug; pub(crate) struct TestHttpClient; diff --git a/opentelemetry-zipkin/Cargo.toml b/opentelemetry-zipkin/Cargo.toml index d2e5d6f4188..533df3fbd27 100644 --- a/opentelemetry-zipkin/Cargo.toml +++ b/opentelemetry-zipkin/Cargo.toml @@ -21,13 +21,14 @@ rustdoc-args = ["--cfg", "docsrs"] [features] default = ["reqwest-blocking-client"] -reqwest-blocking-client = ["reqwest/blocking", "opentelemetry/reqwest"] -reqwest-client = ["reqwest", "opentelemetry/reqwest"] -surf-client = ["surf", "opentelemetry/surf"] +reqwest-blocking-client = ["reqwest/blocking", "opentelemetry-http/reqwest"] +reqwest-client = ["reqwest", "opentelemetry-http/reqwest"] +surf-client = ["surf", "opentelemetry-http/surf"] [dependencies] async-trait = "0.1" -opentelemetry = { version = "0.11", path = "../opentelemetry", features = ["trace", "http"] } +opentelemetry = { version = "0.11", path = "../opentelemetry", features = ["trace"] } +opentelemetry-http = { version = "0.1", path = "../opentelemetry-http", optional = true } serde_json = "1.0" serde = { version = "1.0", features = ["derive"] } typed-builder = "0.7" diff --git a/opentelemetry-zipkin/src/exporter/mod.rs b/opentelemetry-zipkin/src/exporter/mod.rs index e8fc6e23d2e..cf5218eb9a8 100644 --- a/opentelemetry-zipkin/src/exporter/mod.rs +++ b/opentelemetry-zipkin/src/exporter/mod.rs @@ -6,12 +6,10 @@ use http::Uri; use model::endpoint::Endpoint; use opentelemetry::{ global, sdk, - sdk::export::{ - trace::{self, HttpClient}, - ExportError, - }, + sdk::export::{trace, ExportError}, trace::{TraceError, TracerProvider}, }; +use opentelemetry_http::HttpClient; use std::net::SocketAddr; /// Default Zipkin collector endpoint diff --git a/opentelemetry-zipkin/src/exporter/uploader.rs b/opentelemetry-zipkin/src/exporter/uploader.rs index 27751e3a120..efce27c4b51 100644 --- a/opentelemetry-zipkin/src/exporter/uploader.rs +++ b/opentelemetry-zipkin/src/exporter/uploader.rs @@ -2,7 +2,8 @@ use crate::exporter::model::span::Span; use crate::exporter::Error; use http::{header::CONTENT_TYPE, Method, Request, Uri}; -use opentelemetry::sdk::export::trace::{ExportResult, HttpClient}; +use opentelemetry::sdk::export::trace::ExportResult; +use opentelemetry_http::HttpClient; use std::fmt::Debug; #[derive(Debug)] diff --git a/opentelemetry-zipkin/src/lib.rs b/opentelemetry-zipkin/src/lib.rs index 737359f7865..ecc77abbc78 100644 --- a/opentelemetry-zipkin/src/lib.rs +++ b/opentelemetry-zipkin/src/lib.rs @@ -79,8 +79,9 @@ //! ```no_run //! use opentelemetry::{KeyValue, trace::Tracer}; //! use opentelemetry::sdk::{trace::{self, IdGenerator, Sampler}, Resource}; -//! use opentelemetry::sdk::export::trace::{ExportResult, HttpClient}; +//! use opentelemetry::sdk::export::trace::ExportResult; //! use opentelemetry::global; +//! use opentelemetry_http::HttpClient; //! use async_trait::async_trait; //! use std::error::Error; //! diff --git a/opentelemetry/Cargo.toml b/opentelemetry/Cargo.toml index bd744fecfed..f312ea1b3aa 100644 --- a/opentelemetry/Cargo.toml +++ b/opentelemetry/Cargo.toml @@ -31,12 +31,9 @@ percent-encoding = { version = "2.0", optional = true } pin-project = { version = "1.0.2", optional = true } rand = { version = "0.8", default-features = false, features = ["std", "std_rng"], optional = true } serde = { version = "1.0", features = ["derive", "rc"], optional = true } -http = { version = "0.2", optional = true } thiserror = "1" tokio = { version = "0.2", default-features = false, features = ["rt-core", "blocking", "time", "stream"], optional = true } tonic = { version = "0.3", default-features = false, optional = true } -reqwest = { version = "0.10", default-features = false, features = ["blocking"], optional = true } -surf = { version = "2.0", default-features = false, optional = true } [target.'cfg(target_arch = "wasm32")'.dependencies] js-sys = "0.3" diff --git a/opentelemetry/src/api/propagation/mod.rs b/opentelemetry/src/api/propagation/mod.rs index 50a4df8fb3d..5f2c57af1d4 100644 --- a/opentelemetry/src/api/propagation/mod.rs +++ b/opentelemetry/src/api/propagation/mod.rs @@ -201,33 +201,6 @@ impl Extractor for HashMap { } } -#[cfg(feature = "http")] -#[cfg_attr(docsrs, doc(cfg(feature = "http")))] -impl Injector for http::HeaderMap { - /// Set a key and value in the HeaderMap. Does nothing if the key or value are not valid inputs. - fn set(&mut self, key: &str, value: String) { - if let Ok(name) = http::header::HeaderName::from_bytes(key.as_bytes()) { - if let Ok(val) = http::header::HeaderValue::from_str(&value) { - self.insert(name, val); - } - } - } -} - -#[cfg(feature = "http")] -#[cfg_attr(docsrs, doc(cfg(feature = "http")))] -impl Extractor for http::HeaderMap { - /// Get a value for a key from the HeaderMap. If the value is not valid ASCII, returns None. - fn get(&self, key: &str) -> Option<&str> { - self.get(key).and_then(|value| value.to_str().ok()) - } - - /// Collect all the keys from the HeaderMap. - fn keys(&self) -> Vec<&str> { - self.keys().map(|value| value.as_str()).collect::>() - } -} - #[cfg(feature = "tonic")] #[cfg_attr(docsrs, doc(cfg(feature = "tonic")))] impl Injector for tonic::metadata::MetadataMap { @@ -289,32 +262,6 @@ mod tests { assert!(got.contains(&"headername2")); } - #[test] - #[cfg(feature = "http")] - fn http_headers_get() { - let mut carrier = http::HeaderMap::new(); - carrier.set("headerName", "value".to_string()); - - assert_eq!( - Extractor::get(&carrier, "HEADERNAME"), - Some("value"), - "case insensitive extraction" - ) - } - - #[test] - #[cfg(feature = "http")] - fn http_headers_keys() { - let mut carrier = http::HeaderMap::new(); - carrier.set("headerName1", "value1".to_string()); - carrier.set("headerName2", "value2".to_string()); - - let got = Extractor::keys(&carrier); - assert_eq!(got.len(), 2); - assert!(got.contains(&"headername1")); - assert!(got.contains(&"headername2")); - } - #[test] #[cfg(feature = "tonic")] fn tonic_headers_get() { diff --git a/opentelemetry/src/sdk/export/trace/mod.rs b/opentelemetry/src/sdk/export/trace/mod.rs index b1106af91d1..4740297cd61 100644 --- a/opentelemetry/src/sdk/export/trace/mod.rs +++ b/opentelemetry/src/sdk/export/trace/mod.rs @@ -1,23 +1,17 @@ //! Trace exporters +use std::fmt::Debug; +use std::sync::Arc; +use std::time::SystemTime; + +use async_trait::async_trait; +#[cfg(feature = "serialize")] +use serde::{Deserialize, Serialize}; + use crate::api::trace::TraceError; -#[cfg(all(feature = "http", any(feature = "surf", feature = "reqwest")))] -use crate::sdk::export::ExportError; use crate::{ sdk, trace::{Event, Link, SpanContext, SpanId, SpanKind, StatusCode}, }; -use async_trait::async_trait; -#[cfg(feature = "http")] -use http::Request; -#[cfg(feature = "serialize")] -use serde::{Deserialize, Serialize}; -#[cfg(all(feature = "http", feature = "reqwest"))] -use std::convert::TryInto; -use std::fmt::Debug; -#[cfg(all(feature = "surf", feature = "http"))] -use std::fmt::{Display, Formatter}; -use std::sync::Arc; -use std::time::SystemTime; pub mod stdout; @@ -61,53 +55,6 @@ pub trait SpanExporter: Send + Debug { fn shutdown(&mut self) {} } -/// A minimal interface necessary for export spans over HTTP. -/// -/// Users sometime choose http clients that relay on certain runtime. This trait -/// allows users to bring their choice of http clients. -#[cfg(feature = "http")] -#[cfg_attr(docsrs, doc(cfg(feature = "http")))] -#[async_trait] -pub trait HttpClient: Debug + Send + Sync { - /// Send a batch of spans to collectors - async fn send(&self, request: Request>) -> ExportResult; -} - -#[cfg(all(feature = "reqwest", feature = "http"))] -impl ExportError for reqwest::Error { - fn exporter_name(&self) -> &'static str { - "reqwest" - } -} - -#[cfg(all(feature = "surf", feature = "http"))] -impl ExportError for SurfError { - fn exporter_name(&self) -> &'static str { - "surf" - } -} - -#[cfg(all(feature = "surf", feature = "http"))] -#[derive(Debug)] -struct SurfError(surf::Error); - -#[cfg(all(feature = "surf", feature = "http"))] -impl Display for SurfError { - fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { - write!(f, "{}", self.0.to_string()) - } -} - -#[cfg(all(feature = "surf", feature = "http"))] -impl std::error::Error for SurfError {} - -#[cfg(all(feature = "surf", feature = "http"))] -impl From for SurfError { - fn from(err: surf::Error) -> Self { - SurfError(err) - } -} - /// `SpanData` contains all the information collected by a `Span` and can be used /// by exporters as a standard input. #[cfg_attr(feature = "serialize", derive(Deserialize, Serialize))]