use hyper::Version;
use opentelemetry::{
KeyValue,
global::{BoxedSpan, BoxedTracer},
trace::{Span, Status, Tracer},
};
pub fn span_for_request<T>(tracer: &BoxedTracer, req: &hyper::Request<T>) -> BoxedSpan {
let mut span = tracer.start(format!(
"HTTP {} {}",
req.method(),
req.uri().host().unwrap_or("<unknown>")
));
span.set_attribute(KeyValue::new("span.kind", "client"));
span.set_attribute(KeyValue::new("http.method", req.method().to_string()));
span.set_attribute(KeyValue::new("http.url", req.uri().to_string()));
if let Some(path_and_query) = req.uri().path_and_query() {
span.set_attribute(KeyValue::new("http.target", path_and_query.to_string()));
}
if let Some(host) = req.uri().host() {
span.set_attribute(KeyValue::new("http.host", host.to_owned()));
}
if let Some(scheme) = req.uri().scheme_str() {
span.set_attribute(KeyValue::new("http.scheme", scheme.to_string()));
}
let serialized_version = match req.version() {
Version::HTTP_10 => "1.0",
Version::HTTP_11 => "1.1",
Version::HTTP_2 => "2",
Version::HTTP_3 => "3",
_ => "unknown",
};
span.set_attribute(KeyValue::new("http.flavor", serialized_version));
span
}
pub fn annotate_span_for_response<T>(span: &mut BoxedSpan, response: &hyper::Response<T>) {
let status = response.status();
span.set_attribute(KeyValue::new(
"http.status_code",
status.as_u16().to_string(),
));
if let Some(canonical_reason) = status.canonical_reason() {
span.set_attribute(KeyValue::new(
"http.status_text",
canonical_reason.to_owned(),
));
}
if status.is_client_error() || status.is_server_error() {
span.set_status(Status::error(status.as_str().to_owned()));
}
}