opentelemetry-http
Version: 0.31.0
The opentelemetry-http crate provides HTTP-related utilities for OpenTelemetry, including context propagation helpers and HTTP client abstractions for exporting telemetry.
Installation
[ dependencies ]
opentelemetry-http = "0.31"
Feature Flags
HTTP Client Implementations:
reqwest: Async reqwest client
reqwest-blocking: Blocking reqwest client
reqwest-rustls: Reqwest with rustls TLS
reqwest-rustls-webpki-roots: Reqwest with webpki trust roots
hyper: Hyper client
Other:
internal-logs: Enable internal logging (enabled by default)
Context Propagation
Injecting Context into HTTP Requests
Helper for injecting OpenTelemetry context into HTTP headers
use opentelemetry :: {global, Context };
use opentelemetry_http :: HeaderInjector ;
use http :: HeaderMap ;
let mut headers = HeaderMap :: new ();
let cx = Context :: current ();
global :: get_text_map_propagator ( | propagator | {
propagator . inject_context ( & cx , & mut HeaderInjector ( & mut headers ));
});
// headers now contains propagated context (e.g., traceparent, tracestate)
Helper for extracting OpenTelemetry context from HTTP headers
use opentelemetry :: global;
use opentelemetry_http :: HeaderExtractor ;
use http :: HeaderMap ;
let headers : HeaderMap = /* incoming request headers */ ;
let parent_cx = global :: get_text_map_propagator ( | propagator | {
propagator . extract ( & HeaderExtractor ( & headers ))
});
// Use parent_cx as parent context for new spans
HTTP Client Trait
Minimal interface for sending HTTP requests. Used by exporters to send telemetry data.
use opentelemetry_http :: { HttpClient , HttpError };
use async_trait :: async_trait;
use http :: { Request , Response };
use bytes :: Bytes ;
#[derive( Debug )]
struct MyHttpClient ;
#[async_trait]
impl HttpClient for MyHttpClient {
async fn send_bytes ( & self , request : Request < Bytes >)
-> Result < Response < Bytes >, HttpError > {
// Your HTTP client implementation
todo! ()
}
}
Built-in HTTP Clients
Reqwest Client (Async)
[ dependencies ]
opentelemetry-http = { version = "0.31" , features = [ "reqwest" ] }
reqwest = "0.12"
use opentelemetry_http :: HttpClient ;
let client = reqwest :: Client :: new ();
// client implements HttpClient trait
Reqwest Blocking Client
[ dependencies ]
opentelemetry-http = { version = "0.31" , features = [ "reqwest-blocking" ] }
reqwest = { version = "0.12" , features = [ "blocking" ] }
use opentelemetry_http :: HttpClient ;
let client = reqwest :: blocking :: Client :: new ();
// client implements HttpClient trait
Hyper Client
[ dependencies ]
opentelemetry-http = { version = "0.31" , features = [ "hyper" ] }
hyper = "1.0"
tokio = { version = "1.0" , features = [ "full" ] }
use opentelemetry_http :: hyper :: HyperClient ;
use std :: time :: Duration ;
let client = HyperClient :: with_default_connector (
Duration :: from_secs ( 10 ), // timeout
None , // optional authorization header
);
Complete Example
Context Propagation in HTTP Server
use opentelemetry :: {global, trace :: { Tracer , TraceContextExt }};
use opentelemetry_http :: { HeaderExtractor , HeaderInjector };
use http :: { Request , Response , HeaderMap };
fn handle_request ( req : Request < Vec < u8 >>) -> Response < Vec < u8 >> {
// Extract parent context from incoming headers
let parent_cx = global :: get_text_map_propagator ( | propagator | {
propagator . extract ( & HeaderExtractor ( req . headers ()))
});
let tracer = global :: tracer ( "http-server" );
// Start span with extracted parent context
let span = tracer
. span_builder ( "handle_request" )
. start_with_context ( & tracer , & parent_cx );
let cx = parent_cx . with_span ( span );
// Do work...
// If making downstream request, inject context
let mut headers = HeaderMap :: new ();
global :: get_text_map_propagator ( | propagator | {
propagator . inject_context ( & cx , & mut HeaderInjector ( & mut headers ));
});
Response :: new ( vec! [])
}
Using Custom HTTP Client with Exporter
use opentelemetry_http :: { HttpClient , HttpError };
use opentelemetry_otlp :: SpanExporter ;
use async_trait :: async_trait;
use http :: { Request , Response };
use bytes :: Bytes ;
#[derive( Debug )]
struct CustomClient {
// Your client implementation
}
#[async_trait]
impl HttpClient for CustomClient {
async fn send_bytes ( & self , request : Request < Bytes >)
-> Result < Response < Bytes >, HttpError > {
// Custom HTTP logic
todo! ()
}
}
let exporter = SpanExporter :: builder ()
. with_http_client ( CustomClient { /* ... */ })
. build () ? ;
Response Extension Trait
Extension methods for http::Response
use opentelemetry_http :: ResponseExt ;
use http :: Response ;
let response : Response < Vec < u8 >> = /* ... */ ;
// Convert 4xx/5xx responses to errors
let response = response . error_for_status () ? ;
Types
Type alias for boxed error: Box<dyn std::error::Error + Send + Sync + 'static>
Re-exported from bytes crate for convenience
Re-exported from http crate: http::Request
Re-exported from http crate: http::Response
Use Cases
Distributed Tracing Propagate trace context across HTTP service boundaries
Custom Exporters Implement custom HTTP-based telemetry exporters
Client Selection Choose HTTP client based on async runtime and performance needs
Testing Mock HTTP client for testing exporters
Example: Propagation in Web Framework
With Axum
use axum :: { extract :: Request , middleware :: Next , response :: Response };
use opentelemetry :: {global, trace :: { Tracer , TraceContextExt }};
use opentelemetry_http :: HeaderExtractor ;
async fn trace_middleware ( req : Request , next : Next ) -> Response {
let parent_cx = global :: get_text_map_propagator ( | propagator | {
propagator . extract ( & HeaderExtractor ( req . headers ()))
});
let tracer = global :: tracer ( "axum-server" );
let span = tracer
. span_builder ( format! ( "{} {}" , req . method (), req . uri () . path ()))
. start_with_context ( & tracer , & parent_cx );
let cx = parent_cx . with_span ( span );
let _guard = cx . attach ();
next . run ( req ) . await
}
Documentation
Full API Documentation View complete API reference on docs.rs
Context Propagation Example Full working example on GitHub
Minimum Rust Version
MSRV: 1.75.0