use std::error::Error;
use tracing::field::Empty;
use tracing_opentelemetry_instrumentation_sdk::http::{
http_flavor, http_host, http_method, url_scheme, user_agent,
};
use tracing_opentelemetry_instrumentation_sdk::TRACING_TARGET;
pub fn make_span_from_request<B>(req: &http::Request<B>) -> tracing::Span {
let http_method = http_method(req.method());
tracing::trace_span!(
target: TRACING_TARGET,
"HTTP request",
http.request.method = %http_method,
http.route = Empty, network.protocol.version = %http_flavor(req.version()),
server.address = http_host(req),
http.client.address = Empty, user_agent.original = user_agent(req),
http.response.status_code = Empty, http.status_code = Empty, url.path = req.uri().path(),
url.query = req.uri().query(),
url.scheme = url_scheme(req.uri()),
otel.name = %http_method, otel.kind = ?opentelemetry::trace::SpanKind::Server,
otel.status_code = Empty, trace_id = Empty, request_id = Empty, exception.message = Empty, "span.type" = "web", )
}
pub fn update_span_from_response<B>(span: &tracing::Span, response: &http::Response<B>) {
let status = response.status();
span.record("http.response.status_code", status.as_u16());
span.record("http.status_code", status.as_u16());
if status.is_server_error() {
span.record("otel.status_code", "ERROR");
}
}
pub fn update_span_from_error<E>(span: &tracing::Span, error: &E)
where
E: Error,
{
span.record("otel.status_code", "ERROR");
span.record("exception.message", error.to_string());
error
.source()
.map(|s| span.record("exception.message", s.to_string()));
}
pub fn update_span_from_response_or_error<B, E>(
span: &tracing::Span,
response: &Result<http::Response<B>, E>,
) where
E: Error,
{
match response {
Ok(response) => {
update_span_from_response(span, response);
}
Err(err) => {
update_span_from_error(span, err);
}
}
}