tracing_opentelemetry_instrumentation_sdk/http/
http_server.rs1use std::error::Error;
2
3use crate::http::{http_flavor, http_host, url_scheme, user_agent};
4use crate::otel_trace_span;
5use crate::span_type::SpanType;
6use opentelemetry_semantic_conventions::attribute::OTEL_STATUS_CODE;
7use opentelemetry_semantic_conventions::trace::{EXCEPTION_MESSAGE, HTTP_RESPONSE_STATUS_CODE};
8use tracing::field::Empty;
9
10pub fn make_span_from_request<B>(req: &http::Request<B>) -> tracing::Span {
11 let http_method = req.method();
15 otel_trace_span!(
16 "HTTP request",
17 http.request.method = %http_method,
18 http.route = Empty, network.protocol.version = %http_flavor(req.version()),
20 server.address = http_host(req),
21 http.client.address = Empty, user_agent.original = user_agent(req),
24 http.response.status_code = Empty, url.path = req.uri().path(),
26 url.query = req.uri().query(),
27 url.scheme = url_scheme(req.uri()),
28 otel.name = %http_method, otel.kind = ?opentelemetry::trace::SpanKind::Server,
30 otel.status_code = Empty, trace_id = Empty, request_id = Empty, exception.message = Empty, "span.type" = %SpanType::Web, )
36}
37
38pub fn update_span_from_response<B>(span: &tracing::Span, response: &http::Response<B>) {
39 let status = response.status();
40 span.record(HTTP_RESPONSE_STATUS_CODE, status.as_u16());
41
42 if status.is_server_error() {
43 span.record(OTEL_STATUS_CODE, "ERROR");
44 }
51}
52
53pub fn update_span_from_error<E>(span: &tracing::Span, error: &E)
54where
55 E: Error,
56{
57 span.record(OTEL_STATUS_CODE, "ERROR");
58 span.record(EXCEPTION_MESSAGE, error.to_string());
60 error
61 .source()
62 .map(|s| span.record(EXCEPTION_MESSAGE, s.to_string()));
63}
64
65pub fn update_span_from_response_or_error<B, E>(
66 span: &tracing::Span,
67 response: &Result<http::Response<B>, E>,
68) where
69 E: Error,
70{
71 match response {
72 Ok(response) => {
73 update_span_from_response(span, response);
74 }
75 Err(err) => {
76 update_span_from_error(span, err);
77 }
78 }
79}